use crate::merkle::{hasher::Hasher, proof::Proof, Family, Location, Position};
use alloc::sync::Arc;
use commonware_cryptography::Digest;
use core::ops::Range;
pub trait Readable: Send + Sync {
type Family: Family;
type Digest: Digest;
type Error;
fn size(&self) -> Position<Self::Family>;
fn get_node(&self, pos: Position<Self::Family>) -> Option<Self::Digest>;
fn root(&self) -> Self::Digest;
fn pruning_boundary(&self) -> Location<Self::Family>;
fn proof(
&self,
hasher: &impl Hasher<Self::Family, Digest = Self::Digest>,
loc: Location<Self::Family>,
) -> Result<Proof<Self::Family, Self::Digest>, Self::Error>;
fn range_proof(
&self,
hasher: &impl Hasher<Self::Family, Digest = Self::Digest>,
range: Range<Location<Self::Family>>,
) -> Result<Proof<Self::Family, Self::Digest>, Self::Error>;
fn leaves(&self) -> Location<Self::Family> {
Location::try_from(self.size()).expect("invalid merkle size")
}
fn bounds(&self) -> Range<Location<Self::Family>> {
self.pruning_boundary()..self.leaves()
}
}
impl<T: Readable> Readable for Arc<T> {
type Family = T::Family;
type Digest = T::Digest;
type Error = T::Error;
fn size(&self) -> Position<Self::Family> {
(**self).size()
}
fn get_node(&self, pos: Position<Self::Family>) -> Option<Self::Digest> {
(**self).get_node(pos)
}
fn root(&self) -> Self::Digest {
(**self).root()
}
fn pruning_boundary(&self) -> Location<Self::Family> {
(**self).pruning_boundary()
}
fn proof(
&self,
hasher: &impl Hasher<Self::Family, Digest = Self::Digest>,
loc: Location<Self::Family>,
) -> Result<Proof<Self::Family, Self::Digest>, Self::Error> {
(**self).proof(hasher, loc)
}
fn range_proof(
&self,
hasher: &impl Hasher<Self::Family, Digest = Self::Digest>,
range: Range<Location<Self::Family>>,
) -> Result<Proof<Self::Family, Self::Digest>, Self::Error> {
(**self).range_proof(hasher, range)
}
}