mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-02 10:58:11 +08:00
Better downcast panics (#898)
This commit is contained in:
committed by
Keavon Chambers
parent
ef99c91226
commit
5b3c015f71
@@ -685,11 +685,7 @@ impl PortfolioMessageHandler {
|
|||||||
.0;
|
.0;
|
||||||
}
|
}
|
||||||
// If the input is just a value, return that value
|
// If the input is just a value, return that value
|
||||||
NodeInput::Value { tagged_value, .. } => {
|
NodeInput::Value { tagged_value, .. } => return dyn_any::downcast::<T>(tagged_value.clone().to_value().up_box()).map(|v| *v),
|
||||||
return dyn_any::downcast::<T>(tagged_value.clone().to_value().up_box())
|
|
||||||
.map(|v| *v)
|
|
||||||
.ok_or_else(|| "Incorrectly typed value".to_string())
|
|
||||||
}
|
|
||||||
// If the input is from a node, set the node to be the output (so that is what is evaluated)
|
// If the input is from a node, set the node to be the output (so that is what is evaluated)
|
||||||
NodeInput::Node(n) => {
|
NodeInput::Node(n) => {
|
||||||
inner_network.output = *n;
|
inner_network.output = *n;
|
||||||
@@ -717,7 +713,7 @@ impl PortfolioMessageHandler {
|
|||||||
|
|
||||||
let boxed = unsafe { stack.get().last().unwrap().eval(image.into_owned().into_dyn()) };
|
let boxed = unsafe { stack.get().last().unwrap().eval(image.into_owned().into_dyn()) };
|
||||||
|
|
||||||
dyn_any::downcast::<T>(boxed).map(|v| *v).ok_or_else(|| "Incorrectly typed output".to_string())
|
dyn_any::downcast::<T>(boxed).map(|v| *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encodes an image into a format using the image crate
|
/// Encodes an image into a format using the image crate
|
||||||
|
|||||||
@@ -82,22 +82,25 @@ pub fn downcast_ref<'a, V: StaticType>(i: &'a dyn DynAny<'a>) -> Option<&'a V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
pub fn downcast<'a, V: StaticType>(i: Box<dyn DynAny<'a> + 'a>) -> Option<Box<V>> {
|
pub fn downcast<'a, V: StaticType>(i: Box<dyn DynAny<'a> + 'a>) -> Result<Box<V>, String> {
|
||||||
let type_id = DynAny::type_id(i.as_ref());
|
let type_id = DynAny::type_id(i.as_ref());
|
||||||
if type_id == core::any::TypeId::of::<<V as StaticType>::Static>() {
|
if type_id == core::any::TypeId::of::<<V as StaticType>::Static>() {
|
||||||
// SAFETY: caller guarantees that T is the correct type
|
// SAFETY: caller guarantees that T is the correct type
|
||||||
let ptr = Box::into_raw(i) as *mut dyn DynAny<'a> as *mut V;
|
let ptr = Box::into_raw(i) as *mut dyn DynAny<'a> as *mut V;
|
||||||
Some(unsafe { Box::from_raw(ptr) })
|
Ok(unsafe { Box::from_raw(ptr) })
|
||||||
} else {
|
} else {
|
||||||
#[cfg(feature = "log-bad-types")]
|
|
||||||
{
|
|
||||||
log::error!("Tried to downcast a {} to a {}", DynAny::type_name(i.as_ref()), core::any::type_name::<V>());
|
|
||||||
}
|
|
||||||
|
|
||||||
if type_id == core::any::TypeId::of::<&dyn DynAny<'static>>() {
|
if type_id == core::any::TypeId::of::<&dyn DynAny<'static>>() {
|
||||||
panic!("downcast error: type_id == core::any::TypeId::of::<dyn DynAny<'a>>()");
|
panic!("downcast error: type_id == core::any::TypeId::of::<dyn DynAny<'a>>()");
|
||||||
}
|
}
|
||||||
None
|
#[cfg(feature = "log-bad-types")]
|
||||||
|
{
|
||||||
|
Err(format!("Incorrect type, expected {} but found {}", core::any::type_name::<V>(), DynAny::type_name(i.as_ref())))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "log-bad-types"))]
|
||||||
|
{
|
||||||
|
Err(format!("Incorrect type, expected {}", core::any::type_name::<V>()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ pub enum ImaginateStatus {
|
|||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||||
pub struct ImaginateBaseImage {
|
pub struct ImaginateBaseImage {
|
||||||
pub mime: String,
|
pub mime: String,
|
||||||
#[serde(rename = "imageData")]
|
#[cfg_attr(feature = "serde", serde(rename = "imageData"))]
|
||||||
pub image_data: Vec<u8>,
|
pub image_data: Vec<u8>,
|
||||||
pub size: DVec2,
|
pub size: DVec2,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,6 @@ use dyn_any::{DynAny, StaticType, StaticTypeSized};
|
|||||||
pub use graphene_core::{generic, ops /*, structural*/, Node, RefNode};
|
pub use graphene_core::{generic, ops /*, structural*/, Node, RefNode};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
fn fmt_error<I>() -> String {
|
|
||||||
format!("DynAnyNode: input is not of correct type, expected {}", std::any::type_name::<I>())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DynAnyNode<N, I: StaticType, O: StaticType, ORef: StaticType>(pub N, pub PhantomData<(I, O, ORef)>);
|
pub struct DynAnyNode<N, I: StaticType, O: StaticType, ORef: StaticType>(pub N, pub 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> {
|
/*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>;
|
type Output = Box<dyn dyn_any::DynAny<'n> + 'n>;
|
||||||
@@ -35,7 +31,7 @@ where
|
|||||||
{
|
{
|
||||||
type Output = Any<'n>;
|
type Output = Any<'n>;
|
||||||
fn eval(self, input: Any<'n>) -> Self::Output {
|
fn eval(self, input: Any<'n>) -> Self::Output {
|
||||||
let input: Box<I> = dyn_any::downcast(input).unwrap_or_else(|| panic!("{}", fmt_error::<I>()));
|
let input: Box<I> = dyn_any::downcast(input).expect("DynAnyNode Input");
|
||||||
Box::new(self.0.eval(*input))
|
Box::new(self.0.eval(*input))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,7 +41,7 @@ where
|
|||||||
{
|
{
|
||||||
type Output = Any<'n>;
|
type Output = Any<'n>;
|
||||||
fn eval(self, input: Any<'n>) -> Self::Output {
|
fn eval(self, input: Any<'n>) -> Self::Output {
|
||||||
let input: Box<I> = dyn_any::downcast(input).unwrap_or_else(|| panic!("{}", fmt_error::<I>()));
|
let input: Box<I> = dyn_any::downcast(input).expect("DynAnyNode Input");
|
||||||
Box::new((&self.0).eval_ref(*input))
|
Box::new((&self.0).eval_ref(*input))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,7 +128,7 @@ where
|
|||||||
type Output = O;
|
type Output = O;
|
||||||
fn eval(self, input: Any<'n>) -> Self::Output {
|
fn eval(self, input: Any<'n>) -> Self::Output {
|
||||||
let output = self.0.eval(input);
|
let output = self.0.eval(input);
|
||||||
*dyn_any::downcast(output).unwrap_or_else(|| panic!("DowncastNode: {}", fmt_error::<O>()))
|
*dyn_any::downcast(output).expect("DowncastNode Output")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'n, N, I: StaticType> DowncastNode<N, I>
|
impl<'n, N, I: StaticType> DowncastNode<N, I>
|
||||||
@@ -162,7 +158,7 @@ where
|
|||||||
fn eval(self, input: I) -> Self::Output {
|
fn eval(self, input: I) -> Self::Output {
|
||||||
let input = Box::new(input) as Box<dyn DynAny>;
|
let input = Box::new(input) as Box<dyn DynAny>;
|
||||||
let output = self.0.eval(input);
|
let output = self.0.eval(input);
|
||||||
*dyn_any::downcast(output).unwrap_or_else(|| panic!("DowncastBothNode Output: {}", fmt_error::<O>()))
|
*dyn_any::downcast(output).expect("DowncastBothNode Output")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'n, N, I: StaticType, O: StaticType> DowncastBothNode<N, I, O>
|
impl<'n, N, I: StaticType, O: StaticType> DowncastBothNode<N, I, O>
|
||||||
|
|||||||
Reference in New Issue
Block a user