AtomicObject + StaticPair
This commit is contained in:
parent
4f7df3ddb5
commit
c08e769b82
@ -1,6 +1,7 @@
|
||||
//! This module allows to describe a primitive subset of [Mentionable] types, [Atomic]s,
|
||||
//! simple static types, which are completely [Context]-independent.
|
||||
|
||||
pub mod atomic_object;
|
||||
pub mod plain;
|
||||
|
||||
use std::marker::PhantomData;
|
||||
@ -19,55 +20,6 @@ pub trait Atomic: 'static + Sized + Clone + Serializable {
|
||||
fn unexpected_tail(tail: &[u8]) -> Self::ParseError;
|
||||
}
|
||||
|
||||
/// Generic implementation of a factory for [Atomic]s.
|
||||
pub struct AtomicFactory<A: Atomic>(PhantomData<A>);
|
||||
|
||||
impl<A: Atomic> AtomicFactory<A> {
|
||||
fn new() -> Self {
|
||||
AtomicFactory(PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Atomic> Clone for AtomicFactory<A> {
|
||||
fn clone(&self) -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Ctx: 'a + Context, A: Atomic> Mentionable<'a, Ctx> for A {
|
||||
type Fctr = AtomicFactory<A>;
|
||||
|
||||
fn factory(&self) -> Self::Fctr {
|
||||
AtomicFactory::new()
|
||||
}
|
||||
|
||||
fn topology(&self) -> Hash {
|
||||
Ctx::hash(b"")
|
||||
}
|
||||
|
||||
fn points(&self) -> Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Ctx: 'a + Context, A: Atomic> Factory<'a, Ctx> for AtomicFactory<A> {
|
||||
type Mtbl = A;
|
||||
|
||||
type ParseError = A::ParseError;
|
||||
|
||||
fn deserialize(
|
||||
&self,
|
||||
deserializer: &mut dyn Deserializer,
|
||||
_resolver: Rc<dyn Resolver<'a, Ctx>>,
|
||||
) -> ParseResult<'a, Ctx, Self> {
|
||||
A::deserialize(deserializer)
|
||||
}
|
||||
|
||||
fn unexpected_tail(&self, tail: &[u8]) -> Self::ParseError {
|
||||
A::unexpected_tail(tail)
|
||||
}
|
||||
}
|
||||
|
||||
fn _parse_slice<A: Atomic>(slice: &[u8]) -> Result<A, A::ParseError> {
|
||||
let mut deserializer = SliceDeserializer::from(slice);
|
||||
let mentionable = A::deserialize(&mut deserializer)?;
|
||||
@ -81,17 +33,11 @@ fn _parse_slice<A: Atomic>(slice: &[u8]) -> Result<A, A::ParseError> {
|
||||
|
||||
/// Extension trait to provide method-like utilities associated with [Atomic]s.
|
||||
pub trait ExtAtomic: Atomic {
|
||||
/// Short-hand for getting specific [`AtomicFactory`].
|
||||
fn f() -> AtomicFactory<Self>;
|
||||
/// Static equivalent of [`ExtFactory::parse_slice`].
|
||||
fn parse_slice(slice: &[u8]) -> Result<Self, Self::ParseError>;
|
||||
}
|
||||
|
||||
impl<A: Atomic> ExtAtomic for A {
|
||||
fn f() -> AtomicFactory<Self> {
|
||||
AtomicFactory::new()
|
||||
}
|
||||
|
||||
fn parse_slice(slice: &[u8]) -> Result<Self, Self::ParseError> {
|
||||
_parse_slice(slice)
|
||||
}
|
||||
|
100
src/std/atomic/atomic_object.rs
Normal file
100
src/std/atomic/atomic_object.rs
Normal file
@ -0,0 +1,100 @@
|
||||
use std::ops::Deref;
|
||||
|
||||
use super::*;
|
||||
|
||||
pub struct AtomicObject<A: Atomic> {
|
||||
atomic: A,
|
||||
}
|
||||
|
||||
impl<A: Atomic> From<A> for AtomicObject<A> {
|
||||
fn from(value: A) -> Self {
|
||||
Self { atomic: value }
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Atomic> AsRef<A> for AtomicObject<A> {
|
||||
fn as_ref(&self) -> &A {
|
||||
&self.atomic
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Atomic> Deref for AtomicObject<A> {
|
||||
type Target = A;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.atomic
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Atomic> Serializable for AtomicObject<A> {
|
||||
fn serialize(&self, serializer: &mut dyn Serializer) {
|
||||
self.atomic.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Ctx: 'a + Context, A: Atomic> Mentionable<'a, Ctx> for AtomicObject<A> {
|
||||
type Fctr = AtomicFactory<A>;
|
||||
|
||||
fn factory(&self) -> Self::Fctr {
|
||||
AtomicFactory::new()
|
||||
}
|
||||
|
||||
fn topology(&self) -> Hash {
|
||||
Ctx::hash(b"")
|
||||
}
|
||||
|
||||
fn points(&self) -> Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
/// Generic implementation of a factory for [Atomic]s.
|
||||
pub struct AtomicFactory<A: Atomic>(PhantomData<A>);
|
||||
|
||||
impl<A: Atomic> AtomicFactory<A> {
|
||||
fn new() -> Self {
|
||||
AtomicFactory(PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Atomic> Clone for AtomicFactory<A> {
|
||||
fn clone(&self) -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Ctx: 'a + Context, A: Atomic> Factory<'a, Ctx> for AtomicFactory<A> {
|
||||
type Mtbl = AtomicObject<A>;
|
||||
|
||||
type ParseError = A::ParseError;
|
||||
|
||||
fn deserialize(
|
||||
&self,
|
||||
deserializer: &mut dyn Deserializer,
|
||||
_resolver: Rc<dyn Resolver<'a, Ctx>>,
|
||||
) -> ParseResult<'a, Ctx, Self> {
|
||||
Ok(A::deserialize(deserializer)?.into())
|
||||
}
|
||||
|
||||
fn unexpected_tail(&self, tail: &[u8]) -> Self::ParseError {
|
||||
A::unexpected_tail(tail)
|
||||
}
|
||||
}
|
||||
|
||||
/// Extension trait to provide method-like utilities associated with [AtomicObject]s.
|
||||
pub trait ExtAtomicObject: Atomic {
|
||||
/// Short-hand for getting specific [`AtomicFactory`].
|
||||
fn f() -> AtomicFactory<Self>;
|
||||
/// Short-hand for getting specific [`AtomicObject`].
|
||||
fn m(self) -> AtomicObject<Self>;
|
||||
}
|
||||
|
||||
impl<A: Atomic> ExtAtomicObject for A {
|
||||
fn f() -> AtomicFactory<Self> {
|
||||
AtomicFactory::new()
|
||||
}
|
||||
fn m(self) -> AtomicObject<Self> {
|
||||
self.into()
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
//! Standard generic collections.
|
||||
|
||||
pub mod pair;
|
||||
pub mod stack;
|
||||
|
93
src/std/collections/pair.rs
Normal file
93
src/std/collections/pair.rs
Normal file
@ -0,0 +1,93 @@
|
||||
use std::error::Error;
|
||||
use std::fmt::Display;
|
||||
|
||||
use crate::core::*;
|
||||
use crate::std::inlining::static_pair::*;
|
||||
use crate::std::inlining::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Pair<A, B> {
|
||||
pub a: A,
|
||||
pub b: B,
|
||||
}
|
||||
|
||||
impl<A: Serializable, B: Serializable> StaticPairSerializable for Pair<A, B> {
|
||||
type SA = A;
|
||||
type SB = B;
|
||||
|
||||
fn s_elements(&self) -> (&Self::SA, &Self::SB) {
|
||||
(&self.a, &self.b)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PairParseError<ErrorA: Error, ErrorB: Error> {
|
||||
A(ErrorA),
|
||||
B(ErrorB),
|
||||
}
|
||||
|
||||
impl<ErrorA: Error, ErrorB: Error> Display for PairParseError<ErrorA, ErrorB> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
PairParseError::A(error) => f.write_fmt(format_args!(
|
||||
"error while parsing first element of a pair: {}",
|
||||
error
|
||||
)),
|
||||
PairParseError::B(error) => f.write_fmt(format_args!(
|
||||
"error while parsing first element of a pair: {}",
|
||||
error
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<ErrorA: Error, ErrorB: Error> Error for PairParseError<ErrorA, ErrorB> {}
|
||||
|
||||
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>, B: Mentionable<'a, Ctx>> StaticPair<'a, Ctx>
|
||||
for Pair<A, B>
|
||||
where
|
||||
A::Fctr: InlineableFactory,
|
||||
{
|
||||
type FactoryData = Pair<Self::FA, Self::FB>;
|
||||
type A = A;
|
||||
type B = B;
|
||||
type FA = A::Fctr;
|
||||
type FB = B::Fctr;
|
||||
type ParseError = PairParseError<
|
||||
<A::Fctr as Factory<'a, Ctx>>::ParseError,
|
||||
<B::Fctr as Factory<'a, Ctx>>::ParseError,
|
||||
>;
|
||||
|
||||
fn factories(factory_data: &Self::FactoryData) -> (&Self::FA, &Self::FB) {
|
||||
(&factory_data.a, &factory_data.b)
|
||||
}
|
||||
|
||||
fn from_parsed(_factory_data: &Self::FactoryData, a: Self::A, b: Self::B) -> Self {
|
||||
Pair { a, b }
|
||||
}
|
||||
|
||||
fn from_error_a(
|
||||
_factory_data: &Self::FactoryData,
|
||||
error: <Self::FA as Factory<'a, Ctx>>::ParseError,
|
||||
) -> Self::ParseError {
|
||||
PairParseError::A(error)
|
||||
}
|
||||
|
||||
fn from_error_b(
|
||||
_factory_data: &Self::FactoryData,
|
||||
error: <Self::FB as Factory<'a, Ctx>>::ParseError,
|
||||
) -> Self::ParseError {
|
||||
PairParseError::B(error)
|
||||
}
|
||||
|
||||
fn factory_data(&self) -> Self::FactoryData {
|
||||
Pair {
|
||||
a: self.a.factory(),
|
||||
b: self.b.factory(),
|
||||
}
|
||||
}
|
||||
|
||||
fn elements(&self) -> (&Self::A, &Self::B) {
|
||||
(&self.a, &self.b)
|
||||
}
|
||||
}
|
@ -175,27 +175,29 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> ExtStack<'a, Ctx, A> for St
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::std::atomic::atomic_object::*;
|
||||
use crate::std::atomic::plain::*;
|
||||
use crate::std::atomic::*;
|
||||
use crate::testing::*;
|
||||
|
||||
type T = Stack<'static, TestContext, Plain>;
|
||||
type T = Stack<'static, TestContext, AtomicObject<Plain>>;
|
||||
|
||||
fn unstack(stack: &T) -> Result<Vec<Vec<u8>>, StackFaiure<'static, TestContext, Plain>> {
|
||||
fn unstack(
|
||||
stack: &T,
|
||||
) -> Result<Vec<Vec<u8>>, StackFaiure<'static, TestContext, AtomicObject<Plain>>> {
|
||||
Ok(stack
|
||||
.clone()
|
||||
.vec()?
|
||||
.iter()
|
||||
.map(|plain| plain.bytes())
|
||||
.map(|plain| plain.raw())
|
||||
.collect())
|
||||
}
|
||||
|
||||
fn make_stack() -> T {
|
||||
let stack: T = Stack::empty(Plain::f());
|
||||
|
||||
let stack: T = stack.add(Plain::from_slice(b"A0"));
|
||||
let stack: T = stack.add(Plain::from_slice(b"B1"));
|
||||
let stack: T = stack.add(Plain::from_slice(b"C2"));
|
||||
let stack: T = stack.add(Plain::from_slice(b"A0").into());
|
||||
let stack: T = stack.add(Plain::from_slice(b"B1").into());
|
||||
let stack: T = stack.add(Plain::from_slice(b"C2").into());
|
||||
|
||||
stack
|
||||
}
|
||||
@ -207,7 +209,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stack() -> Result<(), StackFaiure<'static, TestContext, Plain>> {
|
||||
fn test_stack() -> Result<(), StackFaiure<'static, TestContext, AtomicObject<Plain>>> {
|
||||
let stack: T = make_stack();
|
||||
|
||||
validate_stack(&stack);
|
||||
@ -244,5 +246,5 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> ConstSizeFactory
|
||||
where
|
||||
A::Fctr: ConstSizeFactory,
|
||||
{
|
||||
const SIZE: usize = { Stack::<'a, Ctx, A>::SIZE + A::Fctr::SIZE };
|
||||
const SIZE: usize = Stack::<'a, Ctx, A>::SIZE + A::Fctr::SIZE;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
pub mod staticpair;
|
||||
pub mod static_pair;
|
||||
|
||||
use super::atomic::*;
|
||||
use super::atomic::atomic_object::*;
|
||||
use crate::core::*;
|
||||
use crate::std::*;
|
||||
|
||||
|
134
src/std/inlining/static_pair.rs
Normal file
134
src/std/inlining/static_pair.rs
Normal file
@ -0,0 +1,134 @@
|
||||
use super::*;
|
||||
use crate::core::*;
|
||||
|
||||
pub trait StaticPairSerializable {
|
||||
type SA: Serializable;
|
||||
type SB: Serializable;
|
||||
|
||||
fn s_elements(&self) -> (&Self::SA, &Self::SB);
|
||||
}
|
||||
|
||||
pub trait StaticPair<'a, Ctx: 'a + Context>:
|
||||
'a + StaticPairSerializable<SA = Self::A, SB = Self::B>
|
||||
{
|
||||
type FactoryData: 'a + Clone;
|
||||
type A: Mentionable<'a, Ctx, Fctr = Self::FA>;
|
||||
type B: Mentionable<'a, Ctx, Fctr = Self::FB>;
|
||||
type FA: Factory<'a, Ctx, Mtbl = Self::A> + InlineableFactory;
|
||||
type FB: Factory<'a, Ctx, Mtbl = Self::B>;
|
||||
type ParseError: 'a + Error;
|
||||
|
||||
fn factories(factory_data: &Self::FactoryData) -> (&Self::FA, &Self::FB);
|
||||
fn from_parsed(factory_data: &Self::FactoryData, a: Self::A, b: Self::B) -> Self;
|
||||
fn from_error_a(
|
||||
factory_data: &Self::FactoryData,
|
||||
error: <Self::FA as Factory<'a, Ctx>>::ParseError,
|
||||
) -> Self::ParseError;
|
||||
fn from_error_b(
|
||||
factory_data: &Self::FactoryData,
|
||||
error: <Self::FB as Factory<'a, Ctx>>::ParseError,
|
||||
) -> Self::ParseError;
|
||||
fn factory_data(&self) -> Self::FactoryData;
|
||||
fn elements(&self) -> (&Self::A, &Self::B);
|
||||
}
|
||||
|
||||
pub struct StaticPairObject<SP> {
|
||||
pair: SP,
|
||||
}
|
||||
|
||||
pub struct StaticPairFactory<'a, Ctx: 'a + Context, SP: StaticPair<'a, Ctx>> {
|
||||
factory_data: SP::FactoryData,
|
||||
}
|
||||
|
||||
impl<SP: StaticPairSerializable> Serializable for StaticPairObject<SP> {
|
||||
fn serialize(&self, serializer: &mut dyn Serializer) {
|
||||
let (a, b) = self.pair.s_elements();
|
||||
a.serialize(serializer);
|
||||
b.serialize(serializer);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Ctx: 'a + Context, SP: StaticPair<'a, Ctx>> Mentionable<'a, Ctx> for StaticPairObject<SP> {
|
||||
type Fctr = StaticPairFactory<'a, Ctx, SP>;
|
||||
|
||||
fn factory(&self) -> Self::Fctr {
|
||||
StaticPairFactory {
|
||||
factory_data: self.pair.factory_data(),
|
||||
}
|
||||
}
|
||||
|
||||
fn points(&self) -> Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>> {
|
||||
let (a, b) = self.pair.elements();
|
||||
let mut vec = a.points();
|
||||
vec.extend(b.points());
|
||||
vec
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Ctx: 'a + Context, SP: StaticPair<'a, Ctx>> Clone for StaticPairFactory<'a, Ctx, SP> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
factory_data: self.factory_data.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Ctx: 'a + Context, SP: StaticPair<'a, Ctx>> Factory<'a, Ctx>
|
||||
for StaticPairFactory<'a, Ctx, SP>
|
||||
{
|
||||
type Mtbl = StaticPairObject<SP>;
|
||||
|
||||
type ParseError = SP::ParseError;
|
||||
|
||||
fn deserialize(
|
||||
&self,
|
||||
deserializer: &mut dyn Deserializer,
|
||||
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
||||
) -> ParseResult<'a, Ctx, Self> {
|
||||
let (fa, fb) = SP::factories(&self.factory_data);
|
||||
let a: SP::A = match fa.deserialize(deserializer, resolver.clone()) {
|
||||
Ok(a) => a,
|
||||
Err(error) => return Err(SP::from_error_a(&self.factory_data, error)),
|
||||
};
|
||||
let b: SP::B = match fb.deserialize(deserializer, resolver) {
|
||||
Ok(b) => b,
|
||||
Err(error) => return Err(SP::from_error_b(&self.factory_data, error)),
|
||||
};
|
||||
Ok(StaticPairObject {
|
||||
pair: SP::from_parsed(&self.factory_data, a, b),
|
||||
})
|
||||
}
|
||||
|
||||
fn unexpected_tail(&self, tail: &[u8]) -> Self::ParseError {
|
||||
let (_, fb) = SP::factories(&self.factory_data);
|
||||
SP::from_error_b(&self.factory_data, fb.unexpected_tail(tail))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Ctx: 'a + Context, SP: StaticPair<'a, Ctx>> InlineableFactory
|
||||
for StaticPairFactory<'a, Ctx, SP>
|
||||
where
|
||||
SP::FB: InlineableFactory,
|
||||
{
|
||||
}
|
||||
|
||||
impl<'a, Ctx: 'a + Context, SP: StaticPair<'a, Ctx>> FixedSizeFactory
|
||||
for StaticPairFactory<'a, Ctx, SP>
|
||||
where
|
||||
SP::FA: FixedSizeFactory,
|
||||
SP::FB: FixedSizeFactory,
|
||||
{
|
||||
fn size(&self) -> usize {
|
||||
let (fa, fb) = SP::factories(&self.factory_data);
|
||||
fa.size() + fb.size()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Ctx: 'a + Context, SP: StaticPair<'a, Ctx>> ConstSizeFactory
|
||||
for StaticPairFactory<'a, Ctx, SP>
|
||||
where
|
||||
SP::FA: ConstSizeFactory,
|
||||
SP::FB: ConstSizeFactory,
|
||||
{
|
||||
const SIZE: usize = SP::FA::SIZE + SP::FB::SIZE;
|
||||
}
|
@ -1 +0,0 @@
|
||||
|
Loading…
Reference in New Issue
Block a user