62 lines
1.8 KiB
Rust
62 lines
1.8 KiB
Rust
use crate::func::context::*;
|
|
|
|
use super::*;
|
|
|
|
/// ```rust
|
|
/// # use radn::rcore::Context;
|
|
/// # use radn::rcore::Factory;
|
|
/// # use radn::rcore::FactoryExt;
|
|
/// # use radn::rcore::Mentionable;
|
|
/// # use radn::rstd::ResolverExt;
|
|
/// # use radn::rstd::SerializableExt;
|
|
/// # use radn::rstd::singular::SingularResolver;
|
|
/// # fn test<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>>(a: &A) {
|
|
/// let resolver = SingularResolver::from_mentionable(a).into_rc();
|
|
/// let bytes = a.bytes();
|
|
/// let factory = a.factory();
|
|
/// factory.parse_slice(&bytes, &resolver);
|
|
/// # }
|
|
/// ```
|
|
pub struct SingularResolver<'a, Ctx: Context<'a>> {
|
|
topology: Arc<dyn Topology<'a, Ctx>>,
|
|
}
|
|
|
|
impl<'a, Ctx: Context<'a>> SingularResolver<'a, Ctx> {
|
|
pub fn from_mentionable<A: Mentionable<'a, Ctx>>(a: &A) -> Self {
|
|
Self {
|
|
topology: a.topology(),
|
|
}
|
|
}
|
|
|
|
fn try_resolve(
|
|
self: Arc<Self>,
|
|
address: Address,
|
|
) -> Result<HashResolution<'a, Ctx>, SingularError> {
|
|
let point = self
|
|
.topology
|
|
.point_at(address.index)
|
|
.ok_or(SingularError::OutOfBounds {
|
|
index: address.index,
|
|
len: self.topology.points_count(),
|
|
})?;
|
|
if point.s_hash() != address.point {
|
|
Err(SingularError::Mismatch {
|
|
index: address.index,
|
|
expected: address.point,
|
|
point: point.s_hash(),
|
|
})
|
|
} else {
|
|
Ok(point.clone().singular())
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a, Ctx: Context<'a>> Resolver<'a, Ctx> for SingularResolver<'a, Ctx> {
|
|
fn resolve(self: Arc<Self>, address: Address) -> HashResolution<'a, Ctx> {
|
|
self.try_resolve(address)
|
|
.map_err(SingularError::into)
|
|
.map_err(Err)
|
|
.unwrap_or_else(Ctx::pure)
|
|
}
|
|
}
|