1use super::*;
2use 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)]
6pub struct Ref<'a, T: Type<T>>(T::Abi, core::marker::PhantomData<&'a T>);
7
8impl<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
49impl<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
56impl<'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