use std::hash::Hash;
use kitsune_p2p_types::KOpHash;
const GRAN: usize = 4096;
#[derive(Clone, Copy, Default, PartialEq, Eq, Hash, serde::Deserialize, serde::Serialize)]
pub struct RoughInt(i16);
impl std::fmt::Debug for RoughInt {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.get())
}
}
impl RoughInt {
pub fn get(&self) -> usize {
if self.0 > 0 {
self.0 as usize
} else {
(-self.0) as usize * GRAN
}
}
pub fn set(&mut self, v: usize) -> Self {
if v <= i16::MAX as usize {
self.0 = v as i16
} else {
self.0 = -(std::cmp::min(i16::MAX as usize, v / GRAN) as i16);
}
*self
}
}
impl From<usize> for RoughInt {
fn from(v: usize) -> Self {
Self::default().set(v)
}
}
pub type OpHashSized = RoughSized<KOpHash>;
#[derive(
Clone,
Debug,
serde::Deserialize,
serde::Serialize,
derive_more::From,
derive_more::Into,
derive_more::Constructor,
derive_more::Deref,
)]
pub struct RoughSized<T> {
#[deref]
data: T,
size: Option<RoughInt>,
}
impl<T> RoughSized<T> {
pub fn into_inner(self) -> (T, Option<RoughInt>) {
(self.data, self.size)
}
pub fn data_ref(&self) -> &T {
&self.data
}
pub fn maybe_size(&self) -> Option<RoughInt> {
self.size
}
pub fn size(&self) -> RoughInt {
self.size.unwrap_or_default()
}
}
impl<T: Clone> RoughSized<T> {
pub fn data(&self) -> T {
self.data.clone()
}
}
impl<T: Hash> Hash for RoughSized<T> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.data.hash(state);
}
}
impl<T: PartialEq> PartialEq for RoughSized<T> {
fn eq(&self, other: &Self) -> bool {
self.data == other.data
}
}
impl<T: Eq> Eq for RoughSized<T> {}