219 lines
4.4 KiB
Rust
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);
|
|
}
|
|
}
|