remove cast
	
		
			
	
		
	
	
				
					
				
			This commit is contained in:
		
							parent
							
								
									36a12f3053
								
							
						
					
					
						commit
						01c9fd26ba
					
				| @ -4,7 +4,6 @@ | ||||
| 
 | ||||
| pub mod atomic; | ||||
| pub mod atomic_object; | ||||
| pub mod cast; | ||||
| pub mod collections; | ||||
| pub mod inject; | ||||
| pub mod inlining; | ||||
|  | ||||
							
								
								
									
										224
									
								
								src/rstd/cast.rs
									
									
									
									
									
								
							
							
						
						
									
										224
									
								
								src/rstd/cast.rs
									
									
									
									
									
								
							| @ -1,224 +0,0 @@ | ||||
| //! Utilities to convert from typeless instances defined in [`rcore`].
 | ||||
| //! See [`TypelessMentionable::cast`]/[`Point::cast`].
 | ||||
| //!
 | ||||
| //! p.s. the implementation is horrific.
 | ||||
| //!
 | ||||
| //! [`rcore`]: crate::rcore
 | ||||
| 
 | ||||
| use std::convert::identity; | ||||
| 
 | ||||
| use crate::func::context::*; | ||||
| use crate::rcore::*; | ||||
| 
 | ||||
| use super::{typeless::*, wrapped_origin::*, *}; | ||||
| 
 | ||||
| struct CastResolver<'a, Ctx: Context<'a>> { | ||||
|     points: Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>, | ||||
| } | ||||
| 
 | ||||
| /// Used to represent errors that might arise during resolution/parsion.
 | ||||
| /// Is expected to be classified as [`Context::LookupError`] rather than [`FactoryBase::ParseError`].
 | ||||
| /// [`CastError::AddressIndexOutOfBounds`] and [`CastError::AddressPointMismatch`]
 | ||||
| /// variants generally shouldn't happen.
 | ||||
| #[derive(Debug)] | ||||
| pub enum CastError<'a> { | ||||
|     Typeless(TypelessError<'a>), | ||||
|     /// If you don't know what that means, it's a good idea to [`panic!`].
 | ||||
|     /// Happens due to internal resolver using indices rather than `point`s.
 | ||||
|     /// This error usually indicates inconsistent behaviour
 | ||||
|     /// of [`MentionableTop::points_typed`] and/or [`MentionableTop::topology`].
 | ||||
|     AddressIndexOutOfBounds { | ||||
|         index: usize, | ||||
|         length: usize, | ||||
|     }, | ||||
|     /// See [`CastError::AddressIndexOutOfBounds`].
 | ||||
|     AddressPointMismatch { | ||||
|         expected: Hash, | ||||
|         received: Hash, | ||||
|         index: usize, | ||||
|     }, | ||||
| } | ||||
| 
 | ||||
| pub trait CastCtx<'a>: Context<'a> { | ||||
|     fn from_cast(cast_error: CastError<'a>) -> Self::LookupError; | ||||
| } | ||||
| 
 | ||||
| impl<'a, Ctx: Context<'a>> CastCtx<'a> for Ctx | ||||
| where | ||||
|     Self::LookupError: From<CastError<'a>>, | ||||
| { | ||||
|     fn from_cast(cast_error: CastError<'a>) -> Self::LookupError { | ||||
|         cast_error.into() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a> Display for CastError<'a> { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         match self { | ||||
|             Self::Typeless(typeless_error) => { | ||||
|                 write!(f, "typeless cast error: {}", typeless_error) | ||||
|             } | ||||
|             Self::AddressIndexOutOfBounds { index, length } => { | ||||
|                 write!(f, "cast index out of bound: {}>={}", index, length) | ||||
|             } | ||||
|             Self::AddressPointMismatch { | ||||
|                 expected, | ||||
|                 received, | ||||
|                 index, | ||||
|             } => write!( | ||||
|                 f, | ||||
|                 "address mismatch at index {}: {}!={}", | ||||
|                 index, | ||||
|                 hex(expected), | ||||
|                 hex(received), | ||||
|             ), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a> CastError<'a> { | ||||
|     fn pure<Ctx: CastCtx<'a>>(self) -> HashResolution<'a, Ctx> { | ||||
|         Ctx::pure(Err(Ctx::from_cast(self))) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a, Ctx: CastCtx<'a>> CastResolver<'a, Ctx> { | ||||
|     fn rc(points: Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>) -> Arc<dyn Resolver<'a, Ctx>> { | ||||
|         Arc::new(Self { points }) | ||||
|     } | ||||
| 
 | ||||
|     fn get_point_impl( | ||||
|         &self, | ||||
|         index: usize, | ||||
|     ) -> Result<&Point<'a, Ctx, TypelessMentionable<'a, Ctx>>, CastError<'a>> { | ||||
|         match self.points.get(index) { | ||||
|             Some(point) => Ok(point), | ||||
|             None => Err(CastError::AddressIndexOutOfBounds { | ||||
|                 index, | ||||
|                 length: self.points.len(), | ||||
|             }), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn validate_point( | ||||
|         &self, | ||||
|         point: &Point<'a, Ctx, TypelessMentionable<'a, Ctx>>, | ||||
|         address: Address, | ||||
|     ) -> Result<(), CastError<'a>> { | ||||
|         if point.point == address.point { | ||||
|             Ok(()) | ||||
|         } else { | ||||
|             Err(CastError::AddressPointMismatch { | ||||
|                 expected: point.point, | ||||
|                 received: address.point, | ||||
|                 index: address.index, | ||||
|             }) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn get_point( | ||||
|         &self, | ||||
|         address: Address, | ||||
|     ) -> Result<&Point<'a, Ctx, TypelessMentionable<'a, Ctx>>, CastError<'a>> { | ||||
|         let point = self.get_point_impl(address.index)?; | ||||
|         self.validate_point(point, address)?; | ||||
|         Ok(point) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn map_resolved<'a, Ctx: CastCtx<'a>>( | ||||
|     resolved: ResolutionResult<'a, Ctx, TypelessMentionable<'a, Ctx>>, | ||||
| ) -> HashResolutionResult<'a, Ctx> { | ||||
|     resolved.map_err(lookup_error::<Ctx>).map(|mentionable| { | ||||
|         ( | ||||
|             mentionable.bytes(), | ||||
|             CastResolver::rc(mentionable.points_vec()), | ||||
|         ) | ||||
|     }) | ||||
| } | ||||
| 
 | ||||
| impl<'a, Ctx: CastCtx<'a>> Resolver<'a, Ctx> for CastResolver<'a, Ctx> { | ||||
|     fn resolve(self: Arc<Self>, address: Address) -> HashResolution<'a, Ctx> { | ||||
|         let point = match self.get_point(address) { | ||||
|             Ok(point) => point, | ||||
|             Err(cast_error) => return cast_error.pure::<Ctx>(), | ||||
|         }; | ||||
|         point.resolve_map(map_resolved) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a, Ctx: CastCtx<'a>> TypelessMentionable<'a, Ctx> { | ||||
|     pub fn cast_full<A: Mentionable<'a, Ctx>>( | ||||
|         &self, | ||||
|         factory: A::Fctr, | ||||
|         map_resolver: impl FnOnce(Arc<dyn Resolver<'a, Ctx>>) -> Arc<dyn Resolver<'a, Ctx>>, | ||||
|     ) -> ParseResultA<'a, A> { | ||||
|         factory.parse_slice( | ||||
|             &self.bytes(), | ||||
|             &map_resolver(CastResolver::rc(self.points_vec())), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     /// Re-parse the object as if it is of a specific type. Has potential to break topology.
 | ||||
|     pub fn cast<A: Mentionable<'a, Ctx>>(&self, factory: A::Fctr) -> ParseResultA<'a, A> { | ||||
|         self.cast_full(factory, identity) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn lookup_error<'a, Ctx: CastCtx<'a>>( | ||||
|     error: ResolutionFailure<'a, Ctx, TypelessMentionable<'a, Ctx>>, | ||||
| ) -> Ctx::LookupError { | ||||
|     match error { | ||||
|         ResolutionError::Lookup(lookup_error) => lookup_error, | ||||
|         ResolutionError::Parse(parse_error) => Ctx::from_cast(CastError::Typeless(parse_error)), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn cast_resolved<'a, Ctx: CastCtx<'a>, A: Mentionable<'a, Ctx>>( | ||||
|     resolved: ResolutionResult<'a, Ctx, TypelessMentionable<'a, Ctx>>, | ||||
|     factory: A::Fctr, | ||||
| ) -> ResolutionResult<'a, Ctx, A> { | ||||
|     resolved | ||||
|         .map_err(lookup_error::<Ctx>) | ||||
|         .map_err(ResolutionError::Lookup)? | ||||
|         .cast(factory) | ||||
|         .map_err(ResolutionError::Parse) | ||||
|         .map(Arc::new) | ||||
| } | ||||
| 
 | ||||
| fn cast_resolve<'a, Ctx: CastCtx<'a>, A: Mentionable<'a, Ctx>>( | ||||
|     typeless_origin: Arc<dyn Origin<'a, Ctx, Mtbl = TypelessMentionable<'a, Ctx>>>, | ||||
|     factory: A::Fctr, | ||||
| ) -> Resolution<'a, Ctx, A> { | ||||
|     typeless_origin.resolve_map(|resolved| cast_resolved(resolved, factory)) | ||||
| } | ||||
| 
 | ||||
| fn cast_origin<'a, Ctx: CastCtx<'a>, A: Mentionable<'a, Ctx>>( | ||||
|     typeless_origin: Arc<dyn Origin<'a, Ctx, Mtbl = TypelessMentionable<'a, Ctx>>>, | ||||
|     factory: A::Fctr, | ||||
| ) -> Arc<dyn Origin<'a, Ctx, Mtbl = A>> { | ||||
|     let origin_rb = typeless_origin.clone(); | ||||
|     wrapped_origin( | ||||
|         factory.clone(), | ||||
|         move || cast_resolve(typeless_origin.clone(), factory.clone()), | ||||
|         move || origin_rb.ref_resolve_bytes(), | ||||
|     ) | ||||
| } | ||||
| 
 | ||||
| impl<'a, Ctx: CastCtx<'a>> Point<'a, Ctx, TypelessMentionable<'a, Ctx>> { | ||||
|     fn cast_origin<A: Mentionable<'a, Ctx>>( | ||||
|         &self, | ||||
|         factory: A::Fctr, | ||||
|     ) -> Arc<dyn Origin<'a, Ctx, Mtbl = A>> { | ||||
|         let typeless_origin = self.origin.clone(); | ||||
|         cast_origin(typeless_origin, factory) | ||||
|     } | ||||
| 
 | ||||
|     /// See [`TypelessMentionable::cast`]
 | ||||
|     pub fn cast<A: Mentionable<'a, Ctx>>(&self, factory: A::Fctr) -> Point<'a, Ctx, A> { | ||||
|         Point { | ||||
|             point: self.point, | ||||
|             origin: self.cast_origin(factory), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -2,7 +2,7 @@ | ||||
| //!
 | ||||
| //! [`rcore`]: crate::rcore
 | ||||
| 
 | ||||
| use super::{cast::*, wrapped_origin::*, *}; | ||||
| use super::{singular::*, tcast::*, wrapped_origin::*, *}; | ||||
| use crate::mode::*; | ||||
| 
 | ||||
| type TypelessSerialize<'a> = dyn 'a + Send + Sync + Fn(&mut dyn Serializer); | ||||
| @ -112,7 +112,7 @@ impl<'a, Ctx: Context<'a>> CRegularFactory<'a, Ctx> for TypelessFactory<'a, Ctx> | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a, Ctx: CastCtx<'a>> TypelessMentionable<'a, Ctx> { | ||||
| impl<'a, Ctx: SingularCtx<'a>> TypelessMentionable<'a, Ctx> { | ||||
|     pub fn from_typed<A: Mentionable<'a, Ctx>>(mentionable: Arc<A>) -> Self { | ||||
|         let factory = TypelessFactory::from_typed(mentionable.factory()); | ||||
|         let topology = mentionable.topology(); | ||||
| @ -126,7 +126,7 @@ impl<'a, Ctx: CastCtx<'a>> TypelessMentionable<'a, Ctx> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a, Ctx: CastCtx<'a>, F: Factory<'a, Ctx>> Tde<'a, Ctx> for F { | ||||
| impl<'a, Ctx: SingularCtx<'a>, F: Factory<'a, Ctx>> Tde<'a, Ctx> for F { | ||||
|     fn clone_box(&self) -> TdeBox<'a, Ctx> { | ||||
|         Box::new(self.clone()) | ||||
|     } | ||||
| @ -142,7 +142,7 @@ impl<'a, Ctx: CastCtx<'a>, F: Factory<'a, Ctx>> Tde<'a, Ctx> for F { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a, Ctx: CastCtx<'a>, F: Factory<'a, Ctx>> Tut<'a, Ctx> for F { | ||||
| impl<'a, Ctx: SingularCtx<'a>, F: Factory<'a, Ctx>> Tut<'a, Ctx> for F { | ||||
|     fn clone_box(&self) -> TutBox<'a, Ctx> { | ||||
|         Box::new(self.clone()) | ||||
|     } | ||||
| @ -153,7 +153,7 @@ impl<'a, Ctx: CastCtx<'a>, F: Factory<'a, Ctx>> Tut<'a, Ctx> for F { | ||||
|         tail: &[u8], | ||||
|     ) -> Result<TypelessMentionable<'a, Ctx>, TypelessError<'a>> { | ||||
|         self.extend( | ||||
|             match mentionable.cast(self.clone()) { | ||||
|             match mentionable.m_cast(self) { | ||||
|                 Ok(m) => m, | ||||
|                 Err(e) => return Err(TypelessError::from_typed(e)), | ||||
|             }, | ||||
| @ -165,7 +165,7 @@ impl<'a, Ctx: CastCtx<'a>, F: Factory<'a, Ctx>> Tut<'a, Ctx> for F { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a, Ctx: CastCtx<'a>> TypelessFactory<'a, Ctx> { | ||||
| impl<'a, Ctx: SingularCtx<'a>> TypelessFactory<'a, Ctx> { | ||||
|     pub fn from_typed<F: Factory<'a, Ctx>>(factory: F) -> Self { | ||||
|         TypelessFactory { | ||||
|             t_deserialize: Box::new(factory.clone()), | ||||
| @ -180,7 +180,7 @@ impl<'a> TypelessError<'a> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a, Ctx: CastCtx<'a>, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> { | ||||
| impl<'a, Ctx: SingularCtx<'a>, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> { | ||||
|     /// Typeless version of the point.
 | ||||
|     pub fn typeless(&self) -> Point<'a, Ctx, TypelessMentionable<'a, Ctx>> { | ||||
|         Point { | ||||
| @ -201,7 +201,7 @@ pub trait MentionableExt<'a, Ctx: Context<'a>>: Mentionable<'a, Ctx> { | ||||
|     fn points_vec(&self) -> Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>; | ||||
| } | ||||
| 
 | ||||
| impl<'a, Ctx: CastCtx<'a>, A: Mentionable<'a, Ctx>> MentionableExt<'a, Ctx> for A { | ||||
| impl<'a, Ctx: SingularCtx<'a>, A: Mentionable<'a, Ctx>> MentionableExt<'a, Ctx> for A { | ||||
|     fn points_typeless(&self, points: &mut Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>) { | ||||
|         self.points_typed(points) | ||||
|     } | ||||
| @ -213,7 +213,7 @@ impl<'a, Ctx: CastCtx<'a>, A: Mentionable<'a, Ctx>> MentionableExt<'a, Ctx> for | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a, Ctx: CastCtx<'a>> PointsVisitor<'a, Ctx> | ||||
| impl<'a, Ctx: SingularCtx<'a>> PointsVisitor<'a, Ctx> | ||||
|     for Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>> | ||||
| { | ||||
|     fn visit<A: Mentionable<'a, Ctx>>(&mut self, point: &Point<'a, Ctx, A>) { | ||||
|  | ||||
| @ -2,18 +2,6 @@ use crate::func::context::*; | ||||
| 
 | ||||
| use super::*; | ||||
| 
 | ||||
| pub fn wrapped_origin<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>>( | ||||
|     factory: A::Fctr, | ||||
|     resolve: impl 'a + Send + Sync + Fn() -> Resolution<'a, Ctx, A>, | ||||
|     resolve_bytes: impl 'a + Send + Sync + Fn() -> HashResolution<'a, Ctx>, | ||||
| ) -> Arc<dyn Origin<'a, Ctx, Mtbl = A>> { | ||||
|     Arc::new(WrappedOrigin { | ||||
|         w_factory: factory, | ||||
|         w_resolve: Box::new(resolve), | ||||
|         w_resolve_bytes: Box::new(resolve_bytes), | ||||
|     }) | ||||
| } | ||||
| 
 | ||||
| pub trait MappableOrigin<'a, Ctx: Context<'a>>: Origin<'a, Ctx> { | ||||
|     fn map<B: Mentionable<'a, Ctx>>( | ||||
|         self: Arc<Self>, | ||||
|  | ||||
| @ -7,7 +7,8 @@ use sha2::{Digest, Sha256}; | ||||
| 
 | ||||
| use crate::func::{context::*, *}; | ||||
| use crate::rcore::*; | ||||
| use crate::rstd::{cast::*, inject::*, typeless::*}; | ||||
| use crate::rstd::singular::*; | ||||
| use crate::rstd::{inject::*, typeless::*}; | ||||
| 
 | ||||
| pub struct NoDiagnostic; | ||||
| 
 | ||||
| @ -30,7 +31,7 @@ pub struct TestContextPlain; | ||||
| #[derive(Debug)] | ||||
| pub enum TestLookupError<'a> { | ||||
|     Typeless(TypelessError<'a>), | ||||
|     Cast(CastError<'a>), | ||||
|     Singular(SingularError), | ||||
|     EmptyResolverAccess(Address), | ||||
| } | ||||
| 
 | ||||
| @ -40,9 +41,9 @@ impl<'a> From<TypelessError<'a>> for TestLookupError<'a> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a> From<CastError<'a>> for TestLookupError<'a> { | ||||
|     fn from(value: CastError<'a>) -> Self { | ||||
|         Self::Cast(value) | ||||
| impl<'a> From<SingularError> for TestLookupError<'a> { | ||||
|     fn from(value: SingularError) -> Self { | ||||
|         Self::Singular(value) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -52,8 +53,8 @@ impl<'a> Display for TestLookupError<'a> { | ||||
|             Self::Typeless(typeless_error) => { | ||||
|                 write!(f, "typeless lookup failure: {}", typeless_error) | ||||
|             } | ||||
|             Self::Cast(cast_error) => { | ||||
|                 write!(f, "cast failure: {}", cast_error) | ||||
|             Self::Singular(singular_error) => { | ||||
|                 write!(f, "singular failure: {}", singular_error) | ||||
|             } | ||||
|             Self::EmptyResolverAccess(address) => { | ||||
|                 write!(f, "accessed an empty resolved at address {}", address) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user