217 lines
4.3 KiB
Rust
217 lines
4.3 KiB
Rust
use hash2::Hash2;
|
|
|
|
#[derive(Hash2)]
|
|
struct SimpleStruct {
|
|
a: u32,
|
|
b: u64,
|
|
}
|
|
|
|
#[derive(Hash2)]
|
|
struct GenericStruct<T> {
|
|
value: T,
|
|
count: usize,
|
|
}
|
|
|
|
#[derive(Hash2)]
|
|
struct LifetimeStruct<'a> {
|
|
name: &'a str,
|
|
id: u64,
|
|
}
|
|
|
|
#[derive(Hash2)]
|
|
struct BothGenerics<'a, T> {
|
|
data: T,
|
|
reference: &'a str,
|
|
number: i32,
|
|
}
|
|
|
|
#[derive(Hash2)]
|
|
struct MultipleTypes<T, U> {
|
|
first: T,
|
|
second: U,
|
|
}
|
|
|
|
#[derive(Hash2)]
|
|
struct MultipleLifetimes<'a, 'b> {
|
|
first: &'a str,
|
|
second: &'b str,
|
|
}
|
|
|
|
#[derive(Hash2)]
|
|
struct Complex<'a, 'b, T, U>
|
|
where
|
|
T: Clone,
|
|
U: Clone,
|
|
{
|
|
data1: T,
|
|
data2: U,
|
|
ref1: &'a str,
|
|
ref2: &'b str,
|
|
}
|
|
|
|
#[derive(Hash2)]
|
|
enum ScalerEnum {
|
|
A,
|
|
B,
|
|
C,
|
|
}
|
|
|
|
#[derive(Hash2)]
|
|
enum SimpleEnum {
|
|
A,
|
|
B(u32),
|
|
C { x: i32, y: i32 },
|
|
}
|
|
|
|
#[derive(Hash2)]
|
|
enum GenericEnum<T> {
|
|
None,
|
|
Some(T),
|
|
Pair(T, T),
|
|
}
|
|
|
|
fn hash_value<T: Hash2>(value: &T) -> u64 {
|
|
use std::collections::hash_map::DefaultHasher;
|
|
let mut hasher = DefaultHasher::new();
|
|
value.hash(&mut hasher);
|
|
std::hash::Hasher::finish(&hasher)
|
|
}
|
|
|
|
#[test]
|
|
fn test_simple_struct() {
|
|
let s = SimpleStruct { a: 42, b: 1000 };
|
|
let hash1 = hash_value(&s);
|
|
let hash2 = hash_value(&s);
|
|
assert_eq!(hash1, hash2, "Same struct should produce same hash");
|
|
}
|
|
|
|
#[test]
|
|
fn test_generic_struct() {
|
|
let s1 = GenericStruct { value: 42u32, count: 10 };
|
|
let s2 = GenericStruct { value: 42u32, count: 10 };
|
|
assert_eq!(hash_value(&s1), hash_value(&s2));
|
|
|
|
let s3 = GenericStruct { value: "hello", count: 10 };
|
|
let _ = hash_value(&s3);
|
|
}
|
|
|
|
#[test]
|
|
fn test_lifetime_struct() {
|
|
let name = String::from("test");
|
|
let s = LifetimeStruct { name: &name, id: 123 };
|
|
let hash1 = hash_value(&s);
|
|
let hash2 = hash_value(&s);
|
|
assert_eq!(hash1, hash2);
|
|
}
|
|
|
|
#[test]
|
|
fn test_both_generics() {
|
|
let reference = String::from("ref");
|
|
let s = BothGenerics {
|
|
data: 42u32,
|
|
reference: &reference,
|
|
number: -10,
|
|
};
|
|
let _ = hash_value(&s);
|
|
}
|
|
|
|
#[test]
|
|
fn test_multiple_types() {
|
|
let s = MultipleTypes {
|
|
first: 42u32,
|
|
second: "hello",
|
|
};
|
|
let _ = hash_value(&s);
|
|
}
|
|
|
|
#[test]
|
|
fn test_multiple_lifetimes() {
|
|
let first = String::from("first");
|
|
let second = String::from("second");
|
|
let s = MultipleLifetimes {
|
|
first: &first,
|
|
second: &second,
|
|
};
|
|
let _ = hash_value(&s);
|
|
}
|
|
|
|
#[test]
|
|
fn test_complex() {
|
|
let ref1 = String::from("ref1");
|
|
let ref2 = String::from("ref2");
|
|
let s = Complex {
|
|
data1: 42u32,
|
|
data2: "data",
|
|
ref1: &ref1,
|
|
ref2: &ref2,
|
|
};
|
|
let _ = hash_value(&s);
|
|
}
|
|
|
|
#[test]
|
|
fn test_scaler_enum() {
|
|
let e1 = ScalerEnum::A;
|
|
let e2 = ScalerEnum::B;
|
|
let e3 = ScalerEnum::C;
|
|
|
|
let a = hash_value(&e1);
|
|
let b = hash_value(&e2);
|
|
let c = hash_value(&e3);
|
|
assert_ne!(a, b);
|
|
assert_ne!(a, c);
|
|
assert_ne!(b, c);
|
|
}
|
|
|
|
|
|
#[test]
|
|
fn test_simple_enum() {
|
|
let e1 = SimpleEnum::A;
|
|
let e2 = SimpleEnum::B(42);
|
|
let e3 = SimpleEnum::C { x: 1, y: 2 };
|
|
|
|
let _ = hash_value(&e1);
|
|
let _ = hash_value(&e2);
|
|
let _ = hash_value(&e3);
|
|
}
|
|
|
|
#[test]
|
|
fn test_generic_enum() {
|
|
let e1: GenericEnum<u32> = GenericEnum::None;
|
|
let e2 = GenericEnum::Some(42u32);
|
|
let e3 = GenericEnum::Pair(1u32, 2u32);
|
|
|
|
let _ = hash_value(&e1);
|
|
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<Cow<[(&str, u32)]>> = Some(Cow::Borrowed(&data));
|
|
let _ = hash_value(&with_option);
|
|
}
|
|
|
|
#[test]
|
|
fn test_cow_str() {
|
|
use std::borrow::Cow;
|
|
|
|
let borrowed: Cow<str> = Cow::Borrowed("hello");
|
|
let owned: Cow<str> = 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");
|
|
}
|