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>, } impl<'a, Ctx: Context<'a>> SingularResolver<'a, Ctx> { pub fn from_mentionable>(a: &A) -> Self { Self { topology: a.topology(), } } fn try_resolve( self: Arc, address: Address, ) -> Result, 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, address: Address) -> HashResolution<'a, Ctx> { self.try_resolve(address) .map_err(SingularError::into) .map_err(Err) .unwrap_or_else(Ctx::pure) } }