69 lines
2.3 KiB
Rust
69 lines
2.3 KiB
Rust
use crate::func::context::*;
|
|
|
|
use super::*;
|
|
|
|
pub fn wrapped_origin<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>>(
|
|
factory: A::Fctr,
|
|
resolve: impl 'a + Fn() -> Resolution<'a, Ctx, A>,
|
|
) -> Rc<dyn Origin<'a, Ctx, Mtbl = A>> {
|
|
Rc::new(WrappedOrigin {
|
|
w_factory: factory,
|
|
w_resolve: Box::new(resolve),
|
|
})
|
|
}
|
|
|
|
pub trait MappableOrigin<'a, Ctx: Context<'a>>: Origin<'a, Ctx> {
|
|
fn map<B: Mentionable<'a, Ctx>>(
|
|
self: Rc<Self>,
|
|
map_ok: impl 'a + Send + Sync + Clone + Fn(Rc<Self::Mtbl>) -> B,
|
|
map_err: impl 'a
|
|
+ Send
|
|
+ Sync
|
|
+ Clone
|
|
+ Fn(ParseError<'a, Ctx, OFctr<'a, Ctx, Self>>) -> ParseError<'a, Ctx, B::Fctr>,
|
|
map_factory: impl 'a + FnOnce(OFctr<'a, Ctx, Self>) -> B::Fctr,
|
|
) -> Rc<dyn Origin<'a, Ctx, Mtbl = B>> {
|
|
let origin = self.clone();
|
|
let origin: WrappedOrigin<'a, Ctx, B> = WrappedOrigin {
|
|
w_factory: map_factory(self.factory()),
|
|
w_resolve: Box::new(move || {
|
|
let origin = origin.clone();
|
|
let map_ok = map_ok.clone();
|
|
let map_err = map_err.clone();
|
|
map_resolve(move || origin.clone().resolve(), map_ok, map_err)
|
|
}),
|
|
};
|
|
Rc::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 + Fn() -> Resolution<'a, Ctx, A>,
|
|
map_ok: impl 'a + Fn(Rc<A>) -> B,
|
|
map_err: impl 'a + Fn(ParseError<'a, Ctx, A::Fctr>) -> ParseError<'a, Ctx, B::Fctr>,
|
|
) -> Resolution<'a, Ctx, B> {
|
|
Ctx::fmap(resolve(), move |resolved| match resolved {
|
|
Ok(mentionable) => Ok(Rc::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 + Fn() -> Resolution<'a, Ctx, A>>,
|
|
}
|
|
|
|
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, Ctx, Self::Mtbl> {
|
|
self.w_factory.clone()
|
|
}
|
|
|
|
fn resolve(self: Rc<Self>) -> Resolution<'a, Ctx, A> {
|
|
(self.w_resolve)()
|
|
}
|
|
}
|