From f1bef0ed2caef767702847b2b4a6ec72bae53888 Mon Sep 17 00:00:00 2001 From: timofey Date: Fri, 23 Jun 2023 12:50:16 +0000 Subject: [PATCH] `ResolverMap::resolve_map` --- src/rcore.rs | 2 +- src/rcore/resolution.rs | 12 ++++++++++++ src/rcore/resolver_origin.rs | 20 +++++++++++--------- src/rstd/tracing/traceable.rs | 14 ++++++++------ src/testing/counted.rs | 16 +++++++++------- src/testing/inject.rs | 22 +++++++++++----------- 6 files changed, 52 insertions(+), 34 deletions(-) diff --git a/src/rcore.rs b/src/rcore.rs index b71484a..130a624 100644 --- a/src/rcore.rs +++ b/src/rcore.rs @@ -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; diff --git a/src/rcore/resolution.rs b/src/rcore/resolution.rs index d8235c8..733f35b 100644 --- a/src/rcore/resolution.rs +++ b/src/rcore/resolution.rs @@ -50,3 +50,15 @@ pub trait Resolver<'a, Ctx: Context<'a>>: 'a { /// with topology header ([`Mentionable::topology()`]) omitted. fn resolve(self: Rc, address: Address) -> HashResolution<'a, Ctx>; } + +pub trait ResolverMap<'a, Ctx: Context<'a>>: Resolver<'a, Ctx> { + fn resolve_map( + self: Rc, + 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 {} diff --git a/src/rcore/resolver_origin.rs b/src/rcore/resolver_origin.rs index 6690d3f..5d4b347 100644 --- a/src/rcore/resolver_origin.rs +++ b/src/rcore/resolver_origin.rs @@ -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>, ) -> 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> { diff --git a/src/rstd/tracing/traceable.rs b/src/rstd/tracing/traceable.rs index d3be15f..4a0fbad 100644 --- a/src/rstd/tracing/traceable.rs +++ b/src/rstd/tracing/traceable.rs @@ -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, address: Address) -> HashResolution<'a, Ctx> { - TracedInstance::fmap(self.resolver.clone().resolve(address), |resolved| { - let (src, resolver) = resolved?; - let delayed: Rc> = Rc::new(TracedResolver { resolver }); - Ok((src, delayed)) - }) - .after_resolution() + self.resolver + .clone() + .resolve_map(address, |resolved| { + let (src, resolver) = resolved?; + let delayed: Rc> = Rc::new(TracedResolver { resolver }); + Ok((src, delayed)) + }) + .after_resolution() } } diff --git a/src/testing/counted.rs b/src/testing/counted.rs index 7865a06..023a5b6 100644 --- a/src/testing/counted.rs +++ b/src/testing/counted.rs @@ -71,13 +71,15 @@ impl<'a> CountedResolver<'a> { impl<'a> Resolver<'a, TestContextCounted> for CountedResolver<'a> { fn resolve(self: Rc, address: Address) -> HashResolution<'a, TestContextCounted> { - CountedInstance::fmap(self.resolver.clone().resolve(address), |resolved| { - let (src, resolver) = resolved?; - let delayed: Rc> = - Rc::new(CountedResolver { resolver }); - Ok((src, delayed)) - }) - .add(1) + self.resolver + .clone() + .resolve_map(address, |resolved| { + let (src, resolver) = resolved?; + let delayed: Rc> = + Rc::new(CountedResolver { resolver }); + Ok((src, delayed)) + }) + .add(1) } } diff --git a/src/testing/inject.rs b/src/testing/inject.rs index a7281fa..e81ec79 100644 --- a/src/testing/inject.rs +++ b/src/testing/inject.rs @@ -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, 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>, - )), - 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>, + )), + Err(e) => Err(e), + }), + ) } }