diff --git a/src/std.rs b/src/std.rs index b806f4f..5e4e1b1 100644 --- a/src/std.rs +++ b/src/std.rs @@ -11,6 +11,7 @@ pub mod nullable; pub mod point; pub mod tracing; mod typeless; +mod wrapped_origin; use std::{error::Error, fmt::Display, rc::Rc}; diff --git a/src/std/cast.rs b/src/std/cast.rs index ff22cf8..1dc4d3b 100644 --- a/src/std/cast.rs +++ b/src/std/cast.rs @@ -7,7 +7,7 @@ use std::convert::identity; use crate::core::*; -use super::{ctypeless::*, typeless::*, *}; +use super::{ctypeless::*, typeless::*, wrapped_origin::*, *}; struct CastResolver<'a, Ctx: 'a + Context> { points: Vec>>, diff --git a/src/std/typeless.rs b/src/std/typeless.rs index deeab07..299e0ad 100644 --- a/src/std/typeless.rs +++ b/src/std/typeless.rs @@ -1,103 +1,17 @@ -use std::rc::Rc; - use crate::core::*; -use super::{ctypeless::*, *}; - -struct WrappedOrigin<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> { - w_factory: A::Fctr, - w_resolve: Box 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> { - Rc::new(WrappedOrigin { - w_factory: factory, - w_resolve: Box::new(resolve), - }) -} - -trait MappableOrigin<'a, Ctx: 'a + Context>: Origin<'a, Ctx> { - fn map>( - self: Rc, - map_ok: impl 'a + Clone + Fn(Rc) -> B, - map_err: impl 'a - + Clone - + Fn( - <>::Fctr as Factory<'a, Ctx>>::ParseError, - ) -> >::ParseError, - map_factory: impl 'a + FnOnce(>::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) -> B, - map_err: impl 'a - + Fn(>::ParseError) -> >::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>( - self: Rc, - map_ok: impl 'a + Clone + Fn(Rc) -> B, - map_err: impl 'a - + Clone - + Fn( - <>::Fctr as Factory<'a, Ctx>>::ParseError, - ) -> >::ParseError, - map_factory: impl 'a + FnOnce(>::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) -> >::Fctr { - self.w_factory.clone() - } - - fn resolve(self: Rc) -> Resolution<'a, Ctx, A> { - (self.w_resolve)() - } -} +use super::{ctypeless::*, wrapped_origin::*}; impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> { /// Typeless version of the point. pub fn typeless(&self) -> Point<'a, Ctx, TypelessMentionable<'a, Ctx>> { Point { point: self.point, - origin: Rc::new(self.origin.clone().map( + origin: self.origin.clone().map( TypelessMentionable::from_typed, TypelessError::from_typed, TypelessFactory::from_typed, - )), + ), } } } diff --git a/src/std/wrapped_origin.rs b/src/std/wrapped_origin.rs new file mode 100644 index 0000000..a547388 --- /dev/null +++ b/src/std/wrapped_origin.rs @@ -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> { + Rc::new(WrappedOrigin { + w_factory: factory, + w_resolve: Box::new(resolve), + }) +} + +pub trait MappableOrigin<'a, Ctx: 'a + Context>: Origin<'a, Ctx> { + fn map>( + self: Rc, + map_ok: impl 'a + Clone + Fn(Rc) -> B, + map_err: impl 'a + + Clone + + Fn( + <>::Fctr as Factory<'a, Ctx>>::ParseError, + ) -> >::ParseError, + map_factory: impl 'a + FnOnce(>::Fctr) -> B::Fctr, + ) -> Rc>; +} + +impl<'a, Ctx: 'a + Context, O: ?Sized + Origin<'a, Ctx>> MappableOrigin<'a, Ctx> for O { + fn map>( + self: Rc, + map_ok: impl 'a + Clone + Fn(Rc) -> B, + map_err: impl 'a + + Clone + + Fn( + <>::Fctr as Factory<'a, Ctx>>::ParseError, + ) -> >::ParseError, + map_factory: impl 'a + FnOnce(>::Fctr) -> B::Fctr, + ) -> Rc> { + 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) -> B, + map_err: impl 'a + + Fn(>::ParseError) -> >::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 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) -> >::Fctr { + self.w_factory.clone() + } + + fn resolve(self: Rc) -> Resolution<'a, Ctx, A> { + (self.w_resolve)() + } +}