use crate::any::Variant;
use crate::engine::State;
use crate::stdlib::{
any::{Any, TypeId},
borrow::Cow,
boxed::Box,
mem, ptr,
string::ToString,
};
pub fn unsafe_try_cast<A: Any, B: Any>(a: A) -> Option<B> {
if TypeId::of::<B>() == a.type_id() {
unsafe {
let ret: B = ptr::read(&a as *const _ as *const B);
mem::forget(a);
Some(ret)
}
} else {
None
}
}
pub fn unsafe_cast_box<X: Variant, T: Variant>(item: Box<X>) -> Result<Box<T>, Box<X>> {
if TypeId::of::<X>() == TypeId::of::<T>() {
unsafe {
let raw: *mut dyn Any = Box::into_raw(item as Box<dyn Any>);
Ok(Box::from_raw(raw as *mut T))
}
} else {
Err(item)
}
}
pub fn unsafe_mut_cast_to_lifetime<'a, T>(value: &mut T) -> &'a mut T {
unsafe { mem::transmute::<_, &'a mut T>(value) }
}
pub fn unsafe_cast_var_name_to_lifetime<'s>(name: &str, state: &State) -> Cow<'s, str> {
if state.scope_level > 0 {
unsafe { mem::transmute::<_, &'s str>(name) }.into()
} else {
name.to_string().into()
}
}