188 lines
3.4 KiB
Rust
188 lines
3.4 KiB
Rust
use std::hash::{Hash, Hasher};
|
|
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);
|
|
}
|