use crate::core::*; use crate::std::*; struct CastResolver<'a, Ctx: 'a + Context> { points: Vec>>, } pub enum CastError<'a> { Typeless(TypelessError<'a>), AddressIndexOutOfBounds(usize), AddressPointMismatch { expected: Hash, received: Hash, index: usize, }, } impl<'a, Ctx: 'a + Context> Resolver<'a, Ctx> for CastResolver<'a, Ctx> where Ctx::LookupError: From>, { fn resolve(self: Rc, address: Address) -> HashResolution<'a, Ctx> { let point = match self.points.get(address.index) { Some(point) => point, None => { return Ctx::T::pure(Err(CastError::AddressIndexOutOfBounds(address.index).into())); } }; if point.point != address.point { return Ctx::T::pure(Err(CastError::AddressPointMismatch { expected: point.point, received: address.point, index: address.index, } .into())); } Ctx::T::fmap( |resolved| match resolved { Ok(mentionable) => { let mut vec = Vec::new(); mentionable.serialize(&mut vec); let resolver: Rc> = Rc::new(CastResolver { points: mentionable.points(), }); Ok((vec, resolver)) } Err(error) => Err(match error { ResolutionError::Lookup(lookup_error) => lookup_error, ResolutionError::Parse(parse_error) => CastError::Typeless(parse_error).into(), }), }, point.resolve(), ) } } pub type CastResult<'a, Ctx, A> = Result>::Fctr as Factory<'a, Ctx>>::ParseError>; impl<'a, Ctx: Context> TypelessMentionable<'a, Ctx> where Ctx::LookupError: From>, { /// . /// /// # Errors /// /// This function will return an error if . pub fn cast>(&self, factory: A::Fctr) -> CastResult<'a, Ctx, A> { let mut vec = Vec::new(); self.serialize(&mut vec); factory.parse_slice( &vec, Rc::new(CastResolver { points: self.points(), }), ) } }