use super::*;
use core::mem::transmute;
#[repr(transparent)]
pub struct Ref<'a, T: Type<T>>(T::Abi, core::marker::PhantomData<&'a T>);
impl<T: Type<T>> Ref<'_, T> {
pub fn is_null(&self) -> bool {
T::is_null(&self.0)
}
pub fn ok(&self) -> Result<&T> {
self.as_ref()
.ok_or_else(|| Error::from_hresult(imp::E_POINTER))
}
pub fn as_ref(&self) -> Option<&T> {
if self.is_null() {
None
} else {
unsafe { Some(self.assume_init_ref()) }
}
}
#[track_caller]
pub fn unwrap(&self) -> &T {
self.as_ref().expect("called `Ref::unwrap` on a null value")
}
pub fn cloned(&self) -> Option<T> {
self.as_ref().cloned()
}
unsafe fn assume_init_ref(&self) -> &T {
unsafe { T::assume_init_ref(&self.0) }
}
}
impl<T: Type<T>> Default for Ref<'_, T> {
fn default() -> Self {
unsafe { core::mem::zeroed() }
}
}
impl<T: Type<T>> core::ops::Deref for Ref<'_, T> {
type Target = T::Default;
fn deref(&self) -> &Self::Target {
unsafe { transmute(&self.0) }
}
}
impl<'a, T: Type<T, InterfaceType>> From<&'a Option<T>> for Ref<'a, T>
where
T: TypeKind<TypeKind = InterfaceType>,
{
fn from(from: &'a Option<T>) -> Self {
unsafe { core::mem::transmute_copy(from) }
}
}
impl<'a, T: Type<T, InterfaceType>> From<Option<&'a T>> for Ref<'a, T>
where
T: TypeKind<TypeKind = InterfaceType>,
{
fn from(from: Option<&'a T>) -> Self {
if let Some(from) = from {
unsafe { core::mem::transmute_copy(from) }
} else {
unsafe { core::mem::zeroed() }
}
}
}
impl<'a, T: Type<T>> From<&'a T> for Ref<'a, T> {
fn from(from: &'a T) -> Self {
unsafe { core::mem::transmute_copy(from) }
}
}