Files
hash2/src/lib.rs
2026-02-03 03:33:48 -05:00

219 lines
4.4 KiB
Rust

pub use core::hash::Hasher;
pub use hash2_derive::Hash2;
use std::hash::Hash;
use ordered_float::OrderedFloat;
pub trait Hash2 {
fn hash<H: Hasher>(&self, state: &mut H);
}
#[cfg(feature = "uuid")]
impl Hash2 for uuid::Uuid {
fn hash<H: Hasher>(&self, state: &mut H) {
let (a,b) = self.as_u64_pair();
state.write_u64(a);
state.write_u64(b);
}
}
// Unsigned integer implementations
impl Hash2 for u8 {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_u8(*self);
}
}
impl Hash2 for u16 {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_u16(*self);
}
}
impl Hash2 for u32 {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_u32(*self);
}
}
impl Hash2 for u64 {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_u64(*self);
}
}
impl Hash2 for u128 {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_u128(*self);
}
}
impl Hash2 for usize {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_usize(*self);
}
}
// Signed integer implementations
impl Hash2 for i8 {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_i8(*self);
}
}
impl Hash2 for i16 {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_i16(*self);
}
}
impl Hash2 for i32 {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_i32(*self);
}
}
impl Hash2 for i64 {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_i64(*self);
}
}
impl Hash2 for i128 {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_i128(*self);
}
}
impl Hash2 for isize {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_isize(*self);
}
}
// floats
impl Hash2 for f32 {
fn hash<H: Hasher>(&self, state: &mut H) {
OrderedFloat(*self).hash(state)
}
}
impl Hash2 for f64 {
fn hash<H: Hasher>(&self, state: &mut H) {
OrderedFloat(*self).hash(state)
}
}
// String types
impl Hash2 for str {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write(self.as_bytes());
state.write_usize(self.len());
}
}
impl Hash2 for String {
fn hash<H: Hasher>(&self, state: &mut H) {
Hash2::hash(self.as_str(), state);
}
}
impl<T: Hash2 + ?Sized> Hash2 for &T {
fn hash<H: Hasher>(&self, state: &mut H) {
(*self).hash(state);
}
}
impl<T: Hash2 + ?Sized> Hash2 for &mut T {
fn hash<H: Hasher>(&self, state: &mut H) {
(**self).hash(state);
}
}
impl<T: Hash2> Hash2 for [T] {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_usize(self.len());
for item in self {
item.hash(state);
}
}
}
impl<T: Hash2, const N: usize> Hash2 for [T; N] {
fn hash<H: Hasher>(&self, state: &mut H) {
for item in self {
item.hash(state);
}
}
}
impl<T: Hash2> Hash2 for Vec<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.as_slice().hash(state);
}
}
impl<T: Hash2> Hash2 for Option<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
match self {
None => state.write_u8(0),
Some(value) => {
state.write_u8(1);
value.hash(state);
}
}
}
}
impl Hash2 for bool {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_u8(*self as u8);
}
}
impl Hash2 for char {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_u32(*self as u32);
}
}
// Tuple implementations
impl<T: ?Sized> Hash2 for std::marker::PhantomData<T> {
fn hash<H: Hasher>(&self, _state: &mut H) {}
}
impl Hash2 for () {
fn hash<H: Hasher>(&self, _state: &mut H) {}
}
impl<T: Hash2> Hash2 for (T,) {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}
impl<T: Hash2, U: Hash2> Hash2 for (T, U) {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.hash(state);
self.1.hash(state);
}
}
impl<T: Hash2, U: Hash2, V: Hash2> Hash2 for (T, U, V) {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.hash(state);
self.1.hash(state);
self.2.hash(state);
}
}
impl<T: Hash2, U: Hash2, V: Hash2, W: Hash2> Hash2 for (T, U, V, W) {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.hash(state);
self.1.hash(state);
self.2.hash(state);
self.3.hash(state);
}
}