From 9e578b6610d4ebe3bd689f9cafb108c91de29091 Mon Sep 17 00:00:00 2001 From: timofey Date: Sun, 23 Apr 2023 00:06:30 +0000 Subject: [PATCH] extract typeless and local_origin --- src/core.rs | 200 +++------------------------------------- src/core/typeless.rs | 132 ++++++++++++++++++++++++++ src/std.rs | 1 + src/std/local_origin.rs | 53 +++++++++++ 4 files changed, 200 insertions(+), 186 deletions(-) create mode 100644 src/core/typeless.rs create mode 100644 src/std/local_origin.rs diff --git a/src/core.rs b/src/core.rs index dc78c07..9c0f872 100644 --- a/src/core.rs +++ b/src/core.rs @@ -2,6 +2,10 @@ //! Brings [`Mentionable`]/[`Factory`]/[`Origin`] concepts from the original implementation in Python. //! Allows for more generic behaviour via [`Context`], as opposed to original async-only. +pub mod typeless; + +pub use typeless::*; + use std::{cmp::min, error::Error, fmt::Display, rc::Rc}; use crate::func::*; @@ -61,16 +65,6 @@ pub trait Serializer { fn tell(&self) -> usize; } -impl Serializer for Vec { - fn write(&mut self, buf: &[u8]) { - self.extend(buf); - } - - fn tell(&self) -> usize { - self.len() - } -} - /// See [`Serializer`]. pub trait Serializable { /// Expected to use [`Serializer::write`]. @@ -171,26 +165,6 @@ pub trait Origin<'a, Ctx: 'a + Context>: 'a { fn resolve(self: Rc) -> Resolution<'a, Ctx, Self::Mtbl>; } -struct LocalOrigin(Rc); - -impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for LocalOrigin { - type Mtbl = A; - - fn factory(&self) -> A::Fctr { - self.0.factory() - } - - fn resolve(self: Rc) -> Resolution<'a, Ctx, Self::Mtbl> { - Ctx::T::pure(Ok(self.0.clone())) - } -} - -impl From for LocalOrigin { - fn from(value: A) -> Self { - LocalOrigin(value.into()) - } -} - /// The main way to represent a reference in ADN. pub struct Point<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> { pub point: Hash, @@ -207,32 +181,11 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Clone for Point<'a, Ctx, A> } impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> { - fn prepare_bytes_for_hashing(mentioned: &A) -> Vec { - let mut vec = mentioned.topology().to_vec(); - mentioned.serialize(&mut vec); - vec - } - - fn from_fields(point: Hash, origin: Rc>) -> Self { - Point { point, origin } - } - - fn from_values>(point: Hash, origin: O) -> Self { - Self::from_fields(point, Rc::new(origin)) - } - /// See [`Origin::resolve`]. pub fn resolve(&self) -> Resolution<'a, Ctx, A> { self.origin.clone().resolve() } - fn from_mentionable(mentionable: A) -> Self { - Self::from_values( - Ctx::hash(Self::prepare_bytes_for_hashing(&mentionable).as_slice()), - LocalOrigin::from(mentionable), - ) - } - /// Make a [Point] from an [Address]. pub fn from_address( address: Address, @@ -250,141 +203,6 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> { } } -impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> From for Point<'a, Ctx, A> { - fn from(value: A) -> Self { - Self::from_mentionable(value) - } -} - -type TypelessSerialize<'a> = dyn 'a + Fn(&mut dyn Serializer); - -/// See [`Mentionable::points`]. -pub struct TypelessMentionable<'a, Ctx: 'a + Context> { - t_serialize: Box>, - t_factory: TypelessFactory<'a, Ctx>, - t_topology: Hash, - t_points: Vec>>, -} - -type TypelessParsed<'a, Ctx> = Result, Box>; - -type TypelessDeserialize<'a, Ctx> = dyn 'a - + Fn(&mut dyn Deserializer, Rc>, &mut Addresses) -> TypelessParsed<'a, Ctx>; - -type TypelessUnexpectedTail<'a> = dyn 'a + Fn(&[u8]) -> TypelessError<'a>; - -/// See [`Mentionable::points`]/[`TypelessMentionable`]. -pub struct TypelessFactory<'a, Ctx: 'a + Context> { - t_deserialize: Rc>, - t_unexpected_tail: Rc>, -} - -impl<'a, Ctx: 'a + Context> Serializable for TypelessMentionable<'a, Ctx> { - fn serialize(&self, serializer: &mut dyn Serializer) { - (self.t_serialize)(serializer); - } -} - -impl<'a, Ctx: 'a + Context> Mentionable<'a, Ctx> for TypelessMentionable<'a, Ctx> { - type Fctr = TypelessFactory<'a, Ctx>; - - fn factory(&self) -> Self::Fctr { - self.t_factory.clone() - } - - fn topology(&self) -> Hash { - self.t_topology - } - - fn points(&self, points: &mut Vec>>) { - points.extend(self.t_points.iter().map(Clone::clone)); - } - - fn points_vec(&self) -> Vec>> { - self.t_points.clone() - } -} - -impl<'a, Ctx: 'a + Context> Clone for TypelessFactory<'a, Ctx> { - fn clone(&self) -> Self { - Self { - t_deserialize: self.t_deserialize.clone(), - t_unexpected_tail: self.t_unexpected_tail.clone(), - } - } -} - -/// See [`Mentionable::points`]/[`TypelessFactory`]. -#[derive(Debug)] -pub struct TypelessError<'a>(Box); - -impl<'a> Display for TypelessError<'a> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_fmt(format_args!("typeless error: {}", self.0)) - } -} - -impl<'a> Error for TypelessError<'a> {} - -impl<'a, Ctx: 'a + Context> Factory<'a, Ctx> for TypelessFactory<'a, Ctx> { - type Mtbl = TypelessMentionable<'a, Ctx>; - - type ParseError = TypelessError<'a>; - - fn deserialize( - &self, - deserializer: &mut dyn Deserializer, - resolver: Rc>, - addresses: &mut Addresses, - ) -> ParseResult<'a, Ctx, Self> { - match (self.t_deserialize)(deserializer, resolver, addresses) { - Ok(mentionable) => Ok(mentionable), - Err(error) => Err(TypelessError(error)), - } - } - - fn unexpected_tail(&self, tail: &[u8]) -> Self::ParseError { - (self.t_unexpected_tail)(tail) - } -} - -impl<'a, Ctx: 'a + Context> TypelessMentionable<'a, Ctx> { - pub fn from_typed>(mentionable: Rc) -> Self { - let factory = TypelessFactory::from_typed(mentionable.factory()); - let topology = mentionable.topology(); - let points = mentionable.points_vec(); - TypelessMentionable { - t_serialize: Box::new(move |serializer| mentionable.serialize(serializer)), - t_factory: factory, - t_topology: topology, - t_points: points, - } - } -} - -impl<'a, Ctx: 'a + Context> TypelessFactory<'a, Ctx> { - pub fn from_typed>(factory: F) -> Self { - let tail_factory = factory.clone(); - TypelessFactory { - t_deserialize: Rc::new(move |deserializer, resolver, addresses| { - match factory.deserialize(deserializer, resolver, addresses) { - Ok(mentionable) => Ok(TypelessMentionable::from_typed(Rc::new(mentionable))), - Err(error) => Err(Box::new(error)), - } - }), - t_unexpected_tail: Rc::new(move |tail| { - TypelessError::from_typed(tail_factory.unexpected_tail(tail)) - }), - } - } -} - -impl<'a> TypelessError<'a> { - pub fn from_typed(error: E) -> Self { - TypelessError(Box::new(error)) - } -} - /// Preferred way to parse [Point]s off of a [Serializer]. pub struct Addresses { current: usize, @@ -544,3 +362,13 @@ impl<'a> Deserializer for SliceDeserializer<'a> { self.pos } } + +impl Serializer for Vec { + fn write(&mut self, buf: &[u8]) { + self.extend(buf); + } + + fn tell(&self) -> usize { + self.len() + } +} diff --git a/src/core/typeless.rs b/src/core/typeless.rs new file mode 100644 index 0000000..298e140 --- /dev/null +++ b/src/core/typeless.rs @@ -0,0 +1,132 @@ +//! Typeless. See [`Mentionable::points`]. + +use super::*; + +type TypelessSerialize<'a> = dyn 'a + Fn(&mut dyn Serializer); + +/// See [`Mentionable::points`]. +pub struct TypelessMentionable<'a, Ctx: 'a + Context> { + t_serialize: Box>, + t_factory: TypelessFactory<'a, Ctx>, + t_topology: Hash, + t_points: Vec>>, +} + +type TypelessParsed<'a, Ctx> = Result, Box>; + +type TypelessDeserialize<'a, Ctx> = dyn 'a + + Fn(&mut dyn Deserializer, Rc>, &mut Addresses) -> TypelessParsed<'a, Ctx>; + +type TypelessUnexpectedTail<'a> = dyn 'a + Fn(&[u8]) -> TypelessError<'a>; + +/// See [`Mentionable::points`]/[`TypelessMentionable`]. +pub struct TypelessFactory<'a, Ctx: 'a + Context> { + t_deserialize: Rc>, + t_unexpected_tail: Rc>, +} + +impl<'a, Ctx: 'a + Context> Serializable for TypelessMentionable<'a, Ctx> { + fn serialize(&self, serializer: &mut dyn Serializer) { + (self.t_serialize)(serializer); + } +} + +impl<'a, Ctx: 'a + Context> Mentionable<'a, Ctx> for TypelessMentionable<'a, Ctx> { + type Fctr = TypelessFactory<'a, Ctx>; + + fn factory(&self) -> Self::Fctr { + self.t_factory.clone() + } + + fn topology(&self) -> Hash { + self.t_topology + } + + fn points(&self, points: &mut Vec>>) { + points.extend(self.t_points.iter().map(Clone::clone)); + } + + fn points_vec(&self) -> Vec>> { + self.t_points.clone() + } +} + +impl<'a, Ctx: 'a + Context> Clone for TypelessFactory<'a, Ctx> { + fn clone(&self) -> Self { + Self { + t_deserialize: self.t_deserialize.clone(), + t_unexpected_tail: self.t_unexpected_tail.clone(), + } + } +} + +/// See [`Mentionable::points`]/[`TypelessFactory`]. +#[derive(Debug)] +pub struct TypelessError<'a>(Box); + +impl<'a> Display for TypelessError<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt(format_args!("typeless error: {}", self.0)) + } +} + +impl<'a> Error for TypelessError<'a> {} + +impl<'a, Ctx: 'a + Context> Factory<'a, Ctx> for TypelessFactory<'a, Ctx> { + type Mtbl = TypelessMentionable<'a, Ctx>; + + type ParseError = TypelessError<'a>; + + fn deserialize( + &self, + deserializer: &mut dyn Deserializer, + resolver: Rc>, + addresses: &mut Addresses, + ) -> ParseResult<'a, Ctx, Self> { + match (self.t_deserialize)(deserializer, resolver, addresses) { + Ok(mentionable) => Ok(mentionable), + Err(error) => Err(TypelessError(error)), + } + } + + fn unexpected_tail(&self, tail: &[u8]) -> Self::ParseError { + (self.t_unexpected_tail)(tail) + } +} + +impl<'a, Ctx: 'a + Context> TypelessMentionable<'a, Ctx> { + pub fn from_typed>(mentionable: Rc) -> Self { + let factory = TypelessFactory::from_typed(mentionable.factory()); + let topology = mentionable.topology(); + let points = mentionable.points_vec(); + TypelessMentionable { + t_serialize: Box::new(move |serializer| mentionable.serialize(serializer)), + t_factory: factory, + t_topology: topology, + t_points: points, + } + } +} + +impl<'a, Ctx: 'a + Context> TypelessFactory<'a, Ctx> { + pub fn from_typed>(factory: F) -> Self { + let tail_factory = factory.clone(); + TypelessFactory { + t_deserialize: Rc::new(move |deserializer, resolver, addresses| { + match factory.deserialize(deserializer, resolver, addresses) { + Ok(mentionable) => Ok(TypelessMentionable::from_typed(Rc::new(mentionable))), + Err(error) => Err(Box::new(error)), + } + }), + t_unexpected_tail: Rc::new(move |tail| { + TypelessError::from_typed(tail_factory.unexpected_tail(tail)) + }), + } + } +} + +impl<'a> TypelessError<'a> { + pub fn from_typed(error: E) -> Self { + TypelessError(Box::new(error)) + } +} diff --git a/src/std.rs b/src/std.rs index c31ff22..9b2ac52 100644 --- a/src/std.rs +++ b/src/std.rs @@ -4,6 +4,7 @@ pub mod atomic; pub mod cast; pub mod collections; pub mod inlining; +mod local_origin; pub mod nullable; use std::{error::Error, fmt::Display, rc::Rc}; diff --git a/src/std/local_origin.rs b/src/std/local_origin.rs new file mode 100644 index 0000000..5063184 --- /dev/null +++ b/src/std/local_origin.rs @@ -0,0 +1,53 @@ +use std::rc::Rc; + +use crate::core::*; +use crate::func::*; + +impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> { + fn prepare_bytes_for_hashing(mentioned: &A) -> Vec { + let mut vec = mentioned.topology().to_vec(); + mentioned.serialize(&mut vec); + vec + } + + fn from_fields(point: Hash, origin: Rc>) -> Self { + Point { point, origin } + } + + fn from_values>(point: Hash, origin: O) -> Self { + Self::from_fields(point, Rc::new(origin)) + } + + fn from_mentionable(mentionable: A) -> Self { + Self::from_values( + Ctx::hash(Self::prepare_bytes_for_hashing(&mentionable).as_slice()), + LocalOrigin::from(mentionable), + ) + } +} + +struct LocalOrigin(Rc); + +impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for LocalOrigin { + type Mtbl = A; + + fn factory(&self) -> A::Fctr { + self.0.factory() + } + + fn resolve(self: Rc) -> Resolution<'a, Ctx, Self::Mtbl> { + Ctx::T::pure(Ok(self.0.clone())) + } +} + +impl From for LocalOrigin { + fn from(value: A) -> Self { + LocalOrigin(value.into()) + } +} + +impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> From for Point<'a, Ctx, A> { + fn from(value: A) -> Self { + Self::from_mentionable(value) + } +}