aboutsummaryrefslogtreecommitdiff
path: root/pw_tokenizer/rust/pw_tokenizer_core.rs
diff options
context:
space:
mode:
Diffstat (limited to 'pw_tokenizer/rust/pw_tokenizer_core.rs')
-rw-r--r--pw_tokenizer/rust/pw_tokenizer_core.rs28
1 files changed, 15 insertions, 13 deletions
diff --git a/pw_tokenizer/rust/pw_tokenizer_core.rs b/pw_tokenizer/rust/pw_tokenizer_core.rs
index c8e550413..ad74ead6a 100644
--- a/pw_tokenizer/rust/pw_tokenizer_core.rs
+++ b/pw_tokenizer/rust/pw_tokenizer_core.rs
@@ -18,10 +18,9 @@
//! for a string or byte sequence. This is intended to provide a minimal core
//! for both the main `pw_tokenizer` and `pw_tokenizer_macro` crates. Users
//! should prefer depending `pw_tokenizer` instead of this crate.
+#![cfg_attr(not(feature = "std"), no_std)]
-use core::num::Wrapping;
-
-pub const HASH_CONSTANT: Wrapping<u32> = Wrapping(65599u32);
+pub const HASH_CONSTANT: u32 = 65599u32;
/// Calculate the hash for a sequence of bytes.
///
@@ -31,7 +30,7 @@ pub const HASH_CONSTANT: Wrapping<u32> = Wrapping(65599u32);
/// let hash = hash_bytes(&[0x34, 0xd8, 0x3a, 0xbb, 0xf1, 0x0e, 0x07]);
/// assert_eq!(hash, 0x9e624642);
/// ```
-pub fn hash_bytes(bytes: &[u8]) -> u32 {
+pub const fn hash_bytes(bytes: &[u8]) -> u32 {
hash_bytes_fixed(bytes, bytes.len())
}
@@ -43,27 +42,30 @@ pub fn hash_bytes(bytes: &[u8]) -> u32 {
/// let hash = hash_bytes_fixed(&[0x34, 0xd8, 0x3a, 0xbb, 0xf1, 0x0e, 0x07], 4);
/// assert_eq!(hash, 0x92c5d2ac);
/// ```
-pub fn hash_bytes_fixed(bytes: &[u8], len: usize) -> u32 {
+pub const fn hash_bytes_fixed(bytes: &[u8], len: usize) -> u32 {
// The length is hashed as if it were the first byte.
- let mut hash = Wrapping(bytes.len() as u32);
+ let mut hash = bytes.len() as u32;
let mut coefficient = HASH_CONSTANT;
// Fixed sized hashes are seeded with the total length of the slice
// but only hash over at most `len` bytes.
let bytes = if bytes.len() > len {
- &bytes[0..len]
+ bytes.split_at(len).0
} else {
bytes
};
- // Hash all of the bytes in the slice as u32s. Wrapping arithmetic
- // is used intentionally as part of the hashing algorithm.
- for b in bytes {
- hash += coefficient * Wrapping(*b as u32);
- coefficient *= HASH_CONSTANT;
+ // For loops are not allowed in const functions.
+ let mut i = 0;
+ while i < bytes.len() {
+ // We call `u32::wrapping_*` instead of using `core::num::Wrapping` to
+ // avoid using traits in a const function.
+ hash = hash.wrapping_add(coefficient.wrapping_mul(bytes[i] as u32));
+ coefficient = coefficient.wrapping_mul(HASH_CONSTANT);
+ i += 1;
}
- hash.0
+ hash
}
/// Calculate the hash for a string.