diff --git a/src/parent2node/clojure.rs b/src/parent2node/clojure.rs index 2d0cf1f..04aa568 100644 --- a/src/parent2node/clojure.rs +++ b/src/parent2node/clojure.rs @@ -1,7 +1,7 @@ use crate::NodeRefContainer; pub trait Parent2NodeGetterClojure: NodeRefContainer { - fn getChild(&self) -> Self::NodeRef; + fn getChild(&self) -> Option; } pub trait Parent2NodeSetterClojure: NodeRefContainer { diff --git a/src/parent2node/dynamic_wrappers.rs b/src/parent2node/dynamic_wrappers.rs index 9e9845b..f7d9e46 100644 --- a/src/parent2node/dynamic_wrappers.rs +++ b/src/parent2node/dynamic_wrappers.rs @@ -2,6 +2,7 @@ use super::clojure::Parent2NodeSetterClojure; use crate::BinaryTreeDirection; use crate::NodeRefContainer; use crate::context::BinaryTreeRootGetter; +use crate::context::BinaryTreeRootSetter; use crate::context::{BinaryTreeChildrenGetterContext, BinaryTreeChildrenSetterContext}; use crate::directed::{ DirectedBinaryTreeChildrenGetterContext, DirectedBinaryTreeChildrenSetterContext, @@ -9,6 +10,7 @@ use crate::directed::{ use crate::direction::DirectedBinaryTreeDirection; use crate::parent2node::clojure::Parent2NodeGetterClojure; use std::mem::ManuallyDrop; +use std::ops::Deref; macro_rules! _mut_switch { ($macro:tt $excl_mark:tt ( $($args:tt)+) ) => { @@ -76,11 +78,15 @@ macro_rules! _get_child { > Parent2NodeGetterClojure for $name <&'ctx $($mut)? Ctx, Ctx::NodeRef> { - fn getChild(&self) -> Self::NodeRef { + fn getChild(&self) -> Option { match self.dir { None => return self.ctx.getRoot(), - Some($dir_enum_lbl::$d1_lbl) => self.ctx.$d1_get (self.ctx.node.node), - Some($dir_enum_lbl::$d2_lbl) => self.ctx.$d2_get (self.ctx.node.node) + Some($dir_enum_lbl::$d1_lbl) => unsafe { + self.ctx.$d1_get (*self.node.node.deref()) + }, + Some($dir_enum_lbl::$d2_lbl) => unsafe { + self.ctx.$d2_get (*self.node.node.deref()) + } } } } @@ -101,36 +107,50 @@ macro_rules! _set_child { $name:ident $ctx_constraint:ident $dir_enum_lbl:ident $d1_lbl:ident $d1_xset:ident $d1_set:ident $d1_clear:ident $d2_lbl:ident $d2_xset:ident $d2_set:ident $d2_clear:ident - $($mut:tt)? ) => { impl< 'ctx, - Ctx: NodeRefContainer + BinaryTreeRootGetter + $ctx_constraint + Ctx: NodeRefContainer + BinaryTreeRootSetter + $ctx_constraint > Parent2NodeSetterClojure - for $name <&'ctx $($mut)? Ctx, Ctx::NodeRef> + for $name <&'ctx mut Ctx, Ctx::NodeRef> { fn xSetChild(&mut self, newChild: Option) { match self.dir { - None => return self.ctx.xSetRoot(newChild), - Some($dir_enum_lbl::$d1_lbl) => self.ctx.$d1_xset (self.ctx.node.node, newChild), - Some($dir_enum_lbl::$d2_lbl) => self.ctx.$d2_xset (self.ctx.node.node, newChild) - } + None => self.ctx.xSetRoot(newChild), + Some($dir_enum_lbl::$d1_lbl) => unsafe { + self.ctx.$d1_xset (*self.node.node.deref(), newChild) + }, + Some($dir_enum_lbl::$d2_lbl) => unsafe { + self.ctx.$d2_xset (*self.node.node.deref(), newChild) + } + }; + return; } fn setChild(&mut self, newChild: Self::NodeRef) { match self.dir { - None => return self.ctx.setRoot(newChild), - Some($dir_enum_lbl::$d1_lbl) => self.ctx.$d1_set (self.ctx.node.node, newChild), - Some($dir_enum_lbl::$d2_lbl) => self.ctx.$d2_set (self.ctx.node.node, newChild) - } + None => self.ctx.setRoot(newChild), + Some($dir_enum_lbl::$d1_lbl) => unsafe { + self.ctx.$d1_set (*self.node.node.deref(), newChild) + }, + Some($dir_enum_lbl::$d2_lbl) => unsafe { + self.ctx.$d2_set (*self.node.node.deref(), newChild) + } + }; + return; } fn clearChild(&mut self) { match self.dir { - None => return self.ctx.clearRoot(), - Some($dir_enum_lbl::$d1_lbl) => self.ctx.$d1_clear (self.ctx.node.node), - Some($dir_enum_lbl::$d2_lbl) => self.ctx.$d2_clear (self.ctx.node.node) - } + None => self.ctx.clearRoot(), + Some($dir_enum_lbl::$d1_lbl) => unsafe { + self.ctx.$d1_clear (*self.node.node.deref()) + }, + Some($dir_enum_lbl::$d2_lbl) => unsafe { + self.ctx.$d2_clear (*self.node.node.deref()) + } + }; + return; } } }; diff --git a/src/parent2node/fixed_wrapper.rs b/src/parent2node/fixed_wrapper.rs index 64d93d1..61c2e23 100644 --- a/src/parent2node/fixed_wrapper.rs +++ b/src/parent2node/fixed_wrapper.rs @@ -42,7 +42,9 @@ macro_rules! _constructor { }; } -impl<'ctx, Ctx: NodeRefContainer + BinaryTreeRootGetter> FixedRootParent2NodeGetterClojureFromContext<&'ctx Ctx> { +impl<'ctx, Ctx: NodeRefContainer + BinaryTreeRootGetter> + FixedRootParent2NodeGetterClojureFromContext<&'ctx Ctx> +{ fn wrap(ctx: &'ctx Ctx) -> Self { return Self { ctx }; } @@ -56,8 +58,12 @@ impl<'ctx, Ctx: NodeRefContainer> FixedRootParent2NodeGetterClojureFromContext<& _mut_switch!(_constructor!(FixedLeftParent2NodeGetterClojureFromContext)); _mut_switch!(_constructor!(FixedRightParent2NodeGetterClojureFromContext)); -_mut_switch!(_constructor!(FixedForwardParent2NodeGetterClojureFromDirectedContext)); -_mut_switch!(_constructor!(FixedOppositeParent2NodeGetterClojureFromDirectedContext)); +_mut_switch!(_constructor!( + FixedForwardParent2NodeGetterClojureFromDirectedContext +)); +_mut_switch!(_constructor!( + FixedOppositeParent2NodeGetterClojureFromDirectedContext +)); macro_rules! _node_ref { ($name:ident $($mut:tt)?) => { @@ -67,7 +73,9 @@ macro_rules! _node_ref { }; } -impl<'ctx, Ctx: NodeRefContainer> NodeRefContainer for FixedRootParent2NodeGetterClojureFromContext<&'ctx Ctx> { +impl<'ctx, Ctx: NodeRefContainer> NodeRefContainer + for FixedRootParent2NodeGetterClojureFromContext<&'ctx Ctx> +{ type NodeRef = Ctx::NodeRef; } @@ -79,16 +87,20 @@ impl<'ctx, Ctx: NodeRefContainer> NodeRefContainer _mut_switch!(_node_ref!(FixedLeftParent2NodeGetterClojureFromContext)); _mut_switch!(_node_ref!(FixedRightParent2NodeGetterClojureFromContext)); -_mut_switch!(_node_ref!(FixedForwardParent2NodeGetterClojureFromDirectedContext)); -_mut_switch!(_node_ref!(FixedOppositeParent2NodeGetterClojureFromDirectedContext)); +_mut_switch!(_node_ref!( + FixedForwardParent2NodeGetterClojureFromDirectedContext +)); +_mut_switch!(_node_ref!( + FixedOppositeParent2NodeGetterClojureFromDirectedContext +)); macro_rules! _get_child { - ($name:ident $fn:ident $($mut:tt)? ) => { - impl<'ctx, Ctx: BinaryTreeChildrenGetterContext> Parent2NodeGetterClojure + ($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) -> Self::NodeRef { - return self.ctx.$fn(self.node); + fn getChild(&self) -> Option { + return self.ctx.$fn (self.node); } } }; @@ -97,7 +109,7 @@ macro_rules! _get_child { impl<'ctx, Ctx: BinaryTreeRootGetter> Parent2NodeGetterClojure for FixedRootParent2NodeGetterClojureFromContext<&'ctx Ctx> { - fn getChild(&self) -> Self::NodeRef { + fn getChild(&self) -> Option { return self.ctx.getRoot(); } } @@ -105,21 +117,31 @@ impl<'ctx, Ctx: BinaryTreeRootGetter> Parent2NodeGetterClojure impl<'ctx, Ctx: BinaryTreeRootGetter> Parent2NodeGetterClojure for FixedRootParent2NodeGetterClojureFromContext<&'ctx mut Ctx> { - fn getChild(&self) -> Self::NodeRef { + fn getChild(&self) -> Option { return self.ctx.getRoot(); } } -_mut_switch!(_get_child!(FixedLeftParent2NodeGetterClojureFromContext getLeftChild)); -_mut_switch!(_get_child!(FixedRightParent2NodeGetterClojureFromContext getRightChild)); -_mut_switch!(_get_child!(FixedForwardParent2NodeGetterClojureFromDirectedContext getForwardChild)); -_mut_switch!(_get_child!(FixedOppositeParent2NodeGetterClojureFromDirectedContext getOppositeChild)); +_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 $xset:ident $set:ident $clear:ident) => { - impl<'ctx, Ctx: BinaryTreeChildrenSetterContext> Parent2NodeSetterClojure - for $name<&'ctx mut Ctx, Ctx::NodeRef> - { + ($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, newChild); } @@ -151,7 +173,19 @@ impl<'ctx, Ctx: BinaryTreeRootSetter> Parent2NodeSetterClojure } } -_set_child!(FixedLeftParent2NodeGetterClojureFromContext xSetLeftChild setLeftChild clearLeftChild); -_set_child!(FixedRightParent2NodeGetterClojureFromContext xSetRightChild setRightChild clearRightChild); -_set_child!(FixedForwardParent2NodeGetterClojureFromDirectedContext xSetForwardChild setForwardChild clearForwardChild); -_set_child!(FixedOppositeParent2NodeGetterClojureFromDirectedContext xSetOppositeChild setOppositeChild clearOppositeChild); +_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 +);