use std::fmt::{Debug};
use std::hash::Hash;
use num::bigint::BigUint;
use num::Zero;
pub trait DatabaseId: Hash + Default + PartialEq + Eq + Ord + Clone + Send + Debug {
fn xor(a: &Self, b: &Self) -> Self;
fn bits(&self) -> usize;
fn is_zero(&self) -> bool;
fn max_bits(&self) -> usize;
}
#[cfg(nope)]
impl DatabaseId for u64 {
fn xor(a: &u64, b: &u64) -> u64 {
a ^ b
}
fn bits(&self) -> usize {
(64 - self.leading_zeros()) as usize
}
fn is_zero(&self) -> bool {
Zero::is_zero(self)
}
fn max_bits(&self) -> usize {
64
}
}
impl<T> DatabaseId for T
where
T: AsRef<[u8]>
+ AsMut<[u8]>
+ Hash
+ Default
+ PartialEq
+ Eq
+ Ord
+ Clone
+ Sync
+ Send
+ Debug,
{
fn xor(a: &T, b: &T) -> Self {
let a = a.as_ref();
let b = b.as_ref();
let mut c = T::default();
{
let c = c.as_mut();
assert!(
a.len() == b.len() && a.len() == c.len(),
"dht IDs must be the same length"
);
for i in 0..a.len() {
c[i] = a[i] ^ b[i];
}
}
c
}
fn bits(&self) -> usize {
let a = BigUint::from_bytes_le(self.as_ref());
a.bits()
}
fn is_zero(&self) -> bool {
let a = BigUint::from_bytes_le(self.as_ref());
Zero::is_zero(&a)
}
fn max_bits(&self) -> usize {
self.as_ref().len() * 8
}
}
pub trait RequestId: Hash + PartialEq + Eq + Ord + Clone + Send + Debug {
fn generate() -> Self;
}
impl RequestId for u8 {
fn generate() -> Self {
rand::random()
}
}
impl RequestId for u16 {
fn generate() -> Self {
rand::random()
}
}
impl RequestId for u32 {
fn generate() -> Self {
rand::random()
}
}
impl RequestId for u64 {
fn generate() -> Self {
rand::random()
}
}
impl RequestId for [u8; 8] {
fn generate() -> Self {
rand::random()
}
}