extract typeless and local_origin

This commit is contained in:
AF 2023-04-23 00:06:30 +00:00
parent 5ae43e60b2
commit 9e578b6610
4 changed files with 200 additions and 186 deletions

View File

@ -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<u8> {
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<Self>) -> Resolution<'a, Ctx, Self::Mtbl>;
}
struct LocalOrigin<A>(Rc<A>);
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for LocalOrigin<A> {
type Mtbl = A;
fn factory(&self) -> A::Fctr {
self.0.factory()
}
fn resolve(self: Rc<Self>) -> Resolution<'a, Ctx, Self::Mtbl> {
Ctx::T::pure(Ok(self.0.clone()))
}
}
impl<A> From<A> for LocalOrigin<A> {
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<u8> {
let mut vec = mentioned.topology().to_vec();
mentioned.serialize(&mut vec);
vec
}
fn from_fields(point: Hash, origin: Rc<dyn Origin<'a, Ctx, Mtbl = A>>) -> Self {
Point { point, origin }
}
fn from_values<O: Origin<'a, Ctx, Mtbl = A>>(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<A> 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<TypelessSerialize<'a>>,
t_factory: TypelessFactory<'a, Ctx>,
t_topology: Hash,
t_points: Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>,
}
type TypelessParsed<'a, Ctx> = Result<TypelessMentionable<'a, Ctx>, Box<dyn 'a + Error>>;
type TypelessDeserialize<'a, Ctx> = dyn 'a
+ Fn(&mut dyn Deserializer, Rc<dyn Resolver<'a, Ctx>>, &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<TypelessDeserialize<'a, Ctx>>,
t_unexpected_tail: Rc<TypelessUnexpectedTail<'a>>,
}
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<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>) {
points.extend(self.t_points.iter().map(Clone::clone));
}
fn points_vec(&self) -> Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>> {
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<dyn 'a + Error>);
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<dyn Resolver<'a, Ctx>>,
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<A: Mentionable<'a, Ctx>>(mentionable: Rc<A>) -> 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<F: Factory<'a, Ctx>>(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<E: 'a + Error>(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<u8> {
fn write(&mut self, buf: &[u8]) {
self.extend(buf);
}
fn tell(&self) -> usize {
self.len()
}
}

132
src/core/typeless.rs Normal file
View File

@ -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<TypelessSerialize<'a>>,
t_factory: TypelessFactory<'a, Ctx>,
t_topology: Hash,
t_points: Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>,
}
type TypelessParsed<'a, Ctx> = Result<TypelessMentionable<'a, Ctx>, Box<dyn 'a + Error>>;
type TypelessDeserialize<'a, Ctx> = dyn 'a
+ Fn(&mut dyn Deserializer, Rc<dyn Resolver<'a, Ctx>>, &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<TypelessDeserialize<'a, Ctx>>,
t_unexpected_tail: Rc<TypelessUnexpectedTail<'a>>,
}
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<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>) {
points.extend(self.t_points.iter().map(Clone::clone));
}
fn points_vec(&self) -> Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>> {
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<dyn 'a + Error>);
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<dyn Resolver<'a, Ctx>>,
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<A: Mentionable<'a, Ctx>>(mentionable: Rc<A>) -> 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<F: Factory<'a, Ctx>>(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<E: 'a + Error>(error: E) -> Self {
TypelessError(Box::new(error))
}
}

View File

@ -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};

53
src/std/local_origin.rs Normal file
View File

@ -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<u8> {
let mut vec = mentioned.topology().to_vec();
mentioned.serialize(&mut vec);
vec
}
fn from_fields(point: Hash, origin: Rc<dyn Origin<'a, Ctx, Mtbl = A>>) -> Self {
Point { point, origin }
}
fn from_values<O: Origin<'a, Ctx, Mtbl = A>>(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<A>(Rc<A>);
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for LocalOrigin<A> {
type Mtbl = A;
fn factory(&self) -> A::Fctr {
self.0.factory()
}
fn resolve(self: Rc<Self>) -> Resolution<'a, Ctx, Self::Mtbl> {
Ctx::T::pure(Ok(self.0.clone()))
}
}
impl<A> From<A> for LocalOrigin<A> {
fn from(value: A) -> Self {
LocalOrigin(value.into())
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> From<A> for Point<'a, Ctx, A> {
fn from(value: A) -> Self {
Self::from_mentionable(value)
}
}