1use std::marker::PhantomData;
2
3use super::*;
4
5pub struct ReadOnlyVar<T, V>(PhantomData<T>, V);
7
8pub struct WeakReadOnlyVar<T, V>(PhantomData<T>, V);
10
11impl<T: VarValue, V: Var<T>> ReadOnlyVar<T, V> {
12 pub(super) fn new(var: V) -> Self {
13 ReadOnlyVar(PhantomData, var)
14 }
15}
16
17impl<T: VarValue, V: Var<T>> Clone for ReadOnlyVar<T, V> {
18 fn clone(&self) -> Self {
19 Self(PhantomData, self.1.clone())
20 }
21}
22
23impl<T: VarValue, V: WeakVar<T>> Clone for WeakReadOnlyVar<T, V> {
24 fn clone(&self) -> Self {
25 Self(PhantomData, self.1.clone())
26 }
27}
28
29impl<T: VarValue, V: Var<T>> crate::private::Sealed for ReadOnlyVar<T, V> {}
30impl<T: VarValue, V: WeakVar<T>> crate::private::Sealed for WeakReadOnlyVar<T, V> {}
31
32impl<T: VarValue, V: Var<T>> AnyVar for ReadOnlyVar<T, V> {
33 fn clone_any(&self) -> BoxedAnyVar {
34 Box::new(self.clone())
35 }
36
37 fn as_any(&self) -> &dyn Any {
38 self
39 }
40
41 fn as_unboxed_any(&self) -> &dyn Any {
42 self
43 }
44
45 fn double_boxed_any(self: Box<Self>) -> Box<dyn Any> {
46 let me: BoxedVar<T> = self;
47 Box::new(me)
48 }
49
50 fn var_type_id(&self) -> TypeId {
51 self.1.var_type_id()
52 }
53
54 fn get_any(&self) -> Box<dyn AnyVarValue> {
55 self.1.get_any()
56 }
57
58 fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
59 self.1.with_any(read)
60 }
61
62 fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
63 self.1.with_new_any(read)
64 }
65
66 fn set_any(&self, _: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
67 Err(VarIsReadOnlyError {
68 capabilities: self.capabilities(),
69 })
70 }
71
72 fn last_update(&self) -> VarUpdateId {
73 self.1.last_update()
74 }
75
76 fn is_contextual(&self) -> bool {
77 self.1.is_contextual()
78 }
79
80 fn capabilities(&self) -> VarCapability {
81 self.1.capabilities().as_read_only()
82 }
83
84 fn hook_any(&self, pos_modify_action: Box<dyn Fn(&AnyVarHookArgs) -> bool + Send + Sync>) -> VarHandle {
85 self.1.hook_any(pos_modify_action)
86 }
87
88 fn hook_animation_stop(&self, handler: Box<dyn FnOnce() + Send>) -> Result<(), Box<dyn FnOnce() + Send>> {
89 self.1.hook_animation_stop(handler)
90 }
91
92 fn strong_count(&self) -> usize {
93 self.1.strong_count()
94 }
95
96 fn weak_count(&self) -> usize {
97 self.1.weak_count()
98 }
99
100 fn actual_var_any(&self) -> BoxedAnyVar {
101 Box::new(self.clone())
102 }
103
104 fn downgrade_any(&self) -> BoxedAnyWeakVar {
105 Box::new(WeakReadOnlyVar(PhantomData, self.1.downgrade()))
106 }
107
108 fn is_animating(&self) -> bool {
109 self.1.is_animating()
110 }
111
112 fn modify_importance(&self) -> usize {
113 self.1.modify_importance()
114 }
115
116 fn var_ptr(&self) -> VarPtr {
117 self.1.var_ptr()
118 }
119
120 fn get_debug(&self) -> Txt {
121 self.with(var_debug)
122 }
123
124 fn update(&self) -> Result<(), VarIsReadOnlyError> {
125 Var::modify(self, var_update)
126 }
127
128 fn map_debug(&self) -> BoxedVar<Txt> {
129 Var::map(self, var_debug).boxed()
130 }
131}
132
133impl<T: VarValue, V: WeakVar<T>> AnyWeakVar for WeakReadOnlyVar<T, V> {
134 fn clone_any(&self) -> BoxedAnyWeakVar {
135 Box::new(self.clone())
136 }
137
138 fn strong_count(&self) -> usize {
139 self.1.strong_count()
140 }
141
142 fn weak_count(&self) -> usize {
143 self.1.weak_count()
144 }
145
146 fn upgrade_any(&self) -> Option<BoxedAnyVar> {
147 self.1.upgrade().map(|inner| Box::new(inner.read_only()) as _)
148 }
149
150 fn as_any(&self) -> &dyn Any {
151 self
152 }
153}
154
155impl<T: VarValue, V: Var<T>> IntoVar<T> for ReadOnlyVar<T, V> {
156 type Var = Self;
157
158 fn into_var(self) -> Self::Var {
159 self
160 }
161}
162
163impl<T: VarValue, V: Var<T>> Var<T> for ReadOnlyVar<T, V> {
164 type ReadOnly = Self;
165
166 type ActualVar = <V::ActualVar as Var<T>>::ReadOnly;
167
168 type Downgrade = WeakReadOnlyVar<T, V::Downgrade>;
169
170 type Map<O: VarValue> = V::Map<O>;
171 type MapBidi<O: VarValue> = V::Map<O>;
172
173 type FlatMap<O: VarValue, VF: Var<O>> = V::FlatMap<O, VF>;
174
175 type FilterMap<O: VarValue> = V::FilterMap<O>;
176 type FilterMapBidi<O: VarValue> = V::FilterMap<O>;
177
178 type MapRef<O: VarValue> = V::MapRef<O>;
179 type MapRefBidi<O: VarValue> = V::MapRef<O>;
180
181 type Easing = <V::Easing as Var<T>>::ReadOnly;
182
183 fn with<R, F>(&self, read: F) -> R
184 where
185 F: FnOnce(&T) -> R,
186 {
187 self.1.with(read)
188 }
189
190 fn modify<F>(&self, _: F) -> Result<(), VarIsReadOnlyError>
191 where
192 F: FnOnce(&mut VarModify<T>) + 'static,
193 {
194 Err(VarIsReadOnlyError {
195 capabilities: self.capabilities(),
196 })
197 }
198
199 fn boxed(self) -> BoxedVar<T>
200 where
201 Self: Sized,
202 {
203 Box::new(self)
204 }
205
206 fn actual_var(self) -> Self::ActualVar {
207 self.1.actual_var().read_only()
208 }
209
210 fn downgrade(&self) -> Self::Downgrade {
211 WeakReadOnlyVar(PhantomData, self.1.downgrade())
212 }
213
214 fn into_value(self) -> T {
215 self.1.into_value()
216 }
217
218 fn read_only(&self) -> Self::ReadOnly {
219 self.clone()
220 }
221
222 fn map<O, M>(&self, map: M) -> Self::Map<O>
223 where
224 O: VarValue,
225 M: FnMut(&T) -> O + Send + 'static,
226 {
227 self.1.map(map)
228 }
229
230 fn map_bidi<O, M, B>(&self, map: M, _: B) -> Self::MapBidi<O>
231 where
232 O: VarValue,
233 M: FnMut(&T) -> O + Send + 'static,
234 B: FnMut(&O) -> T + Send + 'static,
235 {
236 self.1.map(map)
237 }
238
239 fn flat_map<O, VF, M>(&self, map: M) -> Self::FlatMap<O, VF>
240 where
241 O: VarValue,
242 VF: Var<O>,
243 M: FnMut(&T) -> VF + Send + 'static,
244 {
245 self.1.flat_map(map)
246 }
247
248 fn filter_map<O, M, I>(&self, map: M, fallback: I) -> Self::FilterMap<O>
249 where
250 O: VarValue,
251 M: FnMut(&T) -> Option<O> + Send + 'static,
252 I: Fn() -> O + Send + Sync + 'static,
253 {
254 self.1.filter_map(map, fallback)
255 }
256
257 fn filter_map_bidi<O, M, B, I>(&self, map: M, _: B, fallback: I) -> Self::FilterMapBidi<O>
258 where
259 O: VarValue,
260 M: FnMut(&T) -> Option<O> + Send + 'static,
261 B: FnMut(&O) -> Option<T> + Send + 'static,
262 I: Fn() -> O + Send + Sync + 'static,
263 {
264 self.1.filter_map(map, fallback)
265 }
266
267 fn map_ref<O, M>(&self, map: M) -> Self::MapRef<O>
268 where
269 O: VarValue,
270 M: Fn(&T) -> &O + Send + Sync + 'static,
271 {
272 self.1.map_ref(map)
273 }
274
275 fn map_ref_bidi<O, M, B>(&self, map: M, _: B) -> Self::MapRefBidi<O>
276 where
277 O: VarValue,
278 M: Fn(&T) -> &O + Send + Sync + 'static,
279 B: Fn(&mut T) -> &mut O + Send + Sync + 'static,
280 {
281 self.1.map_ref(map)
282 }
283
284 fn easing<F>(&self, duration: Duration, easing: F) -> Self::Easing
285 where
286 T: Transitionable,
287 F: Fn(EasingTime) -> EasingStep + Send + Sync + 'static,
288 {
289 self.1.easing(duration, easing).read_only()
290 }
291
292 fn easing_with<F, S>(&self, duration: Duration, easing: F, sampler: S) -> Self::Easing
293 where
294 T: Transitionable,
295 F: Fn(EasingTime) -> EasingStep + Send + Sync + 'static,
296 S: Fn(&animation::Transition<T>, EasingStep) -> T + Send + Sync + 'static,
297 {
298 self.1.easing_with(duration, easing, sampler).read_only()
299 }
300}
301
302impl<T: VarValue, V: WeakVar<T>> WeakVar<T> for WeakReadOnlyVar<T, V> {
303 type Upgrade = <V::Upgrade as Var<T>>::ReadOnly;
304
305 fn upgrade(&self) -> Option<Self::Upgrade> {
306 self.1.upgrade().map(|inner| inner.read_only())
307 }
308}
309
310pub type ReadOnlyArcVar<T> = ReadOnlyVar<T, ArcVar<T>>;