| 102 | |
| 103 | #[cfg(feature = "alloc")] |
| 104 | pub fn downcast<'a, V: StaticType + 'a>(i: Box<dyn DynAny<'a> + 'a>) -> Result<Box<V>, String> { |
| 105 | let type_id = DynAny::type_id(i.as_ref()); |
| 106 | if type_id == core::any::TypeId::of::<<V as StaticType>::Static>() { |
| 107 | // SAFETY: caller guarantees that T is the correct type |
| 108 | let ptr = Box::into_raw(i) as *mut V; |
| 109 | Ok(unsafe { Box::from_raw(ptr) }) |
| 110 | } else { |
| 111 | if type_id == core::any::TypeId::of::<&dyn DynAny<'static>>() { |
| 112 | panic!("downcast error: type_id == core::any::TypeId::of::<dyn DynAny<'a>>()"); |
| 113 | } |
| 114 | #[cfg(feature = "log-bad-types")] |
| 115 | { |
| 116 | Err(format!("Incorrect type, expected {} but found {}", core::any::type_name::<V>(), DynAny::type_name(i.as_ref()))) |
| 117 | } |
| 118 | |
| 119 | #[cfg(not(feature = "log-bad-types"))] |
| 120 | { |
| 121 | Err(format!("Incorrect type, expected {}", core::any::type_name::<V>())) |
| 122 | } |
| 123 | } |
| 124 | } |
| 125 | |
| 126 | pub unsafe trait StaticType { |
| 127 | type Static: 'static + ?Sized; |