#![feature(generic_associated_types)] //#![deny(rust_2018_idioms)] use std::{any::Any, borrow::Borrow}; mod iter; pub mod nodes; use iter::insert_after_nth; use nodes::*; #[rustfmt::skip] pub trait Node { // Self: 'a means that Self has to live at least as long as 'a (the input and output) // this ensures that the node does not spontaneously disappear during evaluation type Output<'a> where Self: 'a; type Input<'a> where Self: 'a; fn eval<'a, I: Borrow>>(&'a self, input: I) -> Self::Output<'a>; } pub trait AnyRef: Node { fn any<'a>(&'a self, input: &'a dyn Any) -> Self::Output<'a> where Self::Input<'a>: 'static + Copy; } impl AnyRef for T { fn any<'a>(&'a self, input: &'a dyn Any) -> Self::Output<'a> where Self::Input<'a>: 'static + Copy, { self.eval::<&Self::Input<'a>>(input.downcast_ref::>().unwrap_or_else( || { panic!( "Node was evaluated with wrong input. The input has to be of type: {}", std::any::type_name::>(), ) }, )) } } trait DefaultNode: Default { fn default_node() -> ValueNode { ValueNode::new(Self::default()) } } impl DefaultNode for T {} trait After: Sized { fn after<'a, First: Node>(&'a self, first: &'a First) -> ComposeNode<'a, First, Self> { ComposeNode::new(first, self) } } impl After for Second {} fn main() { let int = IntNode::<32>; let add: u32 = AddNode::::default().eval((int.eval(&()), int.eval(&()))); let fnode = FnNode::new(|(a, b): &(i32, i32)| a - b); let sub = fnode.any(&("a", 2)); /* let curry: CurryNthArgNode<'_, _, _, u32, u32, 0> = CurryNthArgNode::new(&AddNode, &int); let composition = curry.after(&curry); let n = ValueNode::new(10_u32); let curry: CurryNthArgNode<'_, _, _, u32, _, 0> = CurryNthArgNode::new(&composition, &n); */ println!("{}", sub) }