use crate::NodeRefContainer; use crate::base_context::{ BinaryTreeChildrenGetterContext, BinaryTreeChildrenSetterContext, BinaryTreeParentSetterContext, BinaryTreeRootGetter, BinaryTreeRootSetter, }; use crate::directed_context::{ DirectedBinaryTreeChildrenGetterContext, DirectedBinaryTreeChildrenSetterContext, }; use crate::parent2node_clojure::clojure::{ Parent2NodeGetterClojure, Parent2NodeSetterClojure, ParentProviderClojure, }; use crate::relation_context::{BinaryTreeRootRelationSetterContext, Parent2NodeRelationSetterClojure}; include!("../_common_macros.rs"); macro_rules! _struct { ($name:ident) => { pub struct $name { ctx: CtxRef, node: NodeRef, } }; } pub struct FixedRootParent2NodeGetterClojureFromContext { ctx: NodeRef, } _struct!(FixedLeftParent2NodeGetterClojureFromContext); _struct!(FixedRightParent2NodeGetterClojureFromContext); _struct!(FixedForwardParent2NodeGetterClojureFromDirectedContext); _struct!(FixedOppositeParent2NodeGetterClojureFromDirectedContext); macro_rules! _constructor { ($name:ident) => { impl<'ctx, Ctx: NodeRefContainer> $name<&'ctx Ctx, Ctx::NodeRef> { pub fn wrap(ctx: &'ctx Ctx, node: Ctx::NodeRef) -> Self { return Self { ctx, node }; } } }; ($name:ident mut) => { impl<'ctx, Ctx: NodeRefContainer> $name<&'ctx mut Ctx, Ctx::NodeRef> { pub fn wrap_mut(ctx: &'ctx mut Ctx, node: Ctx::NodeRef) -> Self { return Self { ctx, node }; } } }; } impl<'ctx, Ctx: NodeRefContainer + BinaryTreeRootGetter> FixedRootParent2NodeGetterClojureFromContext<&'ctx Ctx> { pub fn wrap(ctx: &'ctx Ctx) -> Self { return Self { ctx }; } } impl<'ctx, Ctx: NodeRefContainer> FixedRootParent2NodeGetterClojureFromContext<&'ctx mut Ctx> { pub fn wrap_mut(ctx: &'ctx mut Ctx) -> Self { return Self { ctx }; } } _mut_switch!(_constructor!(FixedLeftParent2NodeGetterClojureFromContext)); _mut_switch!(_constructor!(FixedRightParent2NodeGetterClojureFromContext)); _mut_switch!(_constructor!( FixedForwardParent2NodeGetterClojureFromDirectedContext )); _mut_switch!(_constructor!( FixedOppositeParent2NodeGetterClojureFromDirectedContext )); macro_rules! _node_ref { ($name:ident $($mut:tt)?) => { impl NodeRefContainer for $name<& $($mut)? Ctx, Ctx::NodeRef> { type NodeRef = Ctx::NodeRef; } }; } impl<'ctx, Ctx: NodeRefContainer> NodeRefContainer for FixedRootParent2NodeGetterClojureFromContext<&'ctx Ctx> { type NodeRef = Ctx::NodeRef; } impl<'ctx, Ctx: NodeRefContainer> NodeRefContainer for FixedRootParent2NodeGetterClojureFromContext<&'ctx mut Ctx> { type NodeRef = Ctx::NodeRef; } _mut_switch!(_node_ref!(FixedLeftParent2NodeGetterClojureFromContext)); _mut_switch!(_node_ref!(FixedRightParent2NodeGetterClojureFromContext)); _mut_switch!(_node_ref!( FixedForwardParent2NodeGetterClojureFromDirectedContext )); _mut_switch!(_node_ref!( FixedOppositeParent2NodeGetterClojureFromDirectedContext )); macro_rules! _get_child { ($name:ident $ctx_type:ident $fn:ident $($mut:tt)? ) => { impl<'ctx, Ctx: $ctx_type> Parent2NodeGetterClojure for $name <&'ctx $($mut)? Ctx, Ctx::NodeRef> { fn getChild(&self) -> Option { return self.ctx.$fn (self.node.clone()); } } }; } impl<'ctx, Ctx: BinaryTreeRootGetter> Parent2NodeGetterClojure for FixedRootParent2NodeGetterClojureFromContext<&'ctx Ctx> { fn getChild(&self) -> Option { return self.ctx.getRoot(); } } impl<'ctx, Ctx: BinaryTreeRootGetter> Parent2NodeGetterClojure for FixedRootParent2NodeGetterClojureFromContext<&'ctx mut Ctx> { fn getChild(&self) -> Option { return self.ctx.getRoot(); } } _mut_switch!(_get_child!( FixedLeftParent2NodeGetterClojureFromContext BinaryTreeChildrenGetterContext getLeftChild )); _mut_switch!(_get_child!( FixedRightParent2NodeGetterClojureFromContext BinaryTreeChildrenGetterContext getRightChild )); _mut_switch!(_get_child!( FixedForwardParent2NodeGetterClojureFromDirectedContext DirectedBinaryTreeChildrenGetterContext getForwardChild )); _mut_switch!(_get_child!( FixedOppositeParent2NodeGetterClojureFromDirectedContext DirectedBinaryTreeChildrenGetterContext getOppositeChild )); macro_rules! _set_child { ($name:ident $ctx:ident $xset:ident $set:ident $clear:ident) => { impl<'ctx, Ctx: $ctx> Parent2NodeSetterClojure for $name<&'ctx mut Ctx, Ctx::NodeRef> { fn xSetChild(&mut self, newChild: Option) { self.ctx.$xset(self.node.clone(), newChild); } fn setChild(&mut self, newChild: Self::NodeRef) { self.ctx.$set(self.node.clone(), newChild); } fn clearChild(&mut self) { self.ctx.$clear(self.node.clone()); } } }; } impl<'ctx, Ctx: BinaryTreeRootSetter> Parent2NodeSetterClojure for FixedRootParent2NodeGetterClojureFromContext<&'ctx mut Ctx> { fn xSetChild(&mut self, newChild: Option) { self.ctx.xSetRoot(newChild) } fn setChild(&mut self, newChild: Self::NodeRef) { self.ctx.setRoot(newChild) } fn clearChild(&mut self) { self.ctx.clearRoot() } } _set_child!( FixedLeftParent2NodeGetterClojureFromContext BinaryTreeChildrenSetterContext xSetLeftChild setLeftChild clearLeftChild ); _set_child!( FixedRightParent2NodeGetterClojureFromContext BinaryTreeChildrenSetterContext xSetRightChild setRightChild clearRightChild ); _set_child!( FixedForwardParent2NodeGetterClojureFromDirectedContext DirectedBinaryTreeChildrenSetterContext xSetForwardChild setForwardChild clearForwardChild ); _set_child!( FixedOppositeParent2NodeGetterClojureFromDirectedContext DirectedBinaryTreeChildrenSetterContext xSetOppositeChild setOppositeChild clearOppositeChild ); macro_rules! _set_as_parent_of { ($name:ident) => { impl<'ctx, Ctx: BinaryTreeParentSetterContext> ParentProviderClojure for $name<&'ctx mut Ctx, Ctx::NodeRef> { fn setAsParentOf(&mut self, child: Self::NodeRef) { self.ctx.setParent(child, self.node.clone()) } } }; } impl<'ctx, Ctx: BinaryTreeParentSetterContext> ParentProviderClojure for FixedRootParent2NodeGetterClojureFromContext<&'ctx mut Ctx> { fn setAsParentOf(&mut self, child: Self::NodeRef) { self.ctx.clearParent(child) } } _set_as_parent_of!(FixedLeftParent2NodeGetterClojureFromContext); _set_as_parent_of!(FixedRightParent2NodeGetterClojureFromContext); _set_as_parent_of!(FixedForwardParent2NodeGetterClojureFromDirectedContext); _set_as_parent_of!(FixedOppositeParent2NodeGetterClojureFromDirectedContext); macro_rules! _relation_setter { ($name:ident $ctx:ident $xset:ident $set:ident $clear:ident) => { unsafe impl<'ctx, Ctx: $ctx> Parent2NodeRelationSetterClojure for $name<&'ctx mut Ctx, Ctx::NodeRef> { fn xSetRelation(&mut self, newChild: Option) { self.ctx.$xset(self.node.clone(), newChild); } fn setRelation(&mut self, newChild: Self::NodeRef) { self.ctx.$set(self.node.clone(), newChild); } fn clearChild(&mut self) { self.ctx.$clear(self.node.clone()); } } }; } unsafe impl<'ctx, Ctx: BinaryTreeRootRelationSetterContext> Parent2NodeRelationSetterClojure for FixedRootParent2NodeGetterClojureFromContext<&'ctx mut Ctx> { fn xSetRelation(&mut self, newChild: Option) { self.ctx.xSetRootRelation(newChild); } fn setRelation(&mut self, newChild: Self::NodeRef) { self.ctx.setRootRelation(newChild); } fn clearChild(&mut self) { self.ctx.clearRoot() } } _relation_setter!( FixedLeftParent2NodeGetterClojureFromContext BinaryTreeChildrenSetterContext xSetLeftChild setLeftChild clearLeftChild ); _relation_setter!( FixedRightParent2NodeGetterClojureFromContext BinaryTreeChildrenSetterContext xSetRightChild setRightChild clearRightChild ); _relation_setter!( FixedForwardParent2NodeGetterClojureFromDirectedContext DirectedBinaryTreeChildrenSetterContext xSetForwardChild setForwardChild clearForwardChild ); _relation_setter!( FixedOppositeParent2NodeGetterClojureFromDirectedContext DirectedBinaryTreeChildrenSetterContext xSetOppositeChild setOppositeChild clearOppositeChild );