#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "doc_cfg", feature(doc_cfg))]
use core::fmt::{self, Display, Formatter};
use core::hash::{BuildHasher, BuildHasherDefault, Hash, Hasher};
use core::ops::Deref;
#[cfg(feature = "std")]
mod std_utils;
#[cfg(feature = "std")]
pub use std_utils::*;
#[derive(Copy, Debug)]
pub struct Prehashed<T: ?Sized, H = u64> {
hash: H,
value: T,
}
impl<T: ?Sized, H> Prehashed<T, H> {
#[must_use]
pub fn as_parts(pre: &Self) -> (&T, &H) {
(&pre.value, &pre.hash)
}
#[must_use]
pub fn as_inner(pre: &Self) -> &T {
Self::as_parts(pre).0
}
#[must_use]
pub fn as_hash(pre: &Self) -> &H {
Self::as_parts(pre).1
}
}
impl<T, H> Prehashed<T, H> {
#[must_use]
pub const fn new(value: T, hash: H) -> Self {
Self { hash, value }
}
#[must_use]
pub fn into_parts(pre: Self) -> (T, H) {
(pre.value, pre.hash)
}
#[must_use]
pub fn into_inner(pre: Self) -> T {
Self::into_parts(pre).0
}
}
impl<T: Hash> Prehashed<T, u64> {
#[cfg(feature = "std")]
#[cfg_attr(feature = "doc_cfg", doc(cfg(feature = "std")))]
#[must_use]
pub fn with_default(value: T) -> Self {
Self::with_hasher::<std::collections::hash_map::DefaultHasher>(value)
}
#[must_use]
pub fn with_hasher<H: Default + Hasher>(value: T) -> Self {
Self::with_builder(value, &BuildHasherDefault::<H>::default())
}
#[must_use]
pub fn with_builder<B: BuildHasher + ?Sized>(value: T, build: &B) -> Self {
let mut hasher = build.build_hasher();
value.hash(&mut hasher);
Self::new(value, hasher.finish())
}
}
impl<T: PartialEq + ?Sized, H: Eq> Prehashed<T, H> {
#[must_use]
pub fn fast_eq(lhs: &Self, rhs: &Self) -> bool {
lhs.hash.eq(&rhs.hash) && lhs.value.eq(&rhs.value)
}
}
impl<T: ?Sized, H> AsRef<T> for Prehashed<T, H> {
fn as_ref(&self) -> &T {
Self::as_inner(self)
}
}
impl<T: Copy + ?Sized, H: Copy> Clone for Prehashed<T, H> {
fn clone(&self) -> Self {
*self
}
}
impl<T: ?Sized, H> Deref for Prehashed<T, H> {
type Target = T;
fn deref(&self) -> &Self::Target {
Self::as_inner(self)
}
}
impl<T: Display + ?Sized, H> Display for Prehashed<T, H> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.value.fmt(f)
}
}
impl<T: Eq + ?Sized, H> Eq for Prehashed<T, H> {}
impl<T: ?Sized, H: Hash> Hash for Prehashed<T, H> {
fn hash<S: Hasher>(&self, state: &mut S) {
self.hash.hash(state)
}
}
impl<T: PartialEq + ?Sized, H> PartialEq for Prehashed<T, H> {
fn eq(&self, other: &Self) -> bool {
self.value.eq(&other.value)
}
}
impl<T: PartialEq + ?Sized, H> PartialEq<T> for Prehashed<T, H> {
fn eq(&self, other: &T) -> bool {
self.value.eq(other)
}
}
pub trait Prehasher {
type Hash;
#[must_use]
fn prehash<T: Hash>(&self, value: T) -> Prehashed<T, Self::Hash>;
}
impl<B: BuildHasher> Prehasher for B {
type Hash = u64;
fn prehash<T: Hash>(&self, value: T) -> Prehashed<T, Self::Hash> {
Prehashed::with_builder(value, self)
}
}
#[derive(Debug)]
pub struct Passthru {
hash: u64,
}
impl Passthru {
#[must_use]
pub fn new() -> Self {
Self { hash: 0 }
}
}
impl Default for Passthru {
fn default() -> Self {
Self::new()
}
}
impl Hasher for Passthru {
fn write(&mut self, _bytes: &[u8]) {
panic!("unsupported operation");
}
fn write_u64(&mut self, i: u64) {
self.hash = i;
}
fn finish(&self) -> u64 {
self.hash
}
}