use core::marker::PhantomData; use dyn_any::{DynAny, StaticType, StaticTypeSized}; use crate::Node; #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub struct IntNode; impl<'i, const N: u32> Node<'i, ()> for IntNode { type Output = u32; fn eval<'s: 'i>(&'s self, _input: ()) -> Self::Output { N } } #[derive(Default, Debug)] pub struct ValueNode(pub T); impl StaticType for ValueNode { type Static = ValueNode; } impl<'i, T: 'i> Node<'i, ()> for ValueNode { type Output = &'i T; fn eval<'s: 'i>(&'s self, _input: ()) -> Self::Output { &self.0 } } impl ValueNode { pub const fn new(value: T) -> ValueNode { ValueNode(value) } } impl From for ValueNode { fn from(value: T) -> Self { ValueNode::new(value) } } impl Clone for ValueNode { fn clone(&self) -> Self { Self(self.0.clone()) } } impl Copy for ValueNode {} #[derive(Clone)] pub struct ClonedNode(pub T); impl StaticType for ClonedNode where T::Static: Clone, { type Static = ClonedNode; } impl<'i, T: Clone + 'i> Node<'i, ()> for ClonedNode { type Output = T; fn eval<'s: 'i>(&'s self, _input: ()) -> Self::Output { self.0.clone() } } impl ClonedNode { pub const fn new(value: T) -> ClonedNode { ClonedNode(value) } } impl From for ClonedNode { fn from(value: T) -> Self { ClonedNode::new(value) } } impl Copy for ClonedNode {} #[derive(Default)] pub struct DefaultNode(PhantomData); impl<'i, T: Default + 'i> Node<'i, ()> for DefaultNode { type Output = T; fn eval<'s: 'i>(&self, _input: ()) -> Self::Output { T::default() } } impl DefaultNode { pub fn new() -> Self { Self(PhantomData) } } #[repr(C)] /// Return the unit value #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub struct ForgetNode; impl<'i, T: 'i> Node<'i, T> for ForgetNode { type Output = (); fn eval<'s: 'i>(&self, _input: T) -> Self::Output {} } impl ForgetNode { pub const fn new() -> Self { ForgetNode } } #[cfg(test)] mod test { use super::*; #[test] fn test_int_node() { let node = IntNode::<5>; assert_eq!(node.eval(()), 5); } #[test] fn test_value_node() { let node = ValueNode::new(5); assert_eq!(node.eval(()), &5); let type_erased = &node as &dyn for<'a> Node<'a, (), Output = &'a i32>; assert_eq!(type_erased.eval(()), &5); } #[test] fn test_default_node() { let node = DefaultNode::::new(); assert_eq!(node.eval(()), 0); } #[test] fn test_unit_node() { let node = ForgetNode::new(); assert_eq!(node.eval(()), ()); } }