diff --git a/libraries/dyn-any/src/lib.rs b/libraries/dyn-any/src/lib.rs index 2758b21d..387e09f7 100644 --- a/libraries/dyn-any/src/lib.rs +++ b/libraries/dyn-any/src/lib.rs @@ -5,8 +5,49 @@ #[cfg_attr(feature = "unstable-docs", doc(cfg(feature = "derive")))] pub use dyn_any_derive::DynAny; +/// Implement this trait for your `dyn Trait` types for all `T: Trait` +pub trait UpcastFrom { + fn up_from(value: &T) -> &Self; + fn up_from_mut(value: &mut T) -> &mut Self; + fn up_from_box(value: Box) -> Box; +} + +/// Use this trait to perform your upcasts on dyn traits. Make sure to require it in the supertrait! +pub trait Upcast { + fn up(&self) -> &U; + fn up_mut(&mut self) -> &mut U; + fn up_box(self: Box) -> Box; +} + +impl Upcast for T +where + U: UpcastFrom, +{ + fn up(&self) -> &U { + U::up_from(self) + } + fn up_mut(&mut self) -> &mut U { + U::up_from_mut(self) + } + fn up_box(self: Box) -> Box { + U::up_from_box(self) + } +} + use std::any::TypeId; +impl<'a, T: DynAny<'a> + 'a> UpcastFrom for dyn DynAny<'a> + 'a { + fn up_from(value: &T) -> &(dyn DynAny<'a> + 'a) { + value + } + fn up_from_mut(value: &mut T) -> &mut (dyn DynAny<'a> + 'a) { + value + } + fn up_from_box(value: Box) -> Box { + value + } +} + pub trait DynAny<'a> { fn type_id(&self) -> TypeId; } diff --git a/node-graph/graph-craft/src/document/value.rs b/node-graph/graph-craft/src/document/value.rs index 5dfb03ee..640313af 100644 --- a/node-graph/graph-craft/src/document/value.rs +++ b/node-graph/graph-craft/src/document/value.rs @@ -2,11 +2,11 @@ use dyn_any::StaticType; use dyn_clone::DynClone; -use dyn_any::DynAny; +use dyn_any::{DynAny, Upcast}; pub type Value = Box; -pub trait ValueTrait: DynAny<'static> + std::fmt::Debug + DynClone {} +pub trait ValueTrait: DynAny<'static> + Upcast> + std::fmt::Debug + DynClone {} pub trait IntoValue: Sized + ValueTrait + 'static { fn into_any(self) -> Value { @@ -14,7 +14,7 @@ pub trait IntoValue: Sized + ValueTrait + 'static { } } -impl ValueTrait for T {} +impl> + std::fmt::Debug + PartialEq + Clone> ValueTrait for T {} impl IntoValue for T {} diff --git a/node-graph/graph-craft/src/lib.rs b/node-graph/graph-craft/src/lib.rs index 718c6326..81e97560 100644 --- a/node-graph/graph-craft/src/lib.rs +++ b/node-graph/graph-craft/src/lib.rs @@ -1,4 +1,3 @@ -#![feature(trait_upcasting)] pub mod node_registry; pub mod document; diff --git a/node-graph/graph-craft/src/node_registry.rs b/node-graph/graph-craft/src/node_registry.rs index 03c372c5..afddfae5 100644 --- a/node-graph/graph-craft/src/node_registry.rs +++ b/node-graph/graph-craft/src/node_registry.rs @@ -13,6 +13,8 @@ use graphene_std::raster::Image; use crate::proto::Type; use crate::proto::{ConstructionArgs, NodeIdentifier, ProtoNode, ProtoNodeInput, Type::Concrete}; +use dyn_any::Upcast; + type NodeConstructor = fn(ProtoNode, &FixedSizeStack>); //TODO: turn into hasmap @@ -186,7 +188,8 @@ static NODE_REGISTRY: &[(NodeIdentifier<'static>, NodeConstructor)] = &[ |proto_node, stack| { stack.push_fn(|_nodes| { if let ConstructionArgs::Value(value) = proto_node.construction_args { - let node = FnNode::new(move |_| value.clone() as Any<'static>); + let node = FnNode::new(move |_| value.clone().up_box() as Any<'static>); + node.into_type_erased() } else { unreachable!() @@ -202,7 +205,7 @@ static NODE_REGISTRY: &[(NodeIdentifier<'static>, NodeConstructor)] = &[ |proto_node, stack| { stack.push_fn(|_nodes| { if let ConstructionArgs::Value(value) = proto_node.construction_args { - let node = FnNode::new(move |_| value.clone() as Any<'static>); + let node = FnNode::new(move |_| value.clone().up_box() as Any<'static>); node.into_type_erased() } else { unreachable!()