From f6304cab972245d36dc28165d039c34f1118880c Mon Sep 17 00:00:00 2001 From: Sachymetsu Date: Mon, 15 Dec 2025 16:21:32 +0100 Subject: [PATCH] feat: FNV hasher crate Change-Id: ozxpuzltxoqlqrxkzszzzrvyomonvypk --- .tangled/workflows/test.yml | 2 +- Cargo.lock | 4 ++++ Cargo.toml | 2 +- sachy-fnv/Cargo.toml | 10 +++++++++ sachy-fnv/src/lib.rs | 43 +++++++++++++++++++++++++++++++++++++ 5 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 sachy-fnv/Cargo.toml create mode 100644 sachy-fnv/src/lib.rs diff --git a/.tangled/workflows/test.yml b/.tangled/workflows/test.yml index 0a78931..5e234d6 100644 --- a/.tangled/workflows/test.yml +++ b/.tangled/workflows/test.yml @@ -14,4 +14,4 @@ steps: - name: Format check command: cargo fmt --all --check - name: Tests - command: cargo test --workspace + command: cargo test --workspace --locked diff --git a/Cargo.lock b/Cargo.lock index 3c632c6..a22eafc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -362,6 +362,10 @@ dependencies = [ "defmt 1.0.1", ] +[[package]] +name = "sachy-fnv" +version = "0.1.0" + [[package]] name = "sachy-shtc3" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 7cd8cee..ec929cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "3" -members = ["sachy-battery","sachy-bthome", "sachy-fmt", "sachy-shtc3"] +members = ["sachy-battery","sachy-bthome", "sachy-fmt", "sachy-fnv", "sachy-shtc3"] [workspace.package] authors = ["Sachymetsu "] diff --git a/sachy-fnv/Cargo.toml b/sachy-fnv/Cargo.toml new file mode 100644 index 0000000..e67d023 --- /dev/null +++ b/sachy-fnv/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "sachy-fnv" +authors.workspace = true +edition.workspace = true +repository.workspace = true +license.workspace = true +version.workspace = true +rust-version.workspace = true + +[dependencies] diff --git a/sachy-fnv/src/lib.rs b/sachy-fnv/src/lib.rs new file mode 100644 index 0000000..3ee3341 --- /dev/null +++ b/sachy-fnv/src/lib.rs @@ -0,0 +1,43 @@ +//! This crate provides a `const` FNV32 hasher for the purpose of supporting the ESPHome/Home Assistant protocol where required. +//! +//! ``` +//! use sachy_fnv::fnv32_hash; +//! +//! let hash = fnv32_hash("water_pump_1"); +//! +//! assert_eq!(hash, 3557162331); +//! ``` +#![no_std] + +const FNV_OFFSET_BASIS_32: u32 = 0x811c9dc5; +const FNV_PRIME_32: u32 = 0x01000193; + +/// `const` FNV32 hasher. Takes a `&str` and returns a `u32` hash. +pub const fn fnv32_hash(str: &str) -> u32 { + let bytes = str.as_bytes(); + + let mut hash = FNV_OFFSET_BASIS_32; + let mut i = 0; + let len = bytes.len(); + + while i < len { + hash = hash.wrapping_mul(FNV_PRIME_32); + hash ^= bytes[i] as u32; + i += 1; + } + + hash +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = fnv32_hash("water_pump_1"); + assert_eq!(result, 3557162331); + let result = fnv32_hash("pump_1_duration"); + assert_eq!(result, 931766070); + } +} -- 2.52.0