mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-03 21:08:18 +00:00
Rework DynAnyNode design to work with the borrow stack (#796)
This commit is contained in:
parent
cef58b16c2
commit
562217015d
8 changed files with 198 additions and 80 deletions
|
@ -25,12 +25,20 @@ pub fn downcast_ref<'a, V: StaticType>(i: &'a dyn DynAny<'a>) -> Option<&'a V> {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn downcast<'a, V: StaticType>(i: Box<dyn DynAny<'a> + 'a>) -> Option<Box<V>> {
|
||||
if i.type_id() == std::any::TypeId::of::<<V as StaticType>::Static>() {
|
||||
let type_id = DynAny::type_id(i.as_ref());
|
||||
if type_id == std::any::TypeId::of::<<V as StaticType>::Static>() {
|
||||
// SAFETY: caller guarantees that T is the correct type
|
||||
let ptr = Box::into_raw(i) as *mut dyn DynAny<'a> as *mut V;
|
||||
Some(unsafe { Box::from_raw(ptr) })
|
||||
} else {
|
||||
// TODO: add log error
|
||||
if type_id == std::any::TypeId::of::<&dyn DynAny<'static>>() {
|
||||
panic!("downcast error: type_id == std::any::TypeId::of::<dyn DynAny<'a>>()");
|
||||
}
|
||||
println!("expected: {:?}", std::any::TypeId::of::<<V as StaticType>::Static>());
|
||||
println!("actual one: {:?}", type_id);
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -94,13 +102,29 @@ impl<'a> StaticType for &'a str {
|
|||
impl StaticType for () {
|
||||
type Static = ();
|
||||
}
|
||||
impl<'a, T: 'a + StaticType> StaticType for &'a T {
|
||||
impl<'a, T: 'a + StaticType + ?Sized> StaticType for &'a T {
|
||||
type Static = &'static <T as StaticType>::Static;
|
||||
}
|
||||
impl<T: StaticTypeSized, const N: usize> StaticType for [T; N] {
|
||||
type Static = [<T as StaticTypeSized>::Static; N];
|
||||
}
|
||||
|
||||
impl<'a> StaticType for dyn DynAny<'a> + '_ {
|
||||
type Static = dyn DynAny<'static>;
|
||||
}
|
||||
pub trait IntoDynAny<'n>: Sized + StaticType + 'n {
|
||||
fn into_dyn(self) -> Box<dyn DynAny<'n> + 'n> {
|
||||
Box::new(self)
|
||||
}
|
||||
}
|
||||
impl<'n, T: StaticType + 'n> IntoDynAny<'n> for T {}
|
||||
|
||||
impl From<()> for Box<dyn DynAny<'static>> {
|
||||
fn from(_: ()) -> Box<dyn DynAny<'static>> {
|
||||
Box::new(())
|
||||
}
|
||||
}
|
||||
|
||||
use core::{
|
||||
cell::{Cell, RefCell, UnsafeCell},
|
||||
iter::Empty,
|
||||
|
@ -117,12 +141,21 @@ use std::{
|
|||
|
||||
impl_type!(Option<T>,Result<T, E>,Cell<T>,UnsafeCell<T>,RefCell<T>,MaybeUninit<T>,
|
||||
Vec<T>, String, BTreeMap<K,V>,BTreeSet<V>, LinkedList<T>, VecDeque<T>,
|
||||
BinaryHeap<T>, Box<T>, ManuallyDrop<T>, PhantomData<T>, PhantomPinned,Empty<T>,
|
||||
BinaryHeap<T>, ManuallyDrop<T>, PhantomData<T>, PhantomPinned,Empty<T>,
|
||||
Wrapping<T>, Duration, Once, Mutex<T>, RwLock<T>, bool, f32, f64, char,
|
||||
u8, AtomicU8, u16,AtomicU16, u32,AtomicU32, u64,AtomicU64, usize,AtomicUsize,
|
||||
i8,AtomicI8, i16,AtomicI16, i32,AtomicI32, i64,AtomicI64, isize,AtomicIsize,
|
||||
i128, u128, AtomicBool, AtomicPtr<T>
|
||||
);
|
||||
|
||||
impl<T: crate::StaticType + ?Sized> crate::StaticType for Box<T> {
|
||||
type Static = Box<<T as crate::StaticType>::Static>;
|
||||
}
|
||||
fn test() {
|
||||
let foo = (Box::new(&1 as &dyn DynAny<'static>), Box::new(&2 as &dyn DynAny<'static>));
|
||||
//let bar = &foo as &dyn DynAny<'static>;
|
||||
}
|
||||
|
||||
macro_rules! impl_tuple {
|
||||
(@rec $t:ident) => { };
|
||||
(@rec $_:ident $($t:ident)+) => {
|
||||
|
@ -148,3 +181,9 @@ fn simple_downcast() {
|
|||
let x = Box::new(3_u32) as Box<dyn DynAny>;
|
||||
assert_eq!(*downcast::<u32>(x).unwrap(), 3_u32);
|
||||
}
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn simple_downcast_panic() {
|
||||
let x = Box::new(3_i32) as Box<dyn DynAny>;
|
||||
assert_eq!(*downcast::<u32>(x).expect("attempted to perform invalid downcast"), 3_u32);
|
||||
}
|
||||
|
|
|
@ -8,11 +8,11 @@ use std::{
|
|||
pub trait BorrowStack<'n> {
|
||||
type Item;
|
||||
/// # Safety
|
||||
unsafe fn push(&'n self, value: Self::Item);
|
||||
unsafe fn push(&self, value: Self::Item);
|
||||
/// # Safety
|
||||
unsafe fn pop(&'n self);
|
||||
unsafe fn pop(&self);
|
||||
/// # Safety
|
||||
unsafe fn get(&'n self) -> &'n [Self::Item];
|
||||
unsafe fn get(&self) -> &'n [Self::Item];
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -23,7 +23,7 @@ pub struct FixedSizeStack<'n, T> {
|
|||
_phantom: PhantomData<&'n ()>,
|
||||
}
|
||||
|
||||
impl<'n, T: Unpin> FixedSizeStack<'n, T> {
|
||||
impl<'n, T: Unpin + 'n> FixedSizeStack<'n, T> {
|
||||
pub fn new(capacity: usize) -> Self {
|
||||
let layout = std::alloc::Layout::array::<MaybeUninit<T>>(capacity).unwrap();
|
||||
let array = unsafe { std::alloc::alloc(layout) };
|
||||
|
@ -44,12 +44,15 @@ impl<'n, T: Unpin> FixedSizeStack<'n, T> {
|
|||
pub fn is_empty(&self) -> bool {
|
||||
self.len.load(Ordering::SeqCst) == 0
|
||||
}
|
||||
pub fn push_fn(&self, f: impl FnOnce(&'n [T]) -> T) {
|
||||
unsafe { self.push(f(self.get())) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, T> BorrowStack<'n> for FixedSizeStack<'n, T> {
|
||||
type Item = T;
|
||||
|
||||
unsafe fn push(&'n self, value: Self::Item) {
|
||||
unsafe fn push(&self, value: Self::Item) {
|
||||
let len = self.len.load(Ordering::SeqCst);
|
||||
assert!(len < self.capacity);
|
||||
let ptr = self.data[len].as_ptr();
|
||||
|
@ -57,13 +60,13 @@ impl<'n, T> BorrowStack<'n> for FixedSizeStack<'n, T> {
|
|||
self.len.fetch_add(1, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
unsafe fn pop(&'n self) {
|
||||
unsafe fn pop(&self) {
|
||||
let ptr = self.data[self.len.load(Ordering::SeqCst)].as_ptr();
|
||||
Box::from_raw(ptr as *mut T);
|
||||
let _ = Box::from_raw(ptr as *mut T);
|
||||
self.len.fetch_sub(1, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
unsafe fn get(&'n self) -> &'n [Self::Item] {
|
||||
unsafe fn get(&self) -> &'n [Self::Item] {
|
||||
std::slice::from_raw_parts(self.data.as_ptr() as *const T, self.len.load(Ordering::SeqCst))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,39 +1,53 @@
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use graphene_core::structural::*;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use graphene_core::value::ValueNode;
|
||||
use graphene_core::{structural::*, RefNode};
|
||||
|
||||
use borrow_stack::BorrowStack;
|
||||
use graphene_std::any::{Any, DynAnyNode, DynAnyNodeTrait};
|
||||
use dyn_any::{downcast, DynAny, IntoDynAny};
|
||||
use graphene_std::any::{Any, DowncastNode, DynAnyNode, TypeErasedNode};
|
||||
use graphene_std::ops::AddNode;
|
||||
|
||||
#[test]
|
||||
fn borrow_stack() {
|
||||
let stack = borrow_stack::FixedSizeStack::new(256);
|
||||
unsafe {
|
||||
let dynanynode: DynAnyNode<'_, _, ()> = DynAnyNode::new(&ValueNode(2_u32));
|
||||
let refn = Box::new(dynanynode) as Box<dyn DynAnyNodeTrait>;
|
||||
stack.push(refn);
|
||||
}
|
||||
unsafe {
|
||||
let dynanynode: DynAnyNode<'_, _, &u32> = DynAnyNode::new(&ConsNode(ValueNode(2_u32)));
|
||||
let refn = Box::new(dynanynode) as Box<dyn DynAnyNodeTrait>;
|
||||
stack.push(refn);
|
||||
}
|
||||
unsafe {
|
||||
let dynanynode: DynAnyNode<'_, _, (&u32, u32)> = DynAnyNode::new(&AddNode);
|
||||
let refn = Box::new(dynanynode) as Box<dyn DynAnyNodeTrait>;
|
||||
stack.push(refn);
|
||||
let dynanynode: DynAnyNode<_, (), _, _> = DynAnyNode::new(ValueNode(2_u32));
|
||||
stack.push(dynanynode.into_box());
|
||||
}
|
||||
stack.push_fn(|nodes| {
|
||||
let downcast: DowncastNode<_, &u32> = DowncastNode::new(&nodes[0]);
|
||||
let dynanynode: DynAnyNode<ConsNode<_, Any<'_>>, u32, _, _> = DynAnyNode::new(ConsNode(downcast, PhantomData));
|
||||
dynanynode.into_box()
|
||||
});
|
||||
stack.push_fn(|_| {
|
||||
let dynanynode: DynAnyNode<_, (u32, &u32), _, _> = DynAnyNode::new(AddNode);
|
||||
dynanynode.into_box()
|
||||
});
|
||||
stack.push_fn(|nodes| {
|
||||
let compose_node = nodes[1].after(&nodes[2]);
|
||||
TypeErasedNode(Box::new(compose_node))
|
||||
});
|
||||
|
||||
let mut input = Box::new(()) as Any;
|
||||
let result = unsafe { &stack.get()[1] }.eval_ref(4_u32.into_dyn());
|
||||
assert_eq!(*downcast::<(u32, &u32)>(result).unwrap(), (4_u32, &2_u32));
|
||||
let result = unsafe { &stack.get()[1] }.eval_ref(4_u32.into_dyn());
|
||||
let add = unsafe { &stack.get()[2] }.eval_ref(result);
|
||||
assert_eq!(*downcast::<u32>(add).unwrap(), 6_u32);
|
||||
let add = unsafe { &stack.get()[3] }.eval_ref(4_u32.into_dyn());
|
||||
assert_eq!(*downcast::<u32>(add).unwrap(), 6_u32);
|
||||
|
||||
/*
|
||||
for i in 0..3 {
|
||||
println!("node_id: {}", i);
|
||||
let value = unsafe { &stack.get()[i] };
|
||||
input = value.eval_ref_dispatch(input);
|
||||
}
|
||||
input = value.eval_ref(input);
|
||||
}*/
|
||||
|
||||
assert_eq!(*dyn_any::downcast::<u32>(input).unwrap(), 4)
|
||||
//assert_eq!(*dyn_any::downcast::<u32>(result).unwrap(), 4)
|
||||
|
||||
//assert_eq!(4, *dyn_any::downcast::<u32>(DynamicAddNode.eval((Box::new(2_u32) as Dynamic, Box::new(2_u32) as Dynamic))).unwrap());
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ fn fmt_error<I>() -> String {
|
|||
format!("DynAnyNode: input is not of correct type, expected {}", std::any::type_name::<I>())
|
||||
}
|
||||
|
||||
pub struct DynAnyNode<'n, N: RefNode<I>, I>(pub N, pub PhantomData<&'n I>);
|
||||
pub struct DynAnyNode<N, I: StaticType, O: StaticType, ORef: StaticType>(pub N, PhantomData<(I, O, ORef)>);
|
||||
/*impl<'n, I: StaticType, N: RefNode<'n, &'n I, Output = O> + 'n, O: 'n + StaticType> Node<&'n dyn DynAny<'n>> for DynAnyNode<'n, N, I> {
|
||||
type Output = Box<dyn dyn_any::DynAny<'n> + 'n>;
|
||||
fn eval(self, input: &'n dyn DynAny<'n>) -> Self::Output {
|
||||
|
@ -29,22 +29,42 @@ impl<'n, I: StaticType, N: RefNode<'n, I, Output = O> + 'n, O: 'n + StaticType>
|
|||
Box::new(self.0.eval_ref(*input))
|
||||
}
|
||||
}*/
|
||||
impl<'n, I: StaticType, N: RefNode<I, Output = O> + Copy + 'n, O: 'n + StaticType> Node<Any<'n>> for &'n DynAnyNode<'n, N, I> {
|
||||
impl<'n, I: StaticType, N: 'n, O: 'n + StaticType, ORef: 'n + StaticType> Node<Any<'n>> for DynAnyNode<N, I, O, ORef>
|
||||
where
|
||||
N: Node<I, Output = O>,
|
||||
{
|
||||
type Output = Any<'n>;
|
||||
fn eval(self, input: Any<'n>) -> Self::Output {
|
||||
let input: Box<I> = dyn_any::downcast(input).unwrap_or_else(|| panic!("{}", fmt_error::<I>()));
|
||||
Box::new(self.0.eval_ref(*input))
|
||||
Box::new(self.0.eval(*input))
|
||||
}
|
||||
}
|
||||
impl<'n, I: StaticType, N: 'n, O: 'n + StaticType, ORef: 'n + StaticType> Node<Any<'n>> for &'n DynAnyNode<N, I, O, ORef>
|
||||
where
|
||||
&'n N: Node<I, Output = ORef>,
|
||||
{
|
||||
type Output = Any<'n>;
|
||||
fn eval(self, input: Any<'n>) -> Self::Output {
|
||||
let input: Box<I> = dyn_any::downcast(input).unwrap_or_else(|| panic!("{}", fmt_error::<I>()));
|
||||
Box::new((&self.0).eval_ref(*input))
|
||||
}
|
||||
}
|
||||
pub struct TypeErasedNode<'n>(pub Box<dyn AsBoxNode<'n, Any<'n>, Output = Any<'n>>>);
|
||||
impl<'n> Node<Any<'n>> for &'n TypeErasedNode<'n> {
|
||||
type Output = Any<'n>;
|
||||
fn eval(self, input: Any<'n>) -> Self::Output {
|
||||
self.0.eval_box(input)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, I: StaticType, N: RefNode<I, Output = O> + 'n + Copy, O: 'n + StaticType> DynAnyNode<'n, N, I>
|
||||
impl<'n, I: StaticType + 'n, N: 'n, O: 'n + StaticType, ORef: 'n + StaticType> DynAnyNode<N, I, O, ORef>
|
||||
where
|
||||
N::Output: StaticType,
|
||||
&'n N: Node<I, Output = ORef>,
|
||||
{
|
||||
pub fn new(n: N) -> Self {
|
||||
DynAnyNode(n, PhantomData)
|
||||
}
|
||||
pub fn into_erased(&'n self) -> impl RefNode<Any<'n>, Output = Any<'n>> {
|
||||
pub fn into_impl(&'n self) -> impl RefNode<Any<'n>, Output = Any<'n>> {
|
||||
self
|
||||
}
|
||||
/*pub fn as_ref(&'n self) -> &'n AnyNode<'n> {
|
||||
|
@ -53,22 +73,61 @@ where
|
|||
pub fn into_ref_box(self) -> Box<dyn RefNode<Box<(dyn DynAny<'n> + 'n)>, Output = Box<(dyn DynAny<'n> + 'n)>> + 'n> {
|
||||
Box::new(self)
|
||||
}*/
|
||||
pub fn into_ref(self: &'n &'n Self) -> &'n (dyn RefNode<Any<'n>, Output = Any<'n>> + 'n) {
|
||||
pub fn as_ref(self: &'n &'n Self) -> &'n (dyn RefNode<Any<'n>, Output = Any<'n>> + 'n) {
|
||||
self
|
||||
}
|
||||
pub fn into_box<'a: 'n>(self) -> TypeErasedNode<'n>
|
||||
where
|
||||
Self: 'a,
|
||||
N: Node<I, Output = O>,
|
||||
{
|
||||
TypeErasedNode(Box::new(self))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DowncastNode<N, I: StaticType>(pub N, PhantomData<I>);
|
||||
impl<N: Copy + Clone, I: StaticType> Clone for DowncastNode<N, I> {
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0, self.1)
|
||||
}
|
||||
}
|
||||
impl<N: Copy + Clone, I: StaticType> Copy for DowncastNode<N, I> {}
|
||||
|
||||
impl<'n, N, O: 'n + StaticType> Node<Any<'n>> for DowncastNode<N, O>
|
||||
where
|
||||
N: Node<Any<'n>, Output = Any<'n>>,
|
||||
{
|
||||
type Output = O;
|
||||
fn eval(self, input: Any<'n>) -> Self::Output {
|
||||
let output = self.0.eval(input);
|
||||
*dyn_any::downcast(output).unwrap_or_else(|| panic!("DowncastNode: {}", fmt_error::<O>()))
|
||||
}
|
||||
}
|
||||
impl<'n, N, I: StaticType> DowncastNode<N, I>
|
||||
where
|
||||
N: Node<Any<'n>>,
|
||||
{
|
||||
pub fn new(n: N) -> Self {
|
||||
DowncastNode(n, PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/// If we store a `Box<dyn RefNode>` in the stack then the origional DynAnyNode is dropped (because it is not stored by reference)
|
||||
/// This trait is implemented directly by `DynAnyNode` so this means the borrow stack will hold by value
|
||||
pub trait DynAnyNodeTrait<'n> {
|
||||
fn eval_ref_dispatch(&'n self, input: Any<'n>) -> Any<'n>;
|
||||
}
|
||||
impl<'n, I: StaticType, O: 'n + StaticType, Node: RefNode<I, Output = O> + Copy + 'n> DynAnyNodeTrait<'n> for DynAnyNode<'n, Node, I> {
|
||||
impl<'n, I: StaticType, O: 'n + StaticType, Node: 'n> DynAnyNodeTrait<'n> for DynAnyNode<Node, I, O>
|
||||
where
|
||||
&'n Node: RefNode<I>,
|
||||
{
|
||||
fn eval_ref_dispatch(&'n self, input: Any<'n>) -> Any<'n> {
|
||||
self.eval_ref(input)
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
use graphene_core::ops::Dynamic;
|
||||
use graphene_core::{ops::Dynamic, AsBoxNode};
|
||||
pub struct BoxedComposition<'a, Second> {
|
||||
pub first: Box<dyn Node<(), Output = Dynamic<'a>>>,
|
||||
pub second: Second,
|
||||
|
@ -138,9 +197,9 @@ mod test {
|
|||
#[test]
|
||||
#[should_panic]
|
||||
pub fn dyn_input_invalid_eval_panic() {
|
||||
static ADD: &DynAnyNode<&AddNode, (u32, u32)> = &DynAnyNode(&AddNode, PhantomData);
|
||||
static ADD: &DynAnyNode<AddNode, (u32, u32), u32, u32> = &DynAnyNode(AddNode, PhantomData);
|
||||
|
||||
let add = ADD.into_ref();
|
||||
let add = ADD.as_ref();
|
||||
add.eval_ref(Box::new(&("32", 32u32)));
|
||||
}
|
||||
/*#[test]
|
||||
|
@ -161,11 +220,11 @@ mod test {
|
|||
|
||||
// If we put this until the push in a new scope then it failes to compile due to lifetime errors which I'm struggling to fix.
|
||||
|
||||
let value: &DynAnyNode<&ValueNode<(u32, u32)>, ()> = &DynAnyNode(&ValueNode((3u32, 4u32)), PhantomData);
|
||||
let add: &DynAnyNode<&AddNode, &(u32, u32)> = &DynAnyNode(&AddNode, PhantomData);
|
||||
let value: &DynAnyNode<ValueNode<(u32, u32)>, (), &(u32, u32), _> = &DynAnyNode(ValueNode((3u32, 4u32)), PhantomData);
|
||||
let add: &DynAnyNode<AddNode, &(u32, u32), u32, _> = &DynAnyNode(AddNode, PhantomData);
|
||||
|
||||
let value_ref = (&value).into_ref();
|
||||
let add_ref = (&add).into_ref();
|
||||
let value_ref = value.as_ref();
|
||||
let add_ref = add.as_ref();
|
||||
vec.push(value_ref);
|
||||
vec.push(add_ref);
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ impl<'a> IntoIterator for &'a Image {
|
|||
|
||||
pub fn file_node<'n, P: AsRef<Path> + 'n>() -> impl Node<P, Output = Result<Vec<u8>, Error>> {
|
||||
let fs = ValueNode(StdFs).clone();
|
||||
let fs = ConsNode(fs);
|
||||
let fs = ConsNode(fs, PhantomData);
|
||||
let file: ComposeNode<_, _, P> = fs.then(FileNode(PhantomData));
|
||||
|
||||
file.then(FlatMapResultNode::new(BufferNode))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue