105 lines
2.7 KiB
Rust
105 lines
2.7 KiB
Rust
use std::{error::Error, rc::Rc};
|
|
|
|
use crate::func::*;
|
|
|
|
pub trait Context {
|
|
type T: Monad;
|
|
|
|
fn hash(s: &[u8]) -> Hash;
|
|
}
|
|
|
|
type Hash = [u8; 32];
|
|
|
|
pub trait Serializer {
|
|
fn write(&mut self, buf: &[u8]);
|
|
}
|
|
|
|
impl<F: FnMut(&[u8])> Serializer for F {
|
|
fn write(&mut self, buf: &[u8]) {
|
|
self(buf);
|
|
}
|
|
}
|
|
|
|
pub trait Mentionable<Ctx: Context> {
|
|
type Fctr: Factory<Ctx, Mtbl = Self>;
|
|
|
|
fn serialize<F: Serializer>(&self, serializer: F);
|
|
fn factory(&self) -> Self::Fctr;
|
|
fn topology(&self) -> Hash;
|
|
}
|
|
|
|
pub trait Deserializer {
|
|
fn read_n_const<const N: usize>(&mut self) -> Result<[u8; N], &[u8]>;
|
|
fn read_n(&mut self, n: usize) -> &[u8];
|
|
fn read_all(&mut self, n: usize) -> &[u8];
|
|
}
|
|
|
|
pub trait Factory<Ctx: Context>: Clone {
|
|
type Mtbl: Mentionable<Ctx, Fctr = Self>;
|
|
type ParseError: Error;
|
|
|
|
fn deserialize<F: Deserializer>(&self, deserializer: F)
|
|
-> Result<Self::Mtbl, Self::ParseError>;
|
|
}
|
|
|
|
pub trait Origin<'a, Ctx: Context>: 'a {
|
|
type Mtbl: Mentionable<Ctx>;
|
|
fn factory(&self) -> <Self::Mtbl as Mentionable<Ctx>>::Fctr;
|
|
fn resolve(&self) -> <<Ctx as Context>::T as WeakFunctor>::F<'a, Rc<Self::Mtbl>>;
|
|
}
|
|
|
|
struct LocalOrigin<A>(Rc<A>);
|
|
|
|
impl<'a, Ctx: 'a + Context, A: 'a + Mentionable<Ctx>> Origin<'a, Ctx> for LocalOrigin<A> {
|
|
type Mtbl = A;
|
|
|
|
fn factory(&self) -> <Self::Mtbl as Mentionable<Ctx>>::Fctr {
|
|
self.0.factory()
|
|
}
|
|
|
|
fn resolve(&self) -> <<Ctx as Context>::T as WeakFunctor>::F<'a, Rc<Self::Mtbl>> {
|
|
<Ctx::T as Applicative>::pure(self.0.clone())
|
|
}
|
|
}
|
|
|
|
impl<A> From<A> for LocalOrigin<A> {
|
|
fn from(value: A) -> Self {
|
|
LocalOrigin(value.into())
|
|
}
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct Point<'a, Ctx: Context, A: Mentionable<Ctx>> {
|
|
pub point: Hash,
|
|
pub origin: Rc<dyn Origin<'a, Ctx, Mtbl = A>>,
|
|
}
|
|
|
|
impl<'a, Ctx: 'a + Context, A: 'a + Mentionable<Ctx>> Point<'a, Ctx, A> {
|
|
fn prepare_bytes_for_hashing(mentioned: &A) -> Vec<u8> {
|
|
let mut vec = mentioned.topology().to_vec();
|
|
mentioned.serialize(|x: &[u8]| vec.extend(x.iter()));
|
|
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))
|
|
}
|
|
|
|
pub fn resolve(&self) -> <<Ctx as Context>::T as WeakFunctor>::F<'a, Rc<A>> {
|
|
self.origin.resolve()
|
|
}
|
|
}
|
|
|
|
impl<'a, Ctx: 'a + Context, A: 'a + Mentionable<Ctx>> From<A> for Point<'a, Ctx, A> {
|
|
fn from(value: A) -> Self {
|
|
Self::from_values(
|
|
Ctx::hash(Self::prepare_bytes_for_hashing(&value).as_slice()),
|
|
LocalOrigin::from(value),
|
|
)
|
|
}
|
|
}
|