pub mod diff;
pub mod encoding;
pub mod file;
pub mod identity;
pub mod prelude;
pub mod repo;
#[cfg(feature = "std")]
pub mod store;
#[cfg(any(test, feature = "testing"))]
pub mod testing;
pub mod to_record;
pub use terrors;

#[doc(inline)]
pub use pijul_config::Config as PijulConfig;

#[doc(inline)]
pub use std::hash::DefaultHasher;

pub type AHash = u64;

pub fn hasher() -> DefaultHasher {
    DefaultHasher::new()
}

pub fn hash_one<T>(x: T) -> u64
where
    T: std::hash::Hash,
{
    let mut hasher = hasher();
    x.hash(&mut hasher);
    std::hash::Hasher::finish(&hasher)
}

pub type NoHashMap<K, V> = std::collections::HashMap<K, V, BuildNoHashHasher>;

pub type BuildNoHashHasher = std::hash::BuildHasherDefault<NoHashHasher>;

#[derive(Debug, Default)]
pub struct NoHashHasher(u64);

impl std::hash::Hasher for NoHashHasher {
    fn write(&mut self, _: &[u8]) {
        unimplemented!("Invalid use of NoHashHasher")
    }

    fn write_u8(&mut self, n: u8) {
        self.0 = u64::from(n)
    }
    fn write_u16(&mut self, n: u16) {
        self.0 = u64::from(n)
    }
    fn write_u32(&mut self, n: u32) {
        self.0 = u64::from(n)
    }
    fn write_u64(&mut self, n: u64) {
        self.0 = n
    }
    fn write_usize(&mut self, n: usize) {
        self.0 = n as u64
    }

    fn write_i8(&mut self, n: i8) {
        self.0 = n as u64
    }
    fn write_i16(&mut self, n: i16) {
        self.0 = n as u64
    }
    fn write_i32(&mut self, n: i32) {
        self.0 = n as u64
    }
    fn write_i64(&mut self, n: i64) {
        self.0 = n as u64
    }
    fn write_isize(&mut self, n: isize) {
        self.0 = n as u64
    }

    fn finish(&self) -> u64 {
        self.0
    }
}