use std::sync::Arc; use crate::rcore::*; use super::{singular::*, *}; pub trait CastMentionable<'a, Ctx: Context<'a>>: Mentionable<'a, Ctx> { fn m_cast>(&self, factory: &Fctr<'a, A>) -> ParseResultA<'a, A> { factory.parse_slice( &self.bytes(), &SingularResolver::from_mentionable(self).robust(), ) } } impl<'a, Ctx: Context<'a>, B: Mentionable<'a, Ctx>> CastMentionable<'a, Ctx> for B {} struct CastedOrigin { origin: Arc, factory: F, } impl<'a, Ctx: Context<'a>, O: ?Sized + Origin<'a, Ctx>, F: Factory<'a, Ctx>> Origin<'a, Ctx> for CastedOrigin { type Mtbl = F::Mtbl; fn factory(&self) -> OFctr<'a, Ctx, Self> { self.factory.clone() } fn resolve(self: Arc) -> Resolution<'a, Ctx, Self::Mtbl> where OFctr<'a, Ctx, Self>: FactoryParse<'a, Ctx>, { self.clone().origin.resolve_bytes_map(move |resolved| { resolved .map_err(ResolutionError::Lookup) .and_then(|(src, resolver)| { self.factory .parse_slice(&src, &resolver) .map_err(ResolutionError::Parse) }) .map(Arc::new) }) } fn resolve_bytes(self: Arc) -> HashResolution<'a, Ctx> { self.origin.ref_resolve_bytes() } } pub trait CastOrigin<'a, Ctx: Context<'a>>: Origin<'a, Ctx> { fn o_cast>( self: &Arc, factory: Fctr<'a, A>, ) -> Arc> { Arc::new(CastedOrigin { origin: self.clone(), factory, }) as _ } } impl<'a, Ctx: Context<'a>, O: ?Sized + Origin<'a, Ctx>> CastOrigin<'a, Ctx> for O {} pub trait CastPoint<'a, Ctx: Context<'a>> { fn p_cast>(self, factory: Fctr<'a, A>) -> Point<'a, Ctx, A>; } impl<'a, Ctx: Context<'a>, B: Mentionable<'a, Ctx>> CastPoint<'a, Ctx> for Point<'a, Ctx, B> { fn p_cast>(self, factory: Fctr<'a, A>) -> Point<'a, Ctx, A> { Point { point: self.point, origin: self.origin.o_cast(factory), } } }