From 79514257386ed44501a105341c9a1db3e2052ff5 Mon Sep 17 00:00:00 2001 From: timofey Date: Sun, 23 Apr 2023 00:47:47 +0000 Subject: [PATCH] extract resolution --- src/core.rs | 158 +--------------------------------------- src/core/resolution.rs | 159 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+), 156 deletions(-) create mode 100644 src/core/resolution.rs diff --git a/src/core.rs b/src/core.rs index 67527eb..2b2faf0 100644 --- a/src/core.rs +++ b/src/core.rs @@ -3,11 +3,13 @@ //! Allows for more generic behaviour via [`Context`], as opposed to original async-only. mod hashing; +mod resolution; mod serialization; mod slice_deserializer; mod typeless; pub use hashing::*; +pub use resolution::*; pub use serialization::*; pub use slice_deserializer::*; pub use typeless::*; @@ -28,28 +30,9 @@ pub trait Context { fn hash(s: &[u8]) -> Hash; } -/// Failure yielded by [`Origin`]. -#[derive(Debug)] -pub enum ResolutionError { - Lookup(L), - Parse(P), -} - -/// See [`ResolutionResult`]. -pub type ResolutionFailure<'a, Ctx, A> = ResolutionError< - ::LookupError<'a>, - <>::Fctr as Factory<'a, Ctx>>::ParseError, ->; - -/// Result yielded by [`Origin`]. -pub type ResolutionResult<'a, Ctx, A> = Result, ResolutionFailure<'a, Ctx, A>>; - /// Helper alias for [`WeakFunctor::F`] of [`Context::T`]. pub type Wrapped<'a, Ctx, A> = <::T as WeakFunctor>::F<'a, A>; -/// Wrapped result returned by [`Origin`]. -pub type Resolution<'a, Ctx, A> = Wrapped<'a, Ctx, ResolutionResult<'a, Ctx, A>>; - /// Fundamental trait for ADN objects. pub trait Mentionable<'a, Ctx: 'a + Context>: 'a + Serializable { /// Type of the associated factory. @@ -77,28 +60,6 @@ pub trait Mentionable<'a, Ctx: 'a + Context>: 'a + Serializable { } } -/// Short-hand for the type of values returned by [`Resolver::resolve`]. -pub type HashResolution<'a, Ctx> = Wrapped< - 'a, - Ctx, - Result<(Vec, Rc>), ::LookupError<'a>>, ->; - -/// Value accepted by [`Resolver::resolve`]. Includes index to make it order-sensitive. -#[derive(Clone, Copy, Debug)] -pub struct Address { - pub point: Hash, - /// Index of the point in the [`Mentionable::points()`]. - pub index: usize, -} - -/// Trait representing the "rainbow table" behaviour. -pub trait Resolver<'a, Ctx: 'a + Context>: 'a { - /// Successfully returned value should be the inverse of the point passed - /// with topology header ([`Mentionable::topology()`]) omitted. - fn resolve(self: Rc, address: Address) -> HashResolution<'a, Ctx>; -} - /// Short-hand for the type of vaalues returned by [`Factory::deserialize`]. pub type ParseResult<'a, Ctx, F> = Result<>::Mtbl, >::ParseError>; @@ -152,111 +113,6 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> { pub fn resolve(&self) -> Resolution<'a, Ctx, A> { self.origin.clone().resolve() } - - /// Make a [Point] from an [Address]. - pub fn from_address( - address: Address, - factory: A::Fctr, - resolver: Rc>, - ) -> Self { - Point { - point: address.point, - origin: Rc::new(ResolverOrigin { - r_factory: factory, - r_address: address, - r_resolver: resolver, - }), - } - } -} - -/// Preferred way to parse [Point]s off of a [Serializer]. -pub struct Addresses { - current: usize, -} - -impl Addresses { - /// Read the next [Address]. - pub fn next<'a>( - &mut self, - deserializer: &'a mut dyn Deserializer, - ) -> Result { - let point = deserializer.read_n_const::()?; - let address = Address { - point, - index: self.current, - }; - self.current += 1; - Ok(address) - } - - /// Read the next [Point]. - pub fn next_point<'a, 'b, Ctx: 'a + Context, A: Mentionable<'a, Ctx>>( - &mut self, - deserializer: &'b mut dyn Deserializer, - resolver: Rc>, - factory: A::Fctr, - ) -> Result, &'b [u8]> { - Ok(Point::from_address( - self.next(deserializer)?, - factory, - resolver, - )) - } - - /// Start reading the [Address]es. - fn start() -> Self { - Addresses { current: 0 } - } -} - -struct ResolverOrigin<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> { - r_factory: F, - r_address: Address, - r_resolver: Rc>, -} - -fn _resolve_origin<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>>( - origin: Rc>, -) -> Resolution<'a, Ctx, A> { - let resolution = origin.r_resolver.clone().resolve(origin.r_address); - Ctx::T::fmap( - move |resolved| match resolved { - Ok((src, resolver)) => match origin.r_factory.parse_slice(&src, resolver) { - Ok(mentionable) => Ok(Rc::new(mentionable)), - Err(parse_error) => Err(ResolutionError::Parse(parse_error)), - }, - Err(lookup_error) => Err(ResolutionError::Lookup(lookup_error)), - }, - resolution, - ) -} - -impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Origin<'a, Ctx> for ResolverOrigin<'a, Ctx, F> { - type Mtbl = F::Mtbl; - - fn factory(&self) -> >::Fctr { - self.r_factory.clone() - } - - fn resolve(self: Rc) -> Resolution<'a, Ctx, Self::Mtbl> { - _resolve_origin(self) - } -} - -fn _parse_slice<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>>( - factory: &A::Fctr, - slice: &[u8], - resolver: Rc>, -) -> ParseResult<'a, Ctx, A::Fctr> { - let mut deserializer = SliceDeserializer::from(slice); - let mentionable = factory.deserialize(&mut deserializer, resolver, &mut Addresses::start())?; - let tail = deserializer.read_all(); - if tail.is_empty() { - Ok(mentionable) - } else { - Err(factory.unexpected_tail(tail)) - } } /// Extension trait for factories. @@ -268,13 +124,3 @@ pub trait ExtFactory<'a, Ctx: 'a + Context>: Factory<'a, Ctx> { resolver: Rc>, ) -> ParseResult<'a, Ctx, Self>; } - -impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> ExtFactory<'a, Ctx> for F { - fn parse_slice( - &self, - slice: &[u8], - resolver: Rc>, - ) -> ParseResult<'a, Ctx, Self> { - _parse_slice::(self, slice, resolver) - } -} diff --git a/src/core/resolution.rs b/src/core/resolution.rs new file mode 100644 index 0000000..e49f74f --- /dev/null +++ b/src/core/resolution.rs @@ -0,0 +1,159 @@ +use super::*; + +/// Failure yielded by [`Origin`]. +#[derive(Debug)] +pub enum ResolutionError { + Lookup(L), + Parse(P), +} + +/// See [`ResolutionResult`]. +pub type ResolutionFailure<'a, Ctx, A> = ResolutionError< + ::LookupError<'a>, + <>::Fctr as Factory<'a, Ctx>>::ParseError, +>; + +/// Result yielded by [`Origin`]. +pub type ResolutionResult<'a, Ctx, A> = Result, ResolutionFailure<'a, Ctx, A>>; + +/// Wrapped result returned by [`Origin`]. +pub type Resolution<'a, Ctx, A> = Wrapped<'a, Ctx, ResolutionResult<'a, Ctx, A>>; + +/// Short-hand for the type of values returned by [`Resolver::resolve`]. +pub type HashResolution<'a, Ctx> = Wrapped< + 'a, + Ctx, + Result<(Vec, Rc>), ::LookupError<'a>>, +>; + +/// Value accepted by [`Resolver::resolve`]. Includes index to make it order-sensitive. +#[derive(Clone, Copy, Debug)] +pub struct Address { + pub point: Hash, + /// Index of the point in the [`Mentionable::points()`]. + pub index: usize, +} + +/// Trait representing the "rainbow table" behaviour. +pub trait Resolver<'a, Ctx: 'a + Context>: 'a { + /// Successfully returned value should be the inverse of the point passed + /// with topology header ([`Mentionable::topology()`]) omitted. + fn resolve(self: Rc, address: Address) -> HashResolution<'a, Ctx>; +} + +impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> { + /// Make a [Point] from an [Address]. + pub fn from_address( + address: Address, + factory: A::Fctr, + resolver: Rc>, + ) -> Self { + Point { + point: address.point, + origin: Rc::new(ResolverOrigin { + r_factory: factory, + r_address: address, + r_resolver: resolver, + }), + } + } +} + +/// Preferred way to parse [Point]s off of a [Serializer]. +pub struct Addresses { + current: usize, +} + +impl Addresses { + /// Read the next [Address]. + pub fn next<'a>( + &mut self, + deserializer: &'a mut dyn Deserializer, + ) -> Result { + let point = deserializer.read_n_const::()?; + let address = Address { + point, + index: self.current, + }; + self.current += 1; + Ok(address) + } + + /// Read the next [Point]. + pub fn next_point<'a, 'b, Ctx: 'a + Context, A: Mentionable<'a, Ctx>>( + &mut self, + deserializer: &'b mut dyn Deserializer, + resolver: Rc>, + factory: A::Fctr, + ) -> Result, &'b [u8]> { + Ok(Point::from_address( + self.next(deserializer)?, + factory, + resolver, + )) + } + + /// Start reading the [Address]es. + fn start() -> Self { + Addresses { current: 0 } + } +} + +struct ResolverOrigin<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> { + r_factory: F, + r_address: Address, + r_resolver: Rc>, +} + +fn _resolve_origin<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>>( + origin: Rc>, +) -> Resolution<'a, Ctx, A> { + let resolution = origin.r_resolver.clone().resolve(origin.r_address); + Ctx::T::fmap( + move |resolved| match resolved { + Ok((src, resolver)) => match origin.r_factory.parse_slice(&src, resolver) { + Ok(mentionable) => Ok(Rc::new(mentionable)), + Err(parse_error) => Err(ResolutionError::Parse(parse_error)), + }, + Err(lookup_error) => Err(ResolutionError::Lookup(lookup_error)), + }, + resolution, + ) +} + +impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Origin<'a, Ctx> for ResolverOrigin<'a, Ctx, F> { + type Mtbl = F::Mtbl; + + fn factory(&self) -> >::Fctr { + self.r_factory.clone() + } + + fn resolve(self: Rc) -> Resolution<'a, Ctx, Self::Mtbl> { + _resolve_origin(self) + } +} + +fn _parse_slice<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>>( + factory: &A::Fctr, + slice: &[u8], + resolver: Rc>, +) -> ParseResult<'a, Ctx, A::Fctr> { + let mut deserializer = SliceDeserializer::from(slice); + let mentionable = factory.deserialize(&mut deserializer, resolver, &mut Addresses::start())?; + let tail = deserializer.read_all(); + if tail.is_empty() { + Ok(mentionable) + } else { + Err(factory.unexpected_tail(tail)) + } +} + +impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> ExtFactory<'a, Ctx> for F { + fn parse_slice( + &self, + slice: &[u8], + resolver: Rc>, + ) -> ParseResult<'a, Ctx, Self> { + _parse_slice::(self, slice, resolver) + } +}