diff --git a/src/rstd/collections/tree.rs b/src/rstd/collections/tree.rs index 3a56acd..9a2943e 100644 --- a/src/rstd/collections/tree.rs +++ b/src/rstd/collections/tree.rs @@ -1,6 +1,13 @@ -use std::{error::Error, fmt::Display}; +use std::{error::Error, fmt::Display, rc::Rc}; -use crate::rstd::{atomic::au64::*, point::*}; +use crate::{ + rcore::*, + rstd::{ + atomic::{au64::*, *}, + nullable::*, + point::*, + }, +}; #[derive(Debug)] pub enum TreeParseError<E> { @@ -38,3 +45,121 @@ impl<E: Display> Display for TreeParseError<E> { } impl<E: Error> Error for TreeParseError<E> {} + +pub struct Node<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> { + l: Tree<'a, Ctx, A>, + r: Tree<'a, Ctx, A>, + key: A, +} + +pub struct Tree<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> { + node: Nullable<'a, Ctx, Node<'a, Ctx, A>>, + height: u64, +} + +#[derive(Clone)] +pub struct NodeFactory<F>(F); + +#[derive(Clone)] +pub struct TreeFactory<F>(NullableFactory<NodeFactory<F>>); + +impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Serializable for Node<'a, Ctx, A> { + fn serialize(&self, serializer: &mut dyn Serializer) { + self.l.serialize(serializer); + self.r.serialize(serializer); + self.key.serialize(serializer); + } +} + +impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Serializable for Tree<'a, Ctx, A> { + fn serialize(&self, serializer: &mut dyn Serializer) { + self.height.serialize(serializer); + self.node.serialize(serializer); + } +} + +impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Node<'a, Ctx, A> { + type Fctr = NodeFactory<A::Fctr>; + + fn factory(&self) -> Self::Fctr { + NodeFactory(self.key.factory()) + } + + fn points_typed(&self, points: &mut impl TakesPoints<'a, Ctx>) { + self.l.points_typed(points); + self.r.points_typed(points); + self.key.points_typed(points); + } +} + +impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Tree<'a, Ctx, A> { + type Fctr = TreeFactory<A::Fctr>; + + fn factory(&self) -> Self::Fctr { + TreeFactory(self.node.factory()) + } + + fn points_typed(&self, points: &mut impl TakesPoints<'a, Ctx>) { + self.node.points_typed(points); + } +} + +impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> Factory<'a, Ctx> for NodeFactory<F> { + type Mtbl = Node<'a, Ctx, F::Mtbl>; + + type ParseError = TreeParseError<F::ParseError>; + + fn deserialize( + &self, + deserializer: &mut dyn Deserializer, + resolver: Rc<dyn Resolver<'a, Ctx>>, + addresses: &mut Addresses, + ) -> ParseResult<'a, Ctx, Self> { + let tree_factory = TreeFactory(NullableFactory::new(self.clone())); + let l = tree_factory.deserialize(deserializer, resolver.clone(), addresses)?; + let r = tree_factory.deserialize(deserializer, resolver.clone(), addresses)?; + let key = self + .0 + .deserialize(deserializer, resolver.clone(), addresses) + .map_err(TreeParseError::Key)?; + Ok(Node { l, r, key }) + } + + fn extend( + &self, + mut mentionable: Self::Mtbl, + tail: &[u8], + ) -> Result<Self::Mtbl, Self::ParseError> { + mentionable.key = self + .0 + .extend(mentionable.key, tail) + .map_err(TreeParseError::Key)?; + Ok(mentionable) + } +} + +impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> Factory<'a, Ctx> for TreeFactory<F> { + type Mtbl = Tree<'a, Ctx, F::Mtbl>; + + type ParseError = TreeParseError<F::ParseError>; + + fn deserialize( + &self, + deserializer: &mut dyn Deserializer, + resolver: Rc<dyn Resolver<'a, Ctx>>, + addresses: &mut Addresses, + ) -> ParseResult<'a, Ctx, Self> { + let node = self.0.deserialize(deserializer, resolver, addresses)?; + let height = u64::a_deserialize(deserializer)?; + Ok(Tree { node, height }) + } + + fn extend( + &self, + mut mentionable: Self::Mtbl, + tail: &[u8], + ) -> Result<Self::Mtbl, Self::ParseError> { + mentionable.height = u64::a_extend(mentionable.height, tail)?; + Ok(mentionable) + } +}