use std::marker::PhantomData;
use std::mem::ManuallyDrop;
use crate::obj::{GodotClass, RawGd};
use crate::sys;
pub(crate) struct CastSuccess<T: GodotClass, U: GodotClass> {
_phantom: PhantomData<*mut T>,
dest: ManuallyDrop<RawGd<U>>,
}
impl<T: GodotClass, U: GodotClass> CastSuccess<T, U> {
pub(crate) fn from_weak(weak: RawGd<U>) -> CastSuccess<T, U>
where
U: GodotClass,
{
Self {
_phantom: PhantomData,
dest: ManuallyDrop::new(weak),
}
}
pub fn null() -> Self {
Self {
_phantom: PhantomData,
dest: ManuallyDrop::new(RawGd::null()),
}
}
#[cfg(safeguards_strict)] #[cfg_attr(published_docs, doc(cfg(safeguards_strict)))]
pub fn as_dest_ref(&self) -> &RawGd<U> {
self.check_validity();
&self.dest
}
pub fn as_dest_mut(&mut self) -> &mut RawGd<U> {
#[cfg(safeguards_strict)] #[cfg_attr(published_docs, doc(cfg(safeguards_strict)))]
self.check_validity();
&mut self.dest
}
pub fn into_dest(self, traded_source: RawGd<T>) -> RawGd<U> {
sys::strict_assert_eq!(
traded_source.instance_id_unchecked(),
self.dest.instance_id_unchecked(),
"traded_source must point to the same object as the destination"
);
#[cfg(safeguards_strict)] #[cfg_attr(published_docs, doc(cfg(safeguards_strict)))]
self.check_validity();
std::mem::forget(traded_source);
ManuallyDrop::into_inner(self.dest)
}
#[cfg(safeguards_strict)] #[cfg_attr(published_docs, doc(cfg(safeguards_strict)))]
fn check_validity(&self) {
assert!(self.dest.is_null() || self.dest.is_instance_valid());
}
}