glib/subclass/
object_impl_ref.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{cmp, fmt, hash};
4
5use super::prelude::*;
6use crate::{
7    clone::{Downgrade, Upgrade},
8    prelude::*,
9    WeakRef,
10};
11
12// rustdoc-stripper-ignore-next
13/// Reference-counted wrapper around an [`ObjectSubclass`] reference.
14///
15/// This can be used for passing into closures as strong or weak reference without manually going
16/// from the implementation type to the instance type and back.
17pub struct ObjectImplRef<T: ObjectSubclass>(T::Type);
18
19unsafe impl<T: ObjectSubclass + Send + Sync> Send for ObjectImplRef<T> {}
20unsafe impl<T: ObjectSubclass + Send + Sync> Sync for ObjectImplRef<T> {}
21
22impl<T: ObjectSubclass> ObjectImplRef<T> {
23    // rustdoc-stripper-ignore-next
24    /// Create a new reference-counting wrapper around `imp`.
25    #[inline]
26    pub fn new(imp: &T) -> Self {
27        Self(imp.obj().clone())
28    }
29
30    // rustdoc-stripper-ignore-next
31    /// Downgrade to a weak reference.
32    ///
33    /// This can be upgraded to a strong reference again via [`ObjectImplWeakRef::upgrade`].
34    #[inline]
35    pub fn downgrade(&self) -> ObjectImplWeakRef<T> {
36        ObjectImplWeakRef(self.0.downgrade())
37    }
38}
39
40impl<T: ObjectSubclass> Clone for ObjectImplRef<T> {
41    #[inline]
42    fn clone(&self) -> Self {
43        Self(self.0.clone())
44    }
45}
46
47impl<T: ObjectSubclass> fmt::Debug for ObjectImplRef<T> {
48    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49        <T::Type as fmt::Debug>::fmt(&self.0, f)
50    }
51}
52
53impl<T: ObjectSubclass> std::ops::Deref for ObjectImplRef<T> {
54    type Target = T;
55
56    #[inline]
57    fn deref(&self) -> &Self::Target {
58        T::from_obj(&self.0)
59    }
60}
61
62impl<T: ObjectSubclass> Downgrade for ObjectImplRef<T> {
63    type Weak = ObjectImplWeakRef<T>;
64
65    #[inline]
66    fn downgrade(&self) -> Self::Weak {
67        self.downgrade()
68    }
69}
70
71impl<T: ObjectSubclass> PartialOrd for ObjectImplRef<T> {
72    #[inline]
73    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
74        Some(self.cmp(other))
75    }
76}
77
78impl<T: ObjectSubclass, OT: crate::object::ObjectType> PartialOrd<OT> for ObjectImplRef<T>
79where
80    T::Type: PartialOrd<OT>,
81{
82    #[inline]
83    fn partial_cmp(&self, other: &OT) -> Option<cmp::Ordering> {
84        self.0.partial_cmp(other)
85    }
86}
87
88impl<T: ObjectSubclass> Ord for ObjectImplRef<T> {
89    #[inline]
90    fn cmp(&self, other: &Self) -> cmp::Ordering {
91        self.0.cmp(&other.0)
92    }
93}
94
95impl<T: ObjectSubclass> PartialEq for ObjectImplRef<T> {
96    #[inline]
97    fn eq(&self, other: &Self) -> bool {
98        self.0 == other.0
99    }
100}
101
102impl<T: ObjectSubclass, OT: crate::object::ObjectType> PartialEq<OT> for ObjectImplRef<T>
103where
104    T::Type: PartialEq<OT>,
105{
106    #[inline]
107    fn eq(&self, other: &OT) -> bool {
108        self.0 == *other
109    }
110}
111
112impl<T: ObjectSubclass> Eq for ObjectImplRef<T> {}
113
114impl<T: ObjectSubclass> hash::Hash for ObjectImplRef<T> {
115    #[inline]
116    fn hash<H>(&self, state: &mut H)
117    where
118        H: hash::Hasher,
119    {
120        self.0.hash(state)
121    }
122}
123
124// rustdoc-stripper-ignore-next
125/// Weak reference to an [`ObjectSubclass`] reference.
126pub struct ObjectImplWeakRef<T: ObjectSubclass>(WeakRef<T::Type>);
127
128unsafe impl<T: ObjectSubclass + Send + Sync> Send for ObjectImplWeakRef<T> {}
129unsafe impl<T: ObjectSubclass + Send + Sync> Sync for ObjectImplWeakRef<T> {}
130
131impl<T: ObjectSubclass> ObjectImplWeakRef<T> {
132    // rustdoc-stripper-ignore-next
133    /// Upgrade to a strong reference, if possible.
134    ///
135    /// This will return `None` if the underlying object was freed in the meantime.
136    #[inline]
137    pub fn upgrade(&self) -> Option<ObjectImplRef<T>> {
138        let obj = self.0.upgrade()?;
139        Some(ObjectImplRef(obj))
140    }
141}
142
143impl<T: ObjectSubclass> Clone for ObjectImplWeakRef<T> {
144    #[inline]
145    fn clone(&self) -> Self {
146        Self(self.0.clone())
147    }
148}
149
150impl<T: ObjectSubclass> fmt::Debug for ObjectImplWeakRef<T> {
151    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
152        <crate::WeakRef<T::Type> as fmt::Debug>::fmt(&self.0, f)
153    }
154}
155
156impl<T: ObjectSubclass> Upgrade for ObjectImplWeakRef<T> {
157    type Strong = ObjectImplRef<T>;
158
159    #[inline]
160    fn upgrade(&self) -> Option<Self::Strong> {
161        self.upgrade()
162    }
163}