export typeless and point

This commit is contained in:
AF 2023-04-23 00:25:57 +00:00
parent 9e578b6610
commit 25c15837d9
10 changed files with 195 additions and 180 deletions

View File

@ -2,7 +2,7 @@
//! Brings [`Mentionable`]/[`Factory`]/[`Origin`] concepts from the original implementation in Python. //! Brings [`Mentionable`]/[`Factory`]/[`Origin`] concepts from the original implementation in Python.
//! Allows for more generic behaviour via [`Context`], as opposed to original async-only. //! Allows for more generic behaviour via [`Context`], as opposed to original async-only.
pub mod typeless; mod typeless;
pub use typeless::*; pub use typeless::*;

View File

@ -1,5 +1,3 @@
//! Typeless. See [`Mentionable::points`].
use super::*; use super::*;
type TypelessSerialize<'a> = dyn 'a + Fn(&mut dyn Serializer); type TypelessSerialize<'a> = dyn 'a + Fn(&mut dyn Serializer);

View File

@ -6,188 +6,14 @@ pub mod collections;
pub mod inlining; pub mod inlining;
mod local_origin; mod local_origin;
pub mod nullable; pub mod nullable;
pub mod point;
mod typeless;
use std::{error::Error, fmt::Display, rc::Rc}; use std::{error::Error, fmt::Display, rc::Rc};
use crate::core::*; use crate::core::*;
use crate::func::*; use crate::func::*;
struct WrappedOrigin<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> {
w_factory: A::Fctr,
w_resolve: Box<dyn 'a + Fn() -> Resolution<'a, Ctx, A>>,
}
fn wrapped_origin<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>>(
factory: A::Fctr,
resolve: impl 'a + Fn() -> Resolution<'a, Ctx, A>,
) -> Rc<dyn Origin<'a, Ctx, Mtbl = A>> {
Rc::new(WrappedOrigin {
w_factory: factory,
w_resolve: Box::new(resolve),
})
}
trait MappableOrigin<'a, Ctx: 'a + Context>: Origin<'a, Ctx> {
fn map<B: Mentionable<'a, Ctx>>(
self: Rc<Self>,
map_ok: impl 'a + Clone + Fn(Rc<Self::Mtbl>) -> B,
map_err: impl 'a
+ Clone
+ Fn(
<<Self::Mtbl as Mentionable<'a, Ctx>>::Fctr as Factory<'a, Ctx>>::ParseError,
) -> <B::Fctr as Factory<'a, Ctx>>::ParseError,
map_factory: impl 'a + FnOnce(<Self::Mtbl as Mentionable<'a, Ctx>>::Fctr) -> B::Fctr,
) -> WrappedOrigin<'a, Ctx, B>;
}
fn map_resolve<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>, B: Mentionable<'a, Ctx>>(
resolve: impl 'a + Fn() -> Resolution<'a, Ctx, A>,
map_ok: impl 'a + Fn(Rc<A>) -> B,
map_err: impl 'a
+ Fn(<A::Fctr as Factory<'a, Ctx>>::ParseError) -> <B::Fctr as Factory<'a, Ctx>>::ParseError,
) -> Resolution<'a, Ctx, B> {
Ctx::T::fmap(
move |resolved| match resolved {
Ok(mentionable) => Ok(Rc::new(map_ok(mentionable))),
Err(ResolutionError::Parse(parse_error)) => {
Err(ResolutionError::Parse(map_err(parse_error)))
}
Err(ResolutionError::Lookup(lookup_error)) => {
Err(ResolutionError::Lookup(lookup_error))
}
},
resolve(),
)
}
impl<'a, Ctx: 'a + Context, O: ?Sized + Origin<'a, Ctx>> MappableOrigin<'a, Ctx> for O {
fn map<B: Mentionable<'a, Ctx>>(
self: Rc<Self>,
map_ok: impl 'a + Clone + Fn(Rc<Self::Mtbl>) -> B,
map_err: impl 'a
+ Clone
+ Fn(
<<Self::Mtbl as Mentionable<'a, Ctx>>::Fctr as Factory<'a, Ctx>>::ParseError,
) -> <B::Fctr as Factory<'a, Ctx>>::ParseError,
map_factory: impl 'a + FnOnce(<Self::Mtbl as Mentionable<'a, Ctx>>::Fctr) -> B::Fctr,
) -> WrappedOrigin<'a, Ctx, B> {
let origin = self.clone();
WrappedOrigin {
w_factory: map_factory(self.factory()),
w_resolve: Box::new(move || {
let origin = origin.clone();
let map_ok = map_ok.clone();
let map_err = map_err.clone();
map_resolve(move || origin.clone().resolve(), map_ok, map_err)
}),
}
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for WrappedOrigin<'a, Ctx, A> {
type Mtbl = A;
fn factory(&self) -> <Self::Mtbl as Mentionable<'a, Ctx>>::Fctr {
self.w_factory.clone()
}
fn resolve(self: Rc<Self>) -> Resolution<'a, Ctx, A> {
(self.w_resolve)()
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> {
/// Typeless version of the point. Useful for [Mentionable::points] implementaion.
pub fn typeless(&self) -> Point<'a, Ctx, TypelessMentionable<'a, Ctx>> {
Point {
point: self.point,
origin: Rc::new(self.origin.clone().map(
TypelessMentionable::from_typed,
TypelessError::from_typed,
TypelessFactory::from_typed,
)),
}
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Serializable for Point<'a, Ctx, A> {
fn serialize(&self, serializer: &mut dyn Serializer) {
serializer.write(&self.point)
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Point<'a, Ctx, A> {
type Fctr = PointFactory<A::Fctr>;
fn factory(&self) -> Self::Fctr {
PointFactory {
factory: self.origin.factory(),
}
}
fn topology(&self) -> Hash {
Ctx::hash(&self.point)
}
fn points(&self, points: &mut Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>) {
points.push(self.typeless());
}
}
#[derive(Clone)]
pub struct PointFactory<F> {
factory: F,
}
#[derive(Debug)]
pub enum PointParseError {
WrongLength(usize),
}
impl Display for PointParseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
PointParseError::WrongLength(length) => f.write_fmt(format_args!(
"expected {} bytes, received {}.",
HASH_SIZE, length
)),
}
}
}
impl Error for PointParseError {}
impl From<&[u8]> for PointParseError {
fn from(value: &[u8]) -> Self {
PointParseError::WrongLength(value.len())
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> AsRef<[u8]> for Point<'a, Ctx, A> {
fn as_ref(&self) -> &[u8] {
&self.point
}
}
impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for PointFactory<F> {
type Mtbl = Point<'a, Ctx, F::Mtbl>;
type ParseError = PointParseError;
fn deserialize(
&self,
deserializer: &mut dyn Deserializer,
resolver: Rc<dyn Resolver<'a, Ctx>>,
addresses: &mut Addresses,
) -> ParseResult<'a, Ctx, Self> {
Ok(addresses.next_point(deserializer, resolver, self.factory.clone())?)
}
fn unexpected_tail(&self, tail: &[u8]) -> Self::ParseError {
PointParseError::WrongLength(HASH_SIZE + tail.len())
}
}
impl Display for Address { impl Display for Address {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("{}@{}", hex::encode(self.point), self.index)) f.write_fmt(format_args!("{}@{}", hex::encode(self.point), self.index))

View File

@ -3,6 +3,7 @@
//! //!
//! p.s. the implementation is horrific. //! p.s. the implementation is horrific.
use super::typeless::*;
use crate::core::*; use crate::core::*;
use crate::std::*; use crate::std::*;

View File

@ -3,6 +3,7 @@
use crate::core::*; use crate::core::*;
use crate::std::inlining::*; use crate::std::inlining::*;
use crate::std::nullable::*; use crate::std::nullable::*;
use crate::std::point::*;
use crate::std::*; use crate::std::*;
/// Node containing a (nullable) reference to the next node and an element. /// Node containing a (nullable) reference to the next node and an element.

View File

@ -4,6 +4,7 @@ pub mod static_pair;
use super::atomic::atomic_object::*; use super::atomic::atomic_object::*;
use super::atomic::*; use super::atomic::*;
use super::point::*;
use crate::core::*; use crate::core::*;
use crate::std::*; use crate::std::*;

View File

@ -20,7 +20,7 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> {
fn from_mentionable(mentionable: A) -> Self { fn from_mentionable(mentionable: A) -> Self {
Self::from_values( Self::from_values(
Ctx::hash(Self::prepare_bytes_for_hashing(&mentionable).as_slice()), Ctx::hash(&Self::prepare_bytes_for_hashing(&mentionable)),
LocalOrigin::from(mentionable), LocalOrigin::from(mentionable),
) )
} }

View File

@ -1,6 +1,7 @@
//! This module introduces [`Option`]-like concepts into RADN typesystem using [`Nullable`]. //! This module introduces [`Option`]-like concepts into RADN typesystem using [`Nullable`].
use super::inlining::*; use super::inlining::*;
use super::point::*;
use crate::core::*; use crate::core::*;
use crate::std::*; use crate::std::*;

85
src/std/point.rs Normal file
View File

@ -0,0 +1,85 @@
//! Module responsible for making [Point]s [Mentionable].
use std::error::Error;
use std::fmt::Display;
use std::rc::Rc;
use crate::core::*;
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Serializable for Point<'a, Ctx, A> {
fn serialize(&self, serializer: &mut dyn Serializer) {
serializer.write(&self.point)
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Point<'a, Ctx, A> {
type Fctr = PointFactory<A::Fctr>;
fn factory(&self) -> Self::Fctr {
PointFactory {
factory: self.origin.factory(),
}
}
fn topology(&self) -> Hash {
Ctx::hash(&self.point)
}
fn points(&self, points: &mut Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>) {
points.push(self.typeless());
}
}
#[derive(Clone)]
pub struct PointFactory<F> {
factory: F,
}
#[derive(Debug)]
pub enum PointParseError {
WrongLength(usize),
}
impl Display for PointParseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
PointParseError::WrongLength(length) => f.write_fmt(format_args!(
"expected {} bytes, received {}.",
HASH_SIZE, length
)),
}
}
}
impl Error for PointParseError {}
impl From<&[u8]> for PointParseError {
fn from(value: &[u8]) -> Self {
PointParseError::WrongLength(value.len())
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> AsRef<[u8]> for Point<'a, Ctx, A> {
fn as_ref(&self) -> &[u8] {
&self.point
}
}
impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for PointFactory<F> {
type Mtbl = Point<'a, Ctx, F::Mtbl>;
type ParseError = PointParseError;
fn deserialize(
&self,
deserializer: &mut dyn Deserializer,
resolver: Rc<dyn Resolver<'a, Ctx>>,
addresses: &mut Addresses,
) -> ParseResult<'a, Ctx, Self> {
Ok(addresses.next_point(deserializer, resolver, self.factory.clone())?)
}
fn unexpected_tail(&self, tail: &[u8]) -> Self::ParseError {
PointParseError::WrongLength(HASH_SIZE + tail.len())
}
}

102
src/std/typeless.rs Normal file
View File

@ -0,0 +1,102 @@
use std::rc::Rc;
use crate::core::*;
use crate::func::*;
struct WrappedOrigin<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> {
w_factory: A::Fctr,
w_resolve: Box<dyn 'a + Fn() -> Resolution<'a, Ctx, A>>,
}
pub fn wrapped_origin<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>>(
factory: A::Fctr,
resolve: impl 'a + Fn() -> Resolution<'a, Ctx, A>,
) -> Rc<dyn Origin<'a, Ctx, Mtbl = A>> {
Rc::new(WrappedOrigin {
w_factory: factory,
w_resolve: Box::new(resolve),
})
}
trait MappableOrigin<'a, Ctx: 'a + Context>: Origin<'a, Ctx> {
fn map<B: Mentionable<'a, Ctx>>(
self: Rc<Self>,
map_ok: impl 'a + Clone + Fn(Rc<Self::Mtbl>) -> B,
map_err: impl 'a
+ Clone
+ Fn(
<<Self::Mtbl as Mentionable<'a, Ctx>>::Fctr as Factory<'a, Ctx>>::ParseError,
) -> <B::Fctr as Factory<'a, Ctx>>::ParseError,
map_factory: impl 'a + FnOnce(<Self::Mtbl as Mentionable<'a, Ctx>>::Fctr) -> B::Fctr,
) -> WrappedOrigin<'a, Ctx, B>;
}
fn map_resolve<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>, B: Mentionable<'a, Ctx>>(
resolve: impl 'a + Fn() -> Resolution<'a, Ctx, A>,
map_ok: impl 'a + Fn(Rc<A>) -> B,
map_err: impl 'a
+ Fn(<A::Fctr as Factory<'a, Ctx>>::ParseError) -> <B::Fctr as Factory<'a, Ctx>>::ParseError,
) -> Resolution<'a, Ctx, B> {
Ctx::T::fmap(
move |resolved| match resolved {
Ok(mentionable) => Ok(Rc::new(map_ok(mentionable))),
Err(ResolutionError::Parse(parse_error)) => {
Err(ResolutionError::Parse(map_err(parse_error)))
}
Err(ResolutionError::Lookup(lookup_error)) => {
Err(ResolutionError::Lookup(lookup_error))
}
},
resolve(),
)
}
impl<'a, Ctx: 'a + Context, O: ?Sized + Origin<'a, Ctx>> MappableOrigin<'a, Ctx> for O {
fn map<B: Mentionable<'a, Ctx>>(
self: Rc<Self>,
map_ok: impl 'a + Clone + Fn(Rc<Self::Mtbl>) -> B,
map_err: impl 'a
+ Clone
+ Fn(
<<Self::Mtbl as Mentionable<'a, Ctx>>::Fctr as Factory<'a, Ctx>>::ParseError,
) -> <B::Fctr as Factory<'a, Ctx>>::ParseError,
map_factory: impl 'a + FnOnce(<Self::Mtbl as Mentionable<'a, Ctx>>::Fctr) -> B::Fctr,
) -> WrappedOrigin<'a, Ctx, B> {
let origin = self.clone();
WrappedOrigin {
w_factory: map_factory(self.factory()),
w_resolve: Box::new(move || {
let origin = origin.clone();
let map_ok = map_ok.clone();
let map_err = map_err.clone();
map_resolve(move || origin.clone().resolve(), map_ok, map_err)
}),
}
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for WrappedOrigin<'a, Ctx, A> {
type Mtbl = A;
fn factory(&self) -> <Self::Mtbl as Mentionable<'a, Ctx>>::Fctr {
self.w_factory.clone()
}
fn resolve(self: Rc<Self>) -> Resolution<'a, Ctx, A> {
(self.w_resolve)()
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> {
/// Typeless version of the point. Useful for [Mentionable::points] implementaion.
pub fn typeless(&self) -> Point<'a, Ctx, TypelessMentionable<'a, Ctx>> {
Point {
point: self.point,
origin: Rc::new(self.origin.clone().map(
TypelessMentionable::from_typed,
TypelessError::from_typed,
TypelessFactory::from_typed,
)),
}
}
}