radn-rs/src/rstd/singular.rs
timofey a28bfa461e
All checks were successful
buildbot/cargo fmt (1.72) Build done.
buildbot/cargo doc (1.72) Build done.
buildbot/cargo clippy (1.72) Build done.
buildbot/cargo test (1.65) Build done.
buildbot/cargo clippy (1.65) Build done.
SingularResolver via Topology
2023-09-03 21:37:28 +00:00

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)
}
}