| 1 | use super::*; |
| 2 | use core::mem::transmute; |
| 3 | |
| 4 | /// A borrowed type with the same memory layout as the type itself that can be used to construct ABI-compatible function signatures. |
| 5 | #[repr (transparent)] |
| 6 | pub struct Ref<'a, T: Type<T>>(T::Abi, core::marker::PhantomData<&'a T>); |
| 7 | |
| 8 | impl<T: Type<T>> Ref<'_, T> { |
| 9 | /// Returns `true` if the argument is null. |
| 10 | pub fn is_null(&self) -> bool { |
| 11 | T::is_null(&self.0) |
| 12 | } |
| 13 | |
| 14 | /// Converts the argument to a [`Result<&T>`] reference. |
| 15 | pub fn ok(&self) -> Result<&T> { |
| 16 | self.as_ref() |
| 17 | .ok_or_else(|| Error::from_hresult(imp::E_POINTER)) |
| 18 | } |
| 19 | |
| 20 | /// Converts the argument to a [`Option<&T>`] reference. |
| 21 | pub fn as_ref(&self) -> Option<&T> { |
| 22 | if self.is_null() { |
| 23 | None |
| 24 | } else { |
| 25 | unsafe { Some(self.assume_init_ref()) } |
| 26 | } |
| 27 | } |
| 28 | |
| 29 | /// Converts the argument to a `&T` reference. |
| 30 | /// |
| 31 | /// # Panics |
| 32 | /// |
| 33 | /// Panics if the argument is null. |
| 34 | #[track_caller ] |
| 35 | pub fn unwrap(&self) -> &T { |
| 36 | self.as_ref().expect("called `Ref::unwrap` on a null value" ) |
| 37 | } |
| 38 | |
| 39 | /// Converts the argument to an [`Option<T>`] by cloning the reference. |
| 40 | pub fn cloned(&self) -> Option<T> { |
| 41 | self.as_ref().cloned() |
| 42 | } |
| 43 | |
| 44 | unsafe fn assume_init_ref(&self) -> &T { |
| 45 | unsafe { T::assume_init_ref(&self.0) } |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | impl<T: Type<T>> core::ops::Deref for Ref<'_, T> { |
| 50 | type Target = T::Default; |
| 51 | fn deref(&self) -> &Self::Target { |
| 52 | unsafe { transmute(&self.0) } |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | impl<'a, T: Type<T>> From<&'a T::Default> for Ref<'a, T> { |
| 57 | fn from(from: &'a T::Default) -> Self { |
| 58 | unsafe { core::mem::transmute_copy(src:from) } |
| 59 | } |
| 60 | } |
| 61 | |