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 | |