use crate::atomic::*; pub mod context; use std::{error::Error, fmt::Display}; use crate::{ flow::binary::*, mode::*, rcore::*, rstd::{atomic::au64::*, nullable::*, point::*}, }; #[derive(Debug)] pub enum TreeParseError { HeightParse(IntParseError), Point(PointParseError), Key(E), HeightValue(HeightError), } impl From for TreeParseError { fn from(value: IntParseError) -> Self { Self::HeightParse(value) } } impl From for TreeParseError { fn from(value: PointParseError) -> Self { Self::Point(value) } } impl From for TreeParseError { fn from(value: HeightError) -> Self { Self::HeightValue(value) } } impl Display for TreeParseError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::HeightParse(height_error) => { write!(f, "failed to parse tree height: {height_error}") } Self::Point(point_error) => { write!(f, "failed to parse node reference: {point_error}") } Self::Key(key_error) => { write!(f, "failed to parse node key: {key_error}") } Self::HeightValue(height_error) => { write!(f, "invalid height: {height_error}") } } } } impl Error for TreeParseError {} pub struct Node<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>> { l: Tree<'a, Ctx, A>, r: Tree<'a, Ctx, A>, key: A, } pub struct Tree<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>> { node: Nullable<'a, Ctx, Node<'a, Ctx, A>>, height: u64, } impl<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>> Tree<'a, Ctx, A> { fn validate_height(&self) -> Result<(), HeightError> { match (&self.node, self.height) { (Nullable::NotNull(_), 0) => Err(HeightError::NodeHeight), (_, 0) => Ok(()), (Nullable::Null(_), height) => Err(HeightError::LeafHeight(height)), _ => Ok(()), } } } #[derive(Clone)] pub struct NodeFactory(F); #[derive(Clone)] pub struct TreeFactory(NullableFactory>); impl<'a, Ctx: Context<'a>, A: MentionableBase<'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: MentionableBase<'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: MentionableBase<'a, Ctx>> MentionableBase<'a, Ctx> for Node<'a, Ctx, A> { type Fctr = NodeFactory; fn factory(&self) -> Self::Fctr { NodeFactory(self.key.factory()) } } impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> MentionableTop<'a, Ctx> for Node<'a, Ctx, A> { fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>) { self.l.points_typed(points); self.r.points_typed(points); self.key.points_typed(points); } } impl<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx>> MentionableBase<'a, Ctx> for Tree<'a, Ctx, A> { type Fctr = TreeFactory; fn factory(&self) -> Self::Fctr { TreeFactory(self.node.factory()) } } impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> MentionableTop<'a, Ctx> for Tree<'a, Ctx, A> { fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>) { self.node.points_typed(points); } } impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx>> FactoryBase<'a, Ctx> for NodeFactory { type Mtbl = Node<'a, Ctx, F::Mtbl>; type ParseError = TreeParseError; } impl ParseMode for NodeFactory { type Mode = F::Mode; } impl<'a, Ctx: Context<'a>, F: FactoryModeParse<'a, Ctx>> FactoryModeParse<'a, Ctx> for NodeFactory { fn mdeserialize>(&self, inctx: I) -> ModeResultM<'a, Ctx, Self, I> { let tree_factory = TreeFactory(NullableFactory::new(self.clone())); let (l, inctx) = tree_factory.ideserialize(inctx)?; let (r, inctx) = tree_factory.ideserialize(inctx)?; let skey = self.0.mdeserialize(inctx).map_err(TreeParseError::Key)?; Ok(Self::map(skey, |key| Node { l, r, key })) } fn mextend( &self, mentionable: ExtensionSourceM<'a, Ctx, Self>, tail: &[u8], ) -> ExtensionResultM<'a, Ctx, Self> { Self::xsbind( mentionable, |Node { l, r, key }| ((l, r), key), |key| Self::xmap_err(self.0.mextend(key, tail), TreeParseError::Key), |(l, r), key| Ok(Node { l, r, key }), ) } } impl<'a, Ctx: Context<'a>, F: FactoryBase<'a, Ctx>> FactoryBase<'a, Ctx> for TreeFactory { type Mtbl = Tree<'a, Ctx, F::Mtbl>; type ParseError = TreeParseError; } impl ImplMode for TreeFactory { type Mode = InliningMode; } impl<'a, Ctx: Context<'a>, F: FactoryParse<'a, Ctx>> CInliningFactory<'a, Ctx> for TreeFactory { fn cextension_error(&self, tail: &[u8]) -> Self::ParseError { u64::a_extension_error(tail).into() } fn cideserialize>(&self, inctx: I) -> IParseResult<'a, Ctx, Self, I> { let (node, inctx) = self.0.ideserialize(inctx)?; let (height, inctx) = u64::a_ideserialize(inctx)?; let tree = Tree { node, height }; tree.validate_height()?; Ok((tree, inctx)) } } impl<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx> + Clone> Clone for Node<'a, Ctx, A> { fn clone(&self) -> Self { Self { l: self.l.clone(), r: self.r.clone(), key: self.key.clone(), } } } impl<'a, Ctx: Context<'a>, A: MentionableBase<'a, Ctx> + Clone> Clone for Tree<'a, Ctx, A> { fn clone(&self) -> Self { Self { node: self.node.clone(), height: self.height, } } }