diff --git a/hash2_derive/src/lib.rs b/hash2_derive/src/lib.rs index c5f1e52..526c54c 100644 --- a/hash2_derive/src/lib.rs +++ b/hash2_derive/src/lib.rs @@ -37,7 +37,7 @@ pub fn derive_hash2(input: TokenStream) -> TokenStream { Data::Enum(data) => { // Hash the discriminant first to ensure different variants hash differently let discriminant_hash = quote! { - core::mem::discriminant(self).hash(state); + core::hash::Hash::hash(&core::mem::discriminant(self), state); }; let variants = data.variants.iter().map(|variant| { diff --git a/src/lib.rs b/src/lib.rs index d0dbec0..11eb310 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,7 +11,7 @@ pub trait Hash2 { #[cfg(feature = "uuid")] impl Hash2 for uuid::Uuid { fn hash(&self, state: &mut H) { - let (a,b) = self.as_u64_pair(); + let (a, b) = self.as_u64_pair(); state.write_u64(a); state.write_u64(b); } @@ -118,6 +118,15 @@ impl Hash2 for String { } } +impl Hash2 for std::borrow::Cow<'_, T> +where + T: Hash2 + ToOwned, +{ + fn hash(&self, state: &mut H) { + Hash2::hash(&**self, state) + } +} + impl Hash2 for &T { fn hash(&self, state: &mut H) { (*self).hash(state); @@ -153,6 +162,12 @@ impl Hash2 for Vec { } } +impl Hash2 for Box { + fn hash(&self, state: &mut H) { + T::hash(&**self, state) + } +} + impl Hash2 for Option { fn hash(&self, state: &mut H) { match self { diff --git a/tests/derive_test.rs b/tests/derive_test.rs index f7017ea..162f5e8 100644 --- a/tests/derive_test.rs +++ b/tests/derive_test.rs @@ -1,4 +1,3 @@ -use std::hash::{Hash, Hasher}; use hash2::Hash2; #[derive(Hash2)] @@ -185,3 +184,33 @@ fn test_generic_enum() { let _ = hash_value(&e2); let _ = hash_value(&e3); } + +#[test] +fn test_cow_tuple_slice() { + use std::borrow::Cow; + + // Test Cow<[T]> where T is a tuple + let data = vec![("key1", 1u32), ("key2", 2u32)]; + let cow_borrowed: Cow<[(&str, u32)]> = Cow::Borrowed(&data); + let cow_owned: Cow<[(&str, u32)]> = Cow::Owned(data.clone()); + + let hash1 = hash_value(&cow_borrowed); + let hash2 = hash_value(&cow_owned); + assert_eq!(hash1, hash2, "Borrowed and owned Cow should hash the same"); + + // Test with nested Option + let with_option: Option> = Some(Cow::Borrowed(&data)); + let _ = hash_value(&with_option); +} + +#[test] +fn test_cow_str() { + use std::borrow::Cow; + + let borrowed: Cow = Cow::Borrowed("hello"); + let owned: Cow = Cow::Owned(String::from("hello")); + + let hash1 = hash_value(&borrowed); + let hash2 = hash_value(&owned); + assert_eq!(hash1, hash2, "Borrowed and owned str Cow should hash the same"); +}