makepad_stitch/
extern_ref.rs

1use {
2    crate::{
3        extern_::{Extern, UnguardedExtern},
4        store::{Store, StoreId},
5    },
6    std::any::Any,
7};
8
9/// A nullable reference to an external object.
10#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
11pub struct ExternRef(Option<Extern>);
12
13impl ExternRef {
14    /// Creates a new [`ExternRef`] wrapping the given underlying object.
15    pub fn new<T>(store: &mut Store, object: impl Into<Option<T>>) -> Self
16    where
17        T: Any + Send + Sync + 'static,
18    {
19        Self(object.into().map(|object| Extern::new(store, object)))
20    }
21
22    /// Creates a null [`ExternRef`].
23    pub fn null() -> Self {
24        Self(None)
25    }
26
27    /// Returns `true` if this [`ExternRef`] is null.
28    pub fn is_null(self) -> bool {
29        self.0.is_none()
30    }
31
32    /// Returns a reference to the underlying object if this `ExternRef` is not null.
33    pub fn get(self, store: &Store) -> Option<&dyn Any> {
34        self.0.as_ref().map(|extern_| extern_.get(store))
35    }
36
37    /// Converts the given [`UnguardedExternRef`] to a [`ExternRef`].
38    ///
39    /// # Safety
40    ///
41    /// The given [`UnguardedExternRef`] must be owned by the [`Store`] with the given [`StoreId`].
42    pub(crate) unsafe fn from_unguarded(extern_: UnguardedExternRef, store_id: StoreId) -> Self {
43        Self(extern_.map(|extern_| unsafe { Extern::from_unguarded(extern_, store_id) }))
44    }
45
46    /// Converts this [`ExternRef`] to an [`UnguardedExternRef`].
47    ///
48    /// # Panics
49    ///
50    /// This [`FuncRef`] is not owned by the [`Store`] with the given [`StoreId`].
51    pub(crate) fn to_unguarded(self, store_id: StoreId) -> UnguardedExternRef {
52        self.0.map(|extern_| extern_.to_unguarded(store_id))
53    }
54}
55
56/// An unguarded [`ExternRef`].
57pub(crate) type UnguardedExternRef = Option<UnguardedExtern>;