ResolverMap::resolve_map

This commit is contained in:
AF 2023-06-23 12:50:16 +00:00
parent 28cfaf47d5
commit f1bef0ed2c
6 changed files with 52 additions and 34 deletions

View File

@ -28,7 +28,7 @@ pub use self::point::Point;
pub use self::points::TakesPoints;
pub use self::resolution::{
Address, HashResolution, HashResolutionResult, Resolution, ResolutionError, ResolutionFailure,
ResolutionResult, Resolver,
ResolutionResult, Resolver, ResolverMap,
};
pub use self::serialization::{Deserializer, DeserializerExt, Serializable, Serializer};
pub use self::slice_deserializer::SliceDeserializer;

View File

@ -50,3 +50,15 @@ pub trait Resolver<'a, Ctx: Context<'a>>: 'a {
/// with topology header ([`Mentionable::topology()`]) omitted.
fn resolve(self: Rc<Self>, address: Address) -> HashResolution<'a, Ctx>;
}
pub trait ResolverMap<'a, Ctx: Context<'a>>: Resolver<'a, Ctx> {
fn resolve_map<T>(
self: Rc<Self>,
address: Address,
f: impl 'a + 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 {}

View File

@ -27,15 +27,17 @@ struct ResolverOrigin<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> {
fn _resolve_origin<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>>(
origin: Rc<ResolverOrigin<'a, Ctx, A::Fctr>>,
) -> Resolution<'a, Ctx, A> {
let resolution = origin.r_resolver.clone().resolve(origin.r_address);
Ctx::fmap(resolution, move |resolved| {
let (src, resolver) = resolved.map_err(ResolutionError::Lookup)?;
let mentionable = origin
.r_factory
.parse_slice(&src, resolver)
.map_err(ResolutionError::Parse)?;
Ok(Rc::new(mentionable))
})
origin
.r_resolver
.clone()
.resolve_map(origin.r_address, move |resolved| {
let (src, resolver) = resolved.map_err(ResolutionError::Lookup)?;
let mentionable = origin
.r_factory
.parse_slice(&src, resolver)
.map_err(ResolutionError::Parse)?;
Ok(Rc::new(mentionable))
})
}
impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> Origin<'a, Ctx> for ResolverOrigin<'a, Ctx, F> {

View File

@ -14,12 +14,14 @@ impl<'a, Ctx: Context<'a, _Tm = TracedInstance>> TracedResolver<'a, Ctx> {
impl<'a, Ctx: Context<'a, _Tm = TracedInstance>> Resolver<'a, Ctx> for TracedResolver<'a, Ctx> {
fn resolve(self: Rc<Self>, address: Address) -> HashResolution<'a, Ctx> {
TracedInstance::fmap(self.resolver.clone().resolve(address), |resolved| {
let (src, resolver) = resolved?;
let delayed: Rc<dyn Resolver<'a, Ctx>> = Rc::new(TracedResolver { resolver });
Ok((src, delayed))
})
.after_resolution()
self.resolver
.clone()
.resolve_map(address, |resolved| {
let (src, resolver) = resolved?;
let delayed: Rc<dyn Resolver<'a, Ctx>> = Rc::new(TracedResolver { resolver });
Ok((src, delayed))
})
.after_resolution()
}
}

View File

@ -71,13 +71,15 @@ impl<'a> CountedResolver<'a> {
impl<'a> Resolver<'a, TestContextCounted> for CountedResolver<'a> {
fn resolve(self: Rc<Self>, address: Address) -> HashResolution<'a, TestContextCounted> {
CountedInstance::fmap(self.resolver.clone().resolve(address), |resolved| {
let (src, resolver) = resolved?;
let delayed: Rc<dyn Resolver<'a, TestContextCounted>> =
Rc::new(CountedResolver { resolver });
Ok((src, delayed))
})
.add(1)
self.resolver
.clone()
.resolve_map(address, |resolved| {
let (src, resolver) = resolved?;
let delayed: Rc<dyn Resolver<'a, TestContextCounted>> =
Rc::new(CountedResolver { resolver });
Ok((src, delayed))
})
.add(1)
}
}

View File

@ -1,6 +1,5 @@
use std::rc::Rc;
use crate::func::context::*;
use crate::rcore::*;
trait Inject<'a, Ctx: Context<'a>>: 'a {
@ -15,15 +14,16 @@ struct InjectedResolver<'a, Ctx: Context<'a>, F: Inject<'a, Ctx>> {
impl<'a, Ctx: Context<'a>, F: Inject<'a, Ctx>> Resolver<'a, Ctx> for InjectedResolver<'a, Ctx, F> {
fn resolve(self: Rc<Self>, address: crate::rcore::Address) -> HashResolution<'a, Ctx> {
let inject = self.inject.clone();
self.inject.inject(Ctx::fmap(
self.resolver.clone().resolve(address),
|resolved| match resolved {
Ok((source, resolver)) => Ok((
source,
Rc::new(InjectedResolver { resolver, inject }) as Rc<dyn Resolver<'a, Ctx>>,
)),
Err(e) => Err(e),
},
))
self.inject.inject(
self.resolver
.clone()
.resolve_map(address, |resolved| match resolved {
Ok((source, resolver)) => Ok((
source,
Rc::new(InjectedResolver { resolver, inject }) as Rc<dyn Resolver<'a, Ctx>>,
)),
Err(e) => Err(e),
}),
)
}
}