use super::*; /// Failure yielded by [`Origin`]. #[derive(Debug)] pub enum ResolutionError { /// Usually comes from [`Resolver::resolve`]. Lookup(L), /// Usually comes from [`FactoryParse::deserialize`]. Parse(P), } impl ResolutionError { /// Maps only the [`ResolutionError::Parse`] variant of the overall error. pub fn map_parse(self, f: impl FnOnce(P) -> Px) -> ResolutionError { match self { Self::Lookup(l) => ResolutionError::Lookup(l), Self::Parse(p) => ResolutionError::Parse(f(p)), } } } /// [`Context::LookupError`]. Mostly useful for `type` definitions. pub type LookupError<'a, Ctx> = >::LookupError; /// See [`ResolutionResult`]. pub type ResolutionFailure<'a, Ctx, A> = ResolutionError, ParseErrorA<'a, A>>; /// Result yielded by [`Origin`]. pub type ResolutionResult<'a, Ctx, A> = Result, ResolutionFailure<'a, Ctx, A>>; /// Wrapped result returned by [`Origin`]. pub type Resolution<'a, Ctx, A> = Wrapped<'a, Ctx, ResolutionResult<'a, Ctx, A>>; /// Underlying [`Result`] of [`HashResolution`]. /// In case of success, contains byte data and the resolver for points appearing inside that data. pub type HashResolutionResult<'a, Ctx> = Result<(Vec, Arc>), LookupError<'a, Ctx>>; /// Shorthand for the type of values returned by [`Resolver::resolve`]. pub type HashResolution<'a, Ctx> = Wrapped<'a, Ctx, HashResolutionResult<'a, Ctx>>; /// Value accepted by [`Resolver::resolve`]. Includes index to make it order-sensitive. #[derive(Clone, Copy, Debug)] pub struct Address { pub point: Hash, /// Index of the point in the [`MentionableTop::points_typed()`]. pub index: usize, } /// Trait representing the "rainbow table" behaviour. pub trait Resolver<'a, Ctx: Context<'a>>: 'a + Send + Sync { /// Successfully returned value should be the inverse of the point passed /// with topology header ([`MentionableTop::topology_hash()`]) omitted. fn resolve(self: Arc, address: Address) -> HashResolution<'a, Ctx>; } /// [`ResolverMap::resolve_map`]. pub trait ResolverMap<'a, Ctx: Context<'a>>: Resolver<'a, Ctx> { /// Resolve the [Address], then map the [`HashResolutionResult`]. fn resolve_map( self: Arc, address: Address, f: impl 'a + Send + FnOnce(HashResolutionResult<'a, Ctx>) -> T, ) -> Wrapped<'a, Ctx, T> { Ctx::fmap(self.resolve(address), f) } } impl<'a, Ctx: Context<'a>, R: ?Sized + Resolver<'a, Ctx>> ResolverMap<'a, Ctx> for R {}