Rework DynAnyNode design to work with the borrow stack (#796)

This commit is contained in:
TrueDoctor
2022-10-15 03:02:58 +02:00
committed by GitHub
parent 99d92ef887
commit 06acd45a81
8 changed files with 198 additions and 80 deletions

View File

@@ -48,6 +48,34 @@ where
}
}
pub trait AsBoxNode<'n, T>
where
&'n Self: Node<T>,
Self: 'n,
{
type Output;
fn eval_box(&'n self, input: T) -> <Self>::Output;
}
impl<'n, N: 'n, I> AsBoxNode<'n, I> for N
where
&'n N: Node<I, Output = N::Output>,
N: Node<I>,
Self: 'n,
{
type Output = <&'n N as Node<I>>::Output;
fn eval_box(&'n self, input: I) -> <Self>::Output {
self.eval(input)
}
}
impl<'n, T> Node<T> for &'n (dyn AsBoxNode<'n, T, Output = T> + 'n) {
type Output = T;
fn eval(self, input: T) -> Self::Output {
self.eval_box(input)
}
}
#[cfg(feature = "async")]
#[async_trait]
pub trait AsyncNode<T> {

View File

@@ -240,7 +240,7 @@ mod test {
pub fn add_node() {
let a = ValueNode(42u32);
let b = ValueNode(6u32);
let cons_a = ConsNode(a);
let cons_a = ConsNode(a, PhantomData);
let sum = b.then(cons_a).then(AddNode);

View File

@@ -115,49 +115,24 @@ pub trait ThenBox<Inter, Input> {
#[cfg(feature = "async")]
impl<'n, First: 'n, Inter, Input> ThenBox<Inter, Input> for alloc::boxed::Box<First> where &'n alloc::boxed::Box<First>: Node<Input, Output = Inter> {}
pub struct ConsNode<Root>(pub Root);
pub struct ConsNode<Root, T: From<()>>(pub Root, pub PhantomData<T>);
impl<Root, Input> Node<Input> for ConsNode<Root>
impl<Root, Input, T: From<()>> Node<Input> for ConsNode<Root, T>
where
Root: Node<()>,
Root: Node<T>,
{
type Output = (Input, <Root as Node<()>>::Output);
type Output = (Input, <Root as Node<T>>::Output);
fn eval(self, input: Input) -> Self::Output {
let arg = self.0.eval(());
let arg = self.0.eval(().into());
(input, arg)
}
}
impl<'n, Root: Node<()> + Copy, Input> Node<Input> for &'n ConsNode<Root> {
impl<'n, Root: Node<T> + Copy, T: From<()>, Input> Node<Input> for &'n ConsNode<Root, T> {
type Output = (Input, Root::Output);
fn eval(self, input: Input) -> Self::Output {
let arg = (&self.0).eval(());
let arg = self.0.eval(().into());
(input, arg)
}
}
pub struct ConsPassInputNode<Root>(pub Root);
impl<Root, L, R> Node<(L, R)> for ConsPassInputNode<Root>
where
Root: Node<R>,
{
type Output = (L, <Root as Node<R>>::Output);
fn eval(self, input: (L, R)) -> Self::Output {
let arg = self.0.eval(input.1);
(input.0, arg)
}
}
impl<'n, Root, L, R> Node<(L, R)> for &'n ConsPassInputNode<Root>
where
&'n Root: Node<R>,
{
type Output = (L, <&'n Root as Node<R>>::Output);
fn eval(self, input: (L, R)) -> Self::Output {
let arg = (&self.0).eval(input.1);
(input.0, arg)
}
}