radn-rs/src/rstd/wrapped_origin.rs
timofey 01c9fd26ba
All checks were successful
buildbot/cargo fmt (1.72) Build done.
buildbot/cargo clippy (1.72) Build done.
buildbot/cargo doc (1.72) Build done.
buildbot/cargo test (1.65) Build done.
buildbot/cargo clippy (1.65) Build done.
remove cast
2023-09-03 19:58:57 +00:00

70 lines
2.4 KiB
Rust

use crate::func::context::*;
use super::*;
pub trait MappableOrigin<'a, Ctx: Context<'a>>: Origin<'a, Ctx> {
fn map<B: Mentionable<'a, Ctx>>(
self: Arc<Self>,
map_ok: impl 'a + Send + Sync + Clone + Fn(Arc<Self::Mtbl>) -> B,
map_err: impl 'a
+ Send
+ Sync
+ Clone
+ Fn(ParseError<'a, OFctr<'a, Ctx, Self>>) -> ParseError<'a, B::Fctr>,
map_factory: impl 'a + FnOnce(OFctr<'a, Ctx, Self>) -> B::Fctr,
) -> Arc<dyn Origin<'a, Ctx, Mtbl = B>>
where
OFctr<'a, Ctx, Self>: Factory<'a, Ctx, _Mtbl = Self::Mtbl>,
Self::Mtbl: MentionableTop<'a, Ctx>,
{
let origin_r = self.clone();
let origin_rb = self.clone();
let origin: WrappedOrigin<'a, Ctx, B> = WrappedOrigin {
w_factory: map_factory(self.factory()),
w_resolve: Box::new(move || {
let origin = origin_r.clone();
let map_ok = map_ok.clone();
let map_err = map_err.clone();
map_resolve(move || origin.ref_resolve(), map_ok, map_err)
}),
w_resolve_bytes: Box::new(move || origin_rb.ref_resolve_bytes()),
};
Arc::new(origin)
}
}
impl<'a, Ctx: Context<'a>, O: ?Sized + Origin<'a, Ctx>> MappableOrigin<'a, Ctx> for O {}
fn map_resolve<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, B: Mentionable<'a, Ctx>>(
resolve: impl 'a + Send + Fn() -> Resolution<'a, Ctx, A>,
map_ok: impl 'a + Send + Fn(Arc<A>) -> B,
map_err: impl 'a + Send + Fn(ParseError<'a, A::Fctr>) -> ParseError<'a, B::Fctr>,
) -> Resolution<'a, Ctx, B> {
Ctx::fmap(resolve(), move |resolved| match resolved {
Ok(mentionable) => Ok(Arc::new(map_ok(mentionable))),
Err(e) => Err(e.map_parse(map_err)),
})
}
struct WrappedOrigin<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> {
w_factory: A::Fctr,
w_resolve: Box<dyn 'a + Send + Sync + Fn() -> Resolution<'a, Ctx, A>>,
w_resolve_bytes: Box<dyn 'a + Send + Sync + Fn() -> HashResolution<'a, Ctx>>,
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for WrappedOrigin<'a, Ctx, A> {
type Mtbl = A;
fn factory(&self) -> Fctr<'a, Self::Mtbl> {
self.w_factory.clone()
}
fn resolve(self: Arc<Self>) -> Resolution<'a, Ctx, A> {
(self.w_resolve)()
}
fn resolve_bytes(self: Arc<Self>) -> HashResolution<'a, Ctx> {
(self.w_resolve_bytes)()
}
}