Implement Upcasting without nightly support (#825)
This commit is contained in:
parent
4ec600957c
commit
ae7affda74
|
|
@ -5,8 +5,49 @@
|
||||||
#[cfg_attr(feature = "unstable-docs", doc(cfg(feature = "derive")))]
|
#[cfg_attr(feature = "unstable-docs", doc(cfg(feature = "derive")))]
|
||||||
pub use dyn_any_derive::DynAny;
|
pub use dyn_any_derive::DynAny;
|
||||||
|
|
||||||
|
/// Implement this trait for your `dyn Trait` types for all `T: Trait`
|
||||||
|
pub trait UpcastFrom<T: ?Sized> {
|
||||||
|
fn up_from(value: &T) -> &Self;
|
||||||
|
fn up_from_mut(value: &mut T) -> &mut Self;
|
||||||
|
fn up_from_box(value: Box<T>) -> Box<Self>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Use this trait to perform your upcasts on dyn traits. Make sure to require it in the supertrait!
|
||||||
|
pub trait Upcast<U: ?Sized> {
|
||||||
|
fn up(&self) -> &U;
|
||||||
|
fn up_mut(&mut self) -> &mut U;
|
||||||
|
fn up_box(self: Box<Self>) -> Box<U>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized, U: ?Sized> Upcast<U> for T
|
||||||
|
where
|
||||||
|
U: UpcastFrom<T>,
|
||||||
|
{
|
||||||
|
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<Self>) -> Box<U> {
|
||||||
|
U::up_from_box(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
use std::any::TypeId;
|
use std::any::TypeId;
|
||||||
|
|
||||||
|
impl<'a, T: DynAny<'a> + 'a> UpcastFrom<T> 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<T>) -> Box<Self> {
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait DynAny<'a> {
|
pub trait DynAny<'a> {
|
||||||
fn type_id(&self) -> TypeId;
|
fn type_id(&self) -> TypeId;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@ use dyn_any::StaticType;
|
||||||
|
|
||||||
use dyn_clone::DynClone;
|
use dyn_clone::DynClone;
|
||||||
|
|
||||||
use dyn_any::DynAny;
|
use dyn_any::{DynAny, Upcast};
|
||||||
|
|
||||||
pub type Value = Box<dyn ValueTrait>;
|
pub type Value = Box<dyn ValueTrait>;
|
||||||
|
|
||||||
pub trait ValueTrait: DynAny<'static> + std::fmt::Debug + DynClone {}
|
pub trait ValueTrait: DynAny<'static> + Upcast<dyn DynAny<'static>> + std::fmt::Debug + DynClone {}
|
||||||
|
|
||||||
pub trait IntoValue: Sized + ValueTrait + 'static {
|
pub trait IntoValue: Sized + ValueTrait + 'static {
|
||||||
fn into_any(self) -> Value {
|
fn into_any(self) -> Value {
|
||||||
|
|
@ -14,7 +14,7 @@ pub trait IntoValue: Sized + ValueTrait + 'static {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static + StaticType + std::fmt::Debug + PartialEq + Clone> ValueTrait for T {}
|
impl<T: 'static + StaticType + Upcast<dyn DynAny<'static>> + std::fmt::Debug + PartialEq + Clone> ValueTrait for T {}
|
||||||
|
|
||||||
impl<T: 'static + ValueTrait> IntoValue for T {}
|
impl<T: 'static + ValueTrait> IntoValue for T {}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
#![feature(trait_upcasting)]
|
|
||||||
pub mod node_registry;
|
pub mod node_registry;
|
||||||
|
|
||||||
pub mod document;
|
pub mod document;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ use graphene_std::raster::Image;
|
||||||
use crate::proto::Type;
|
use crate::proto::Type;
|
||||||
use crate::proto::{ConstructionArgs, NodeIdentifier, ProtoNode, ProtoNodeInput, Type::Concrete};
|
use crate::proto::{ConstructionArgs, NodeIdentifier, ProtoNode, ProtoNodeInput, Type::Concrete};
|
||||||
|
|
||||||
|
use dyn_any::Upcast;
|
||||||
|
|
||||||
type NodeConstructor = fn(ProtoNode, &FixedSizeStack<TypeErasedNode<'static>>);
|
type NodeConstructor = fn(ProtoNode, &FixedSizeStack<TypeErasedNode<'static>>);
|
||||||
|
|
||||||
//TODO: turn into hasmap
|
//TODO: turn into hasmap
|
||||||
|
|
@ -186,7 +188,8 @@ static NODE_REGISTRY: &[(NodeIdentifier<'static>, NodeConstructor)] = &[
|
||||||
|proto_node, stack| {
|
|proto_node, stack| {
|
||||||
stack.push_fn(|_nodes| {
|
stack.push_fn(|_nodes| {
|
||||||
if let ConstructionArgs::Value(value) = proto_node.construction_args {
|
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()
|
node.into_type_erased()
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
|
|
@ -202,7 +205,7 @@ static NODE_REGISTRY: &[(NodeIdentifier<'static>, NodeConstructor)] = &[
|
||||||
|proto_node, stack| {
|
|proto_node, stack| {
|
||||||
stack.push_fn(|_nodes| {
|
stack.push_fn(|_nodes| {
|
||||||
if let ConstructionArgs::Value(value) = proto_node.construction_args {
|
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()
|
node.into_type_erased()
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue