wrapped_origin

This commit is contained in:
AF 2023-05-07 17:41:56 +00:00
parent 084d99b82b
commit 2145a9d852
4 changed files with 91 additions and 90 deletions

View File

@ -11,6 +11,7 @@ pub mod nullable;
pub mod point; pub mod point;
pub mod tracing; pub mod tracing;
mod typeless; mod typeless;
mod wrapped_origin;
use std::{error::Error, fmt::Display, rc::Rc}; use std::{error::Error, fmt::Display, rc::Rc};

View File

@ -7,7 +7,7 @@ use std::convert::identity;
use crate::core::*; use crate::core::*;
use super::{ctypeless::*, typeless::*, *}; use super::{ctypeless::*, typeless::*, wrapped_origin::*, *};
struct CastResolver<'a, Ctx: 'a + Context> { struct CastResolver<'a, Ctx: 'a + Context> {
points: Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>, points: Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>,

View File

@ -1,103 +1,17 @@
use std::rc::Rc;
use crate::core::*; use crate::core::*;
use super::{ctypeless::*, *}; use super::{ctypeless::*, wrapped_origin::*};
struct WrappedOrigin<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> {
w_factory: A::Fctr,
w_resolve: Box<dyn 'a + Fn() -> Resolution<'a, Ctx, A>>,
}
pub fn wrapped_origin<'a, Ctx: 'a + Context, 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),
})
}
trait MappableOrigin<'a, Ctx: 'a + Context>: Origin<'a, Ctx> {
fn map<B: Mentionable<'a, Ctx>>(
self: Rc<Self>,
map_ok: impl 'a + Clone + Fn(Rc<Self::Mtbl>) -> B,
map_err: impl 'a
+ Clone
+ Fn(
<<Self::Mtbl as Mentionable<'a, Ctx>>::Fctr as Factory<'a, Ctx>>::ParseError,
) -> <B::Fctr as Factory<'a, Ctx>>::ParseError,
map_factory: impl 'a + FnOnce(<Self::Mtbl as Mentionable<'a, Ctx>>::Fctr) -> B::Fctr,
) -> WrappedOrigin<'a, Ctx, B>;
}
fn map_resolve<'a, Ctx: 'a + Context, 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(<A::Fctr as Factory<'a, Ctx>>::ParseError) -> <B::Fctr as Factory<'a, Ctx>>::ParseError,
) -> Resolution<'a, Ctx, B> {
Ctx::T::fmap(
move |resolved| match resolved {
Ok(mentionable) => Ok(Rc::new(map_ok(mentionable))),
Err(ResolutionError::Parse(parse_error)) => {
Err(ResolutionError::Parse(map_err(parse_error)))
}
Err(ResolutionError::Lookup(lookup_error)) => {
Err(ResolutionError::Lookup(lookup_error))
}
},
resolve(),
)
}
impl<'a, Ctx: 'a + Context, O: ?Sized + Origin<'a, Ctx>> MappableOrigin<'a, Ctx> for O {
fn map<B: Mentionable<'a, Ctx>>(
self: Rc<Self>,
map_ok: impl 'a + Clone + Fn(Rc<Self::Mtbl>) -> B,
map_err: impl 'a
+ Clone
+ Fn(
<<Self::Mtbl as Mentionable<'a, Ctx>>::Fctr as Factory<'a, Ctx>>::ParseError,
) -> <B::Fctr as Factory<'a, Ctx>>::ParseError,
map_factory: impl 'a + FnOnce(<Self::Mtbl as Mentionable<'a, Ctx>>::Fctr) -> B::Fctr,
) -> WrappedOrigin<'a, Ctx, B> {
let origin = self.clone();
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)
}),
}
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for WrappedOrigin<'a, Ctx, A> {
type Mtbl = A;
fn factory(&self) -> <Self::Mtbl as Mentionable<'a, Ctx>>::Fctr {
self.w_factory.clone()
}
fn resolve(self: Rc<Self>) -> Resolution<'a, Ctx, A> {
(self.w_resolve)()
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> { impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> {
/// Typeless version of the point. /// Typeless version of the point.
pub fn typeless(&self) -> Point<'a, Ctx, TypelessMentionable<'a, Ctx>> { pub fn typeless(&self) -> Point<'a, Ctx, TypelessMentionable<'a, Ctx>> {
Point { Point {
point: self.point, point: self.point,
origin: Rc::new(self.origin.clone().map( origin: self.origin.clone().map(
TypelessMentionable::from_typed, TypelessMentionable::from_typed,
TypelessError::from_typed, TypelessError::from_typed,
TypelessFactory::from_typed, TypelessFactory::from_typed,
)), ),
} }
} }
} }

86
src/std/wrapped_origin.rs Normal file
View File

@ -0,0 +1,86 @@
use super::*;
pub fn wrapped_origin<'a, Ctx: 'a + Context, 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: 'a + Context>: Origin<'a, Ctx> {
fn map<B: Mentionable<'a, Ctx>>(
self: Rc<Self>,
map_ok: impl 'a + Clone + Fn(Rc<Self::Mtbl>) -> B,
map_err: impl 'a
+ Clone
+ Fn(
<<Self::Mtbl as Mentionable<'a, Ctx>>::Fctr as Factory<'a, Ctx>>::ParseError,
) -> <B::Fctr as Factory<'a, Ctx>>::ParseError,
map_factory: impl 'a + FnOnce(<Self::Mtbl as Mentionable<'a, Ctx>>::Fctr) -> B::Fctr,
) -> Rc<dyn Origin<'a, Ctx, Mtbl = B>>;
}
impl<'a, Ctx: 'a + Context, O: ?Sized + Origin<'a, Ctx>> MappableOrigin<'a, Ctx> for O {
fn map<B: Mentionable<'a, Ctx>>(
self: Rc<Self>,
map_ok: impl 'a + Clone + Fn(Rc<Self::Mtbl>) -> B,
map_err: impl 'a
+ Clone
+ Fn(
<<Self::Mtbl as Mentionable<'a, Ctx>>::Fctr as Factory<'a, Ctx>>::ParseError,
) -> <B::Fctr as Factory<'a, Ctx>>::ParseError,
map_factory: impl 'a + FnOnce(<Self::Mtbl as Mentionable<'a, Ctx>>::Fctr) -> 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)
}
}
fn map_resolve<'a, Ctx: 'a + Context, 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(<A::Fctr as Factory<'a, Ctx>>::ParseError) -> <B::Fctr as Factory<'a, Ctx>>::ParseError,
) -> Resolution<'a, Ctx, B> {
Ctx::T::fmap(
move |resolved| match resolved {
Ok(mentionable) => Ok(Rc::new(map_ok(mentionable))),
Err(ResolutionError::Parse(parse_error)) => {
Err(ResolutionError::Parse(map_err(parse_error)))
}
Err(ResolutionError::Lookup(lookup_error)) => {
Err(ResolutionError::Lookup(lookup_error))
}
},
resolve(),
)
}
struct WrappedOrigin<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> {
w_factory: A::Fctr,
w_resolve: Box<dyn 'a + Fn() -> Resolution<'a, Ctx, A>>,
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for WrappedOrigin<'a, Ctx, A> {
type Mtbl = A;
fn factory(&self) -> <Self::Mtbl as Mentionable<'a, Ctx>>::Fctr {
self.w_factory.clone()
}
fn resolve(self: Rc<Self>) -> Resolution<'a, Ctx, A> {
(self.w_resolve)()
}
}