1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
use crate::node::Node;
use std::any::TypeId;
pub fn downcast<T: Node + 'static>(node: &dyn Node) -> Option<&T> {
// Get `TypeId` of the type this function is instantiated with.
let t = TypeId::of::<T>();
// Get `TypeId` of the node we want to downcast.
let concrete = node.type_id();
// Compare both `TypeId`s on equality.
if t == concrete {
// Get the concrete type pointer from the trait object.
let concrete = node as *const dyn Node as *const T;
// Convert it to a reference and return it.
//
// SAFETY: This is safe because we know for sure that the pointer
// is valid and references are only handed out for the lifetime
// of the function.
let concrete = unsafe { &*concrete };
Some(concrete)
} else {
None
}
}
pub fn downcast_mut<T: Node>(node: &mut dyn Node) -> Option<&mut T> {
let t = TypeId::of::<T>();
let concrete = node.type_id();
if t == concrete {
let concrete = node as *mut dyn Node as *mut T;
let concrete = unsafe { &mut *concrete };
Some(concrete)
} else {
None
}
}