1use std::sync::{Arc, Mutex, RwLock};
2use std::rc::Rc;
3use std::cell::RefCell;
4use std::any::Any;
5
6#[cfg(feature = "tagged_core")]
7use tagged_core::Tagged;
8
9pub trait WithContainer<Root, Value> {
13 fn with_arc<F, R>(self, arc: &Arc<Root>, f: F) -> R
16 where
17 F: FnOnce(&Value) -> R;
18
19 fn with_box<F, R>(self, boxed: &Box<Root>, f: F) -> R
22 where
23 F: FnOnce(&Value) -> R;
24
25 fn with_box_mut<F, R>(self, boxed: &mut Box<Root>, f: F) -> R
28 where
29 F: FnOnce(&mut Value) -> R;
30
31 fn with_rc<F, R>(self, rc: &Rc<Root>, f: F) -> R
34 where
35 F: FnOnce(&Value) -> R;
36
37 fn with_result<F, R, E>(self, result: &Result<Root, E>, f: F) -> Option<R>
40 where
41 F: FnOnce(&Value) -> R;
42
43 fn with_result_mut<F, R, E>(self, result: &mut Result<Root, E>, f: F) -> Option<R>
46 where
47 F: FnOnce(&mut Value) -> R;
48
49 fn with_option<F, R>(self, option: &Option<Root>, f: F) -> Option<R>
52 where
53 F: FnOnce(&Value) -> R;
54
55 fn with_option_mut<F, R>(self, option: &mut Option<Root>, f: F) -> Option<R>
58 where
59 F: FnOnce(&mut Value) -> R;
60
61 fn with_refcell<F, R>(self, refcell: &RefCell<Root>, f: F) -> Option<R>
64 where
65 F: FnOnce(&Value) -> R;
66
67 fn with_refcell_mut<F, R>(self, refcell: &RefCell<Root>, f: F) -> Option<R>
70 where
71 F: FnOnce(&mut Value) -> R;
72
73 #[cfg(feature = "tagged_core")]
76 fn with_tagged<F, R, Tag>(self, tagged: &Tagged<Root, Tag>, f: F) -> R
77 where
78 F: FnOnce(&Value) -> R;
79
80 fn with_mutex<F, R>(self, mutex: &Mutex<Root>, f: F) -> Option<R>
83 where
84 F: FnOnce(&Value) -> R;
85
86 fn with_mutex_mut<F, R>(self, mutex: &mut Mutex<Root>, f: F) -> Option<R>
89 where
90 F: FnOnce(&mut Value) -> R;
91
92 fn with_rwlock<F, R>(self, rwlock: &RwLock<Root>, f: F) -> Option<R>
95 where
96 F: FnOnce(&Value) -> R;
97
98 fn with_rwlock_mut<F, R>(self, rwlock: &mut RwLock<Root>, f: F) -> Option<R>
101 where
102 F: FnOnce(&mut Value) -> R;
103
104 fn with_arc_rwlock<F, R>(self, arc_rwlock: &Arc<RwLock<Root>>, f: F) -> Option<R>
107 where
108 F: FnOnce(&Value) -> R;
109
110 fn with_arc_rwlock_mut<F, R>(self, arc_rwlock: &Arc<RwLock<Root>>, f: F) -> Option<R>
113 where
114 F: FnOnce(&mut Value) -> R;
115}
116
117#[derive(Clone)]
118pub enum KeyPaths<Root, Value> {
121 Readable(Arc<dyn for<'a> Fn(&'a Root) -> &'a Value + Send + Sync>),
122 ReadableEnum {
123 extract: Arc<dyn for<'a> Fn(&'a Root) -> Option<&'a Value> + Send + Sync>,
124 embed: Arc<dyn Fn(Value) -> Root + Send + Sync>,
125 },
126 FailableReadable(Arc<dyn for<'a> Fn(&'a Root) -> Option<&'a Value> + Send + Sync>),
127
128 Writable(Arc<dyn for<'a> Fn(&'a mut Root) -> &'a mut Value + Send + Sync>),
129 FailableWritable(Arc<dyn for<'a> Fn(&'a mut Root) -> Option<&'a mut Value> + Send + Sync>),
130 WritableEnum {
131 extract: Arc<dyn for<'a> Fn(&'a Root) -> Option<&'a Value> + Send + Sync>,
132 extract_mut: Arc<dyn for<'a> Fn(&'a mut Root) -> Option<&'a mut Value> + Send + Sync>,
133 embed: Arc<dyn Fn(Value) -> Root + Send + Sync>,
134 },
135
136 ReferenceWritable(Arc<dyn for<'a> Fn(&'a mut Root) -> &'a mut Value + Send + Sync>),
138
139 Owned(Arc<dyn Fn(Root) -> Value + Send + Sync>),
141 FailableOwned(Arc<dyn Fn(Root) -> Option<Value> + Send + Sync>),
142}
143
144#[derive(Clone)]
148pub enum PartialKeyPath<Root> {
149 Readable(Arc<dyn for<'a> Fn(&'a Root) -> &'a (dyn Any + Send + Sync) + Send + Sync>),
150 ReadableEnum {
151 extract: Arc<dyn for<'a> Fn(&'a Root) -> Option<&'a (dyn Any + Send + Sync)> + Send + Sync>,
152 embed: Arc<dyn Fn(Box<dyn Any>) -> Root + Send + Sync>,
153 },
154 FailableReadable(Arc<dyn for<'a> Fn(&'a Root) -> Option<&'a (dyn Any + Send + Sync)> + Send + Sync>),
155
156 Writable(Arc<dyn for<'a> Fn(&'a mut Root) -> &'a mut (dyn Any + Send + Sync) + Send + Sync>),
157 FailableWritable(Arc<dyn for<'a> Fn(&'a mut Root) -> Option<&'a mut (dyn Any + Send + Sync)> + Send + Sync>),
158 WritableEnum {
159 extract: Arc<dyn for<'a> Fn(&'a Root) -> Option<&'a (dyn Any + Send + Sync)> + Send + Sync>,
160 extract_mut: Arc<dyn for<'a> Fn(&'a mut Root) -> Option<&'a mut (dyn Any + Send + Sync)> + Send + Sync>,
161 embed: Arc<dyn Fn(Box<dyn Any>) -> Root + Send + Sync>,
162 },
163
164 ReferenceWritable(Arc<dyn for<'a> Fn(&'a mut Root) -> &'a mut (dyn Any + Send + Sync) + Send + Sync>),
165
166 Owned(Arc<dyn Fn(Root) -> Box<dyn Any> + Send + Sync>),
167 FailableOwned(Arc<dyn Fn(Root) -> Option<Box<dyn Any>> + Send + Sync>),
168}
169
170#[derive(Clone)]
174pub enum AnyKeyPath {
175 Readable(Arc<dyn for<'a> Fn(&'a (dyn Any + Send + Sync)) -> &'a (dyn Any + Send + Sync) + Send + Sync>),
176 ReadableEnum {
177 extract: Arc<dyn for<'a> Fn(&'a (dyn Any + Send + Sync)) -> Option<&'a (dyn Any + Send + Sync)> + Send + Sync>,
178 embed: Arc<dyn Fn(Box<dyn Any>) -> Box<dyn Any> + Send + Sync>,
179 },
180 FailableReadable(Arc<dyn for<'a> Fn(&'a (dyn Any + Send + Sync)) -> Option<&'a (dyn Any + Send + Sync)> + Send + Sync>),
181
182 Writable(Arc<dyn for<'a> Fn(&'a mut (dyn Any + Send + Sync)) -> &'a mut (dyn Any + Send + Sync) + Send + Sync>),
183 FailableWritable(Arc<dyn for<'a> Fn(&'a mut (dyn Any + Send + Sync)) -> Option<&'a mut (dyn Any + Send + Sync)> + Send + Sync>),
184 WritableEnum {
185 extract: Arc<dyn for<'a> Fn(&'a (dyn Any + Send + Sync)) -> Option<&'a (dyn Any + Send + Sync)> + Send + Sync>,
186 extract_mut: Arc<dyn for<'a> Fn(&'a mut (dyn Any + Send + Sync)) -> Option<&'a mut (dyn Any + Send + Sync)> + Send + Sync>,
187 embed: Arc<dyn Fn(Box<dyn Any>) -> Box<dyn Any> + Send + Sync>,
188 },
189
190 ReferenceWritable(Arc<dyn for<'a> Fn(&'a mut (dyn Any + Send + Sync)) -> &'a mut (dyn Any + Send + Sync) + Send + Sync>),
191
192 Owned(Arc<dyn Fn(Box<dyn Any>) -> Box<dyn Any> + Send + Sync>),
193 FailableOwned(Arc<dyn Fn(Box<dyn Any>) -> Option<Box<dyn Any>> + Send + Sync>),
194}
195
196impl<Root, Value> KeyPaths<Root, Value> {
197 #[inline]
198 pub fn readable(get: impl for<'a> Fn(&'a Root) -> &'a Value + Send + Sync + 'static) -> Self {
199 Self::Readable(Arc::new(get))
200 }
201
202 #[inline]
203 pub fn writable(get_mut: impl for<'a> Fn(&'a mut Root) -> &'a mut Value + Send + Sync + 'static) -> Self {
204 Self::Writable(Arc::new(get_mut))
205 }
206
207 #[inline]
208 pub fn failable_readable(
209 get: impl for<'a> Fn(&'a Root) -> Option<&'a Value> + Send + Sync + 'static,
210 ) -> Self {
211 Self::FailableReadable(Arc::new(get))
212 }
213
214 #[inline]
215 pub fn failable_writable(
216 get_mut: impl for<'a> Fn(&'a mut Root) -> Option<&'a mut Value> + Send + Sync + 'static,
217 ) -> Self {
218 Self::FailableWritable(Arc::new(get_mut))
219 }
220
221 #[inline]
222 pub fn readable_enum(
223 embed: impl Fn(Value) -> Root + Send + Sync + 'static,
224 extract: impl for<'a> Fn(&'a Root) -> Option<&'a Value> + Send + Sync + 'static,
225 ) -> Self {
226 Self::ReadableEnum {
227 extract: Arc::new(extract),
228 embed: Arc::new(embed),
229 }
230 }
231
232 #[inline]
233 pub fn writable_enum(
234 embed: impl Fn(Value) -> Root + Send + Sync + 'static,
235 extract: impl for<'a> Fn(&'a Root) -> Option<&'a Value> + Send + Sync + 'static,
236 extract_mut: impl for<'a> Fn(&'a mut Root) -> Option<&'a mut Value> + Send + Sync + 'static,
237 ) -> Self {
238 Self::WritableEnum {
239 extract: Arc::new(extract),
240 embed: Arc::new(embed),
241 extract_mut: Arc::new(extract_mut),
242 }
243 }
244
245
246 #[inline]
248 pub fn owned(get: impl Fn(Root) -> Value + Send + Sync + 'static) -> Self {
249 Self::Owned(Arc::new(get))
250 }
251
252 #[inline]
253 pub fn failable_owned(get: impl Fn(Root) -> Option<Value> + Send + Sync + 'static) -> Self {
254 Self::FailableOwned(Arc::new(get))
255 }
256
257 #[inline]
258 pub fn owned_writable(get: impl Fn(Root) -> Value + Send + Sync + 'static) -> Self {
259 Self::Owned(Arc::new(get))
260 }
261
262 #[inline]
263 pub fn failable_owned_writable(get: impl Fn(Root) -> Option<Value> + Send + Sync + 'static) -> Self {
264 Self::FailableOwned(Arc::new(get))
265 }
266
267 #[inline]
268 pub fn reference_writable(get_mut: impl for<'a> Fn(&'a mut Root) -> &'a mut Value + Send + Sync + 'static) -> Self {
269 Self::ReferenceWritable(Arc::new(get_mut))
270 }
271
272 pub fn to_partial(self) -> PartialKeyPath<Root>
275 where
276 Root: 'static,
277 Value: 'static + Send + Sync,
278 {
279 match self {
280 KeyPaths::Readable(f) => PartialKeyPath::Readable(Arc::new(move |root| f(root) as &(dyn Any + Send + Sync))),
281 KeyPaths::Writable(f) => PartialKeyPath::Writable(Arc::new(move |root| f(root) as &mut (dyn Any + Send + Sync))),
282 KeyPaths::FailableReadable(f) => PartialKeyPath::FailableReadable(Arc::new(move |root| f(root).map(|v| v as &(dyn Any + Send + Sync)))),
283 KeyPaths::FailableWritable(f) => PartialKeyPath::FailableWritable(Arc::new(move |root| f(root).map(|v| v as &mut (dyn Any + Send + Sync)))),
284 KeyPaths::ReadableEnum { extract, embed } => PartialKeyPath::ReadableEnum {
285 extract: Arc::new(move |root| extract(root).map(|v| v as &(dyn Any + Send + Sync))),
286 embed: Arc::new(move |value| embed(*value.downcast::<Value>().unwrap())),
287 },
288 KeyPaths::WritableEnum { extract, extract_mut, embed } => PartialKeyPath::WritableEnum {
289 extract: Arc::new(move |root| extract(root).map(|v| v as &(dyn Any + Send + Sync))),
290 extract_mut: Arc::new(move |root| extract_mut(root).map(|v| v as &mut (dyn Any + Send + Sync))),
291 embed: Arc::new(move |value| embed(*value.downcast::<Value>().unwrap())),
292 },
293 KeyPaths::ReferenceWritable(f) => PartialKeyPath::ReferenceWritable(Arc::new(move |root| f(root) as &mut (dyn Any + Send + Sync))),
294 KeyPaths::Owned(f) => PartialKeyPath::Owned(Arc::new(move |root| Box::new(f(root)) as Box<dyn Any>)),
295 KeyPaths::FailableOwned(f) => PartialKeyPath::FailableOwned(Arc::new(move |root| f(root).map(|v| Box::new(v) as Box<dyn Any>))),
296 }
297 }
298
299 pub fn to_any(self) -> AnyKeyPath
302 where
303 Root: 'static + Send + Sync,
304 Value: 'static + Send + Sync,
305 {
306 match self {
307 KeyPaths::Readable(f) => AnyKeyPath::Readable(Arc::new(move |root| {
308 let typed_root = root.downcast_ref::<Root>().unwrap();
309 f(typed_root) as &(dyn Any + Send + Sync)
310 })),
311 KeyPaths::Writable(f) => AnyKeyPath::Writable(Arc::new(move |root| {
312 let typed_root = root.downcast_mut::<Root>().unwrap();
313 f(typed_root) as &mut (dyn Any + Send + Sync)
314 })),
315 KeyPaths::FailableReadable(f) => AnyKeyPath::FailableReadable(Arc::new(move |root| {
316 let typed_root = root.downcast_ref::<Root>().unwrap();
317 f(typed_root).map(|v| v as &(dyn Any + Send + Sync))
318 })),
319 KeyPaths::FailableWritable(f) => AnyKeyPath::FailableWritable(Arc::new(move |root| {
320 let typed_root = root.downcast_mut::<Root>().unwrap();
321 f(typed_root).map(|v| v as &mut (dyn Any + Send + Sync))
322 })),
323 KeyPaths::ReadableEnum { extract, embed } => AnyKeyPath::ReadableEnum {
324 extract: Arc::new(move |root| {
325 let typed_root = root.downcast_ref::<Root>().unwrap();
326 extract(typed_root).map(|v| v as &(dyn Any + Send + Sync))
327 }),
328 embed: Arc::new(move |value| {
329 let typed_value = *value.downcast::<Value>().unwrap();
330 Box::new(embed(typed_value)) as Box<dyn Any>
331 }),
332 },
333 KeyPaths::WritableEnum { extract, extract_mut, embed } => AnyKeyPath::WritableEnum {
334 extract: Arc::new(move |root| {
335 let typed_root = root.downcast_ref::<Root>().unwrap();
336 extract(typed_root).map(|v| v as &(dyn Any + Send + Sync))
337 }),
338 extract_mut: Arc::new(move |root| {
339 let typed_root = root.downcast_mut::<Root>().unwrap();
340 extract_mut(typed_root).map(|v| v as &mut (dyn Any + Send + Sync))
341 }),
342 embed: Arc::new(move |value| {
343 let typed_value = *value.downcast::<Value>().unwrap();
344 Box::new(embed(typed_value)) as Box<dyn Any>
345 }),
346 },
347 KeyPaths::ReferenceWritable(f) => AnyKeyPath::ReferenceWritable(Arc::new(move |root| {
348 let typed_root = root.downcast_mut::<Root>().unwrap();
349 f(typed_root) as &mut (dyn Any + Send + Sync)
350 })),
351 KeyPaths::Owned(f) => AnyKeyPath::Owned(Arc::new(move |root| {
352 let typed_root = *root.downcast::<Root>().unwrap();
353 Box::new(f(typed_root)) as Box<dyn Any>
354 })),
355 KeyPaths::FailableOwned(f) => AnyKeyPath::FailableOwned(Arc::new(move |root| {
356 let typed_root = *root.downcast::<Root>().unwrap();
357 f(typed_root).map(|v| Box::new(v) as Box<dyn Any>)
358 })),
359 }
360 }
361
362 #[inline]
372 pub fn extract_from_ref_slice<'a>(&self, slice: &'a [&Root]) -> Vec<&'a Value>
373 where
374 Root: 'static,
375 Value: 'static,
376 {
377 match self {
378 KeyPaths::Readable(f) => {
379 slice.iter().map(|item| f(item)).collect()
380 }
381 KeyPaths::FailableReadable(f) => {
382 slice.iter().filter_map(|item| f(item)).collect()
383 }
384 KeyPaths::ReadableEnum { extract, .. } => {
385 slice.iter().filter_map(|item| extract(item)).collect()
386 }
387 _ => panic!("extract_from_ref_slice only works with readable keypaths"),
388 }
389 }
390
391 #[inline]
401 pub fn extract_mut_from_ref_slice<'a>(&self, slice: &'a mut [&mut Root]) -> Vec<&'a mut Value>
402 where
403 Root: 'static,
404 Value: 'static,
405 {
406 match self {
407 KeyPaths::Writable(f) => {
408 slice.iter_mut().map(|item| f(item)).collect()
409 }
410 KeyPaths::FailableWritable(f) => {
411 slice.iter_mut().filter_map(|item| f(item)).collect()
412 }
413 KeyPaths::WritableEnum { extract_mut, .. } => {
414 slice.iter_mut().filter_map(|item| extract_mut(item)).collect()
415 }
416 _ => panic!("extract_mut_from_ref_slice only works with writable keypaths"),
417 }
418 }
419}
420
421impl<Root, Value> KeyPaths<Root, Value> {
422 #[inline]
424 pub fn get<'a>(&'a self, root: &'a Root) -> Option<&'a Value> {
425 match self {
426 KeyPaths::Readable(f) => Some(f(root)),
427 KeyPaths::Writable(_) => None, KeyPaths::FailableReadable(f) => f(root),
429 KeyPaths::FailableWritable(_) => None, KeyPaths::ReadableEnum { extract, .. } => extract(root),
431 KeyPaths::WritableEnum { extract, .. } => extract(root),
432 KeyPaths::ReferenceWritable(_) => None, KeyPaths::Owned(_) => None, KeyPaths::FailableOwned(_) => None, }
437 }
438
439 #[inline]
442 pub fn get_ref<'a, 'b>(&'a self, root: &'b &Root) -> Option<&'b Value>
443 where
444 'a: 'b,
445 {
446 match self {
447 KeyPaths::Readable(f) => Some(f(*root)),
448 KeyPaths::Writable(_) => None, KeyPaths::FailableReadable(f) => f(*root),
450 KeyPaths::FailableWritable(_) => None, KeyPaths::ReadableEnum { extract, .. } => extract(*root),
452 KeyPaths::WritableEnum { extract, .. } => extract(*root),
453 KeyPaths::ReferenceWritable(_) => None, KeyPaths::Owned(_) => None, KeyPaths::FailableOwned(_) => None, }
458 }
459
460 #[inline]
462 pub fn get_mut<'a>(&'a self, root: &'a mut Root) -> Option<&'a mut Value> {
463 match self {
464 KeyPaths::Readable(_) => None, KeyPaths::Writable(f) => Some(f(root)),
466 KeyPaths::FailableReadable(_) => None, KeyPaths::FailableWritable(f) => f(root),
468 KeyPaths::ReadableEnum { .. } => None, KeyPaths::WritableEnum { extract_mut, .. } => extract_mut(root),
470 KeyPaths::ReferenceWritable(f) => Some(f(root)),
471 KeyPaths::Owned(_) => None, KeyPaths::FailableOwned(_) => None, }
475 }
476
477 #[inline]
480 pub fn get_mut_ref<'a, 'b>(&'a self, root: &'b mut &mut Root) -> Option<&'b mut Value>
481 where
482 'a: 'b,
483 {
484 match self {
485 KeyPaths::Readable(_) => None, KeyPaths::Writable(f) => Some(f(*root)),
487 KeyPaths::FailableReadable(_) => None, KeyPaths::FailableWritable(f) => f(*root),
489 KeyPaths::ReadableEnum { .. } => None, KeyPaths::WritableEnum { extract_mut, .. } => extract_mut(*root),
491 KeyPaths::ReferenceWritable(f) => Some(f(*root)),
492 KeyPaths::Owned(_) => None, KeyPaths::FailableOwned(_) => None, }
496 }
497
498 #[inline]
505 pub fn for_arc(self) -> KeyPaths<Arc<Root>, Value>
506 where
507 Root: 'static,
508 Value: 'static,
509 {
510 match self {
511 KeyPaths::Readable(f) => KeyPaths::Readable(Arc::new(move |root: &Arc<Root>| {
512 f(&**root)
513 })),
514 KeyPaths::Writable(_) => {
515 panic!("Cannot create writable keypath for Arc (Arc is immutable)")
517 }
518 KeyPaths::FailableReadable(f) => {
519 KeyPaths::FailableReadable(Arc::new(move |root: &Arc<Root>| f(&**root)))
520 }
521 KeyPaths::ReadableEnum { extract, embed } => KeyPaths::ReadableEnum {
522 extract: Arc::new(move |root: &Arc<Root>| extract(&**root)),
523 embed: Arc::new(move |value| Arc::new(embed(value))),
524 },
525 other => panic!("Unsupported keypath variant for Arc adapter: {:?}", kind_name(&other)),
526 }
527 }
528
529 #[inline]
538 pub fn extract_from_slice<'a>(&self, slice: &'a [Root]) -> Vec<&'a Value>
539 where
540 Root: 'static,
541 Value: 'static,
542 {
543 match self {
544 KeyPaths::Readable(f) => {
545 slice.iter().map(|item| f(item)).collect()
546 }
547 KeyPaths::FailableReadable(f) => {
548 slice.iter().filter_map(|item| f(item)).collect()
549 }
550 KeyPaths::ReadableEnum { extract, .. } => {
551 slice.iter().filter_map(|item| extract(item)).collect()
552 }
553 _ => panic!("extract_from_slice only works with readable keypaths"),
554 }
555 }
556
557 #[inline]
566 pub fn extract_from_iter<'a, I>(&self, iter: I) -> Vec<&'a Value>
567 where
568 I: Iterator<Item = &'a Root>,
569 Root: 'static,
570 Value: 'static,
571 {
572 match self {
573 KeyPaths::Readable(f) => {
574 iter.map(|item| f(item)).collect()
575 }
576 KeyPaths::FailableReadable(f) => {
577 iter.filter_map(|item| f(item)).collect()
578 }
579 KeyPaths::ReadableEnum { extract, .. } => {
580 iter.filter_map(|item| extract(item)).collect()
581 }
582 _ => panic!("extract_from_iter only works with readable keypaths"),
583 }
584 }
585
586 #[inline]
595 pub fn extract_mut_from_slice<'a>(&self, slice: &'a mut [Root]) -> Vec<&'a mut Value>
596 where
597 Root: 'static,
598 Value: 'static,
599 {
600 match self {
601 KeyPaths::Writable(f) => {
602 slice.iter_mut().map(|item| f(item)).collect()
603 }
604 KeyPaths::FailableWritable(f) => {
605 slice.iter_mut().filter_map(|item| f(item)).collect()
606 }
607 KeyPaths::WritableEnum { extract_mut, .. } => {
608 slice.iter_mut().filter_map(|item| extract_mut(item)).collect()
609 }
610 _ => panic!("extract_mut_from_slice only works with writable keypaths"),
611 }
612 }
613
614 #[inline]
617 pub fn for_box(self) -> KeyPaths<Box<Root>, Value>
618 where
619 Root: 'static,
620 Value: 'static,
621 {
622 match self {
623 KeyPaths::Readable(f) => KeyPaths::Readable(Arc::new(move |root: &Box<Root>| {
624 f(&**root)
625 })),
626 KeyPaths::Writable(f) => KeyPaths::Writable(Arc::new(move |root: &mut Box<Root>| {
627 f(&mut **root)
628 })),
629 KeyPaths::FailableReadable(f) => {
630 KeyPaths::FailableReadable(Arc::new(move |root: &Box<Root>| f(&**root)))
631 }
632 KeyPaths::FailableWritable(f) => {
633 KeyPaths::FailableWritable(Arc::new(move |root: &mut Box<Root>| f(&mut **root)))
634 }
635 KeyPaths::ReadableEnum { extract, embed } => KeyPaths::ReadableEnum {
636 extract: Arc::new(move |root: &Box<Root>| extract(&**root)),
637 embed: Arc::new(move |value| Box::new(embed(value))),
638 },
639 KeyPaths::WritableEnum { extract, extract_mut, embed } => KeyPaths::WritableEnum {
640 extract: Arc::new(move |root: &Box<Root>| extract(&**root)),
641 extract_mut: Arc::new(move |root: &mut Box<Root>| extract_mut(&mut **root)),
642 embed: Arc::new(move |value| Box::new(embed(value))),
643 },
644 other => panic!("Unsupported keypath variant for Box adapter: {:?}", kind_name(&other)),
645 }
646 }
647
648 #[inline]
651 pub fn for_rc(self) -> KeyPaths<Rc<Root>, Value>
652 where
653 Root: 'static,
654 Value: 'static,
655 {
656 match self {
657 KeyPaths::Readable(f) => KeyPaths::Readable(Arc::new(move |root: &Rc<Root>| {
658 f(&**root)
659 })),
660 KeyPaths::Writable(_) => {
661 panic!("Cannot create writable keypath for Rc (Rc is immutable)")
663 }
664 KeyPaths::FailableReadable(f) => {
665 KeyPaths::FailableReadable(Arc::new(move |root: &Rc<Root>| f(&**root)))
666 }
667 KeyPaths::ReadableEnum { extract, embed } => KeyPaths::ReadableEnum {
668 extract: Arc::new(move |root: &Rc<Root>| extract(&**root)),
669 embed: Arc::new(move |value| Rc::new(embed(value))),
670 },
671 other => panic!("Unsupported keypath variant for Rc adapter: {:?}", kind_name(&other)),
672 }
673 }
674
675 #[inline]
679 pub fn for_result<E>(self) -> KeyPaths<Result<Root, E>, Value>
680 where
681 Root: 'static,
682 Value: 'static,
683 E: 'static,
684 {
685 match self {
686 KeyPaths::Readable(f) => KeyPaths::FailableReadable(Arc::new(move |root: &Result<Root, E>| {
687 root.as_ref().ok().map(|r| f(r))
688 })),
689 KeyPaths::Writable(f) => KeyPaths::FailableWritable(Arc::new(move |root: &mut Result<Root, E>| {
690 root.as_mut().ok().map(|r| f(r))
691 })),
692 KeyPaths::FailableReadable(f) => {
693 KeyPaths::FailableReadable(Arc::new(move |root: &Result<Root, E>| {
694 root.as_ref().ok().and_then(|r| f(r))
695 }))
696 }
697 KeyPaths::FailableWritable(f) => {
698 KeyPaths::FailableWritable(Arc::new(move |root: &mut Result<Root, E>| {
699 root.as_mut().ok().and_then(|r| f(r))
700 }))
701 }
702 KeyPaths::ReadableEnum { extract, embed } => KeyPaths::ReadableEnum {
703 extract: Arc::new(move |root: &Result<Root, E>| {
704 root.as_ref().ok().and_then(|r| extract(r))
705 }),
706 embed: Arc::new(move |value| Ok(embed(value))),
707 },
708 KeyPaths::WritableEnum { extract, extract_mut, embed } => KeyPaths::WritableEnum {
709 extract: Arc::new(move |root: &Result<Root, E>| {
710 root.as_ref().ok().and_then(|r| extract(r))
711 }),
712 extract_mut: Arc::new(move |root: &mut Result<Root, E>| {
713 root.as_mut().ok().and_then(|r| extract_mut(r))
714 }),
715 embed: Arc::new(move |value| Ok(embed(value))),
716 },
717 other => panic!("Unsupported keypath variant for Result adapter: {:?}", kind_name(&other)),
718 }
719 }
720
721 #[inline]
725 pub fn for_option(self) -> KeyPaths<Option<Root>, Value>
726 where
727 Root: 'static,
728 Value: 'static,
729 {
730 match self {
731 KeyPaths::Readable(f) => KeyPaths::FailableReadable(Arc::new(move |root: &Option<Root>| {
732 root.as_ref().map(|r| f(r))
733 })),
734 KeyPaths::Writable(f) => KeyPaths::FailableWritable(Arc::new(move |root: &mut Option<Root>| {
735 root.as_mut().map(|r| f(r))
736 })),
737 KeyPaths::FailableReadable(f) => {
738 KeyPaths::FailableReadable(Arc::new(move |root: &Option<Root>| {
739 root.as_ref().and_then(|r| f(r))
740 }))
741 }
742 KeyPaths::FailableWritable(f) => {
743 KeyPaths::FailableWritable(Arc::new(move |root: &mut Option<Root>| {
744 root.as_mut().and_then(|r| f(r))
745 }))
746 }
747 KeyPaths::ReadableEnum { extract, embed } => KeyPaths::ReadableEnum {
748 extract: Arc::new(move |root: &Option<Root>| {
749 root.as_ref().and_then(|r| extract(r))
750 }),
751 embed: Arc::new(move |value| Some(embed(value))),
752 },
753 KeyPaths::WritableEnum { extract, extract_mut, embed } => KeyPaths::WritableEnum {
754 extract: Arc::new(move |root: &Option<Root>| {
755 root.as_ref().and_then(|r| extract(r))
756 }),
757 extract_mut: Arc::new(move |root: &mut Option<Root>| {
758 root.as_mut().and_then(|r| extract_mut(r))
759 }),
760 embed: Arc::new(move |value| Some(embed(value))),
761 },
762 other => panic!("Unsupported keypath variant for Option adapter: {:?}", kind_name(&other)),
763 }
764 }
765
766 #[inline]
770 pub fn for_arc_rwlock(self) -> KeyPaths<Arc<RwLock<Root>>, Value>
771 where
772 Root: 'static,
773 Value: Clone + 'static,
774 {
775 match self {
776 KeyPaths::Readable(f) => KeyPaths::FailableOwned(Arc::new(move |root: Arc<RwLock<Root>>| {
777 let guard = root.read().ok()?;
778 Some(f(&*guard).clone())
779 })),
780 KeyPaths::Writable(_) => {
781 panic!("Cannot create writable keypath for Arc<RwLock> (use with_arc_rwlock_mut instead)")
783 }
784 KeyPaths::FailableReadable(f) => {
785 KeyPaths::FailableOwned(Arc::new(move |root: Arc<RwLock<Root>>| {
786 let guard = root.read().ok()?;
787 f(&*guard).map(|v| v.clone())
788 }))
789 }
790 KeyPaths::ReadableEnum { extract, embed: _ } => KeyPaths::FailableOwned(Arc::new(move |root: Arc<RwLock<Root>>| {
791 let guard = root.read().ok()?;
792 extract(&*guard).map(|v| v.clone())
793 })),
794 other => panic!("Unsupported keypath variant for Arc<RwLock> adapter: {:?}", kind_name(&other)),
795 }
796 }
797
798 #[inline]
802 pub fn for_arc_mutex(self) -> KeyPaths<Arc<Mutex<Root>>, Value>
803 where
804 Root: 'static,
805 Value: Clone + 'static,
806 {
807 match self {
808 KeyPaths::Readable(f) => KeyPaths::FailableOwned(Arc::new(move |root: Arc<Mutex<Root>>| {
809 let guard = root.lock().ok()?;
810 Some(f(&*guard).clone())
811 })),
812 KeyPaths::Writable(_) => {
813 panic!("Cannot create writable keypath for Arc<Mutex> (use with_arc_mutex_mut instead)")
815 }
816 KeyPaths::FailableReadable(f) => {
817 KeyPaths::FailableOwned(Arc::new(move |root: Arc<Mutex<Root>>| {
818 let guard = root.lock().ok()?;
819 f(&*guard).map(|v| v.clone())
820 }))
821 }
822 KeyPaths::ReadableEnum { extract, embed: _ } => KeyPaths::FailableOwned(Arc::new(move |root: Arc<Mutex<Root>>| {
823 let guard = root.lock().ok()?;
824 extract(&*guard).map(|v| v.clone())
825 })),
826 other => panic!("Unsupported keypath variant for Arc<Mutex> adapter: {:?}", kind_name(&other)),
827 }
828 }
829
830 #[cfg(feature = "parking_lot")]
835 #[inline]
836 pub fn for_arc_parking_mutex(self) -> KeyPaths<Arc<parking_lot::Mutex<Root>>, Value>
837 where
838 Root: 'static,
839 Value: Clone + 'static,
840 {
841 match self {
842 KeyPaths::Readable(f) => KeyPaths::FailableOwned(Arc::new(move |root: Arc<parking_lot::Mutex<Root>>| {
843 let guard = root.lock();
844 Some(f(&*guard).clone())
845 })),
846 KeyPaths::Writable(_) => {
847 panic!("Cannot create writable keypath for Arc<parking_lot::Mutex> (use with_arc_parking_mutex_mut instead)")
849 }
850 KeyPaths::FailableReadable(f) => {
851 KeyPaths::FailableOwned(Arc::new(move |root: Arc<parking_lot::Mutex<Root>>| {
852 let guard = root.lock();
853 f(&*guard).map(|v| v.clone())
854 }))
855 }
856 KeyPaths::ReadableEnum { extract, embed: _ } => KeyPaths::FailableOwned(Arc::new(move |root: Arc<parking_lot::Mutex<Root>>| {
857 let guard = root.lock();
858 extract(&*guard).map(|v| v.clone())
859 })),
860 other => panic!("Unsupported keypath variant for Arc<parking_lot::Mutex> adapter: {:?}", kind_name(&other)),
861 }
862 }
863
864 #[cfg(feature = "parking_lot")]
869 #[inline]
870 pub fn for_arc_parking_rwlock(self) -> KeyPaths<Arc<parking_lot::RwLock<Root>>, Value>
871 where
872 Root: 'static,
873 Value: Clone + 'static,
874 {
875 match self {
876 KeyPaths::Readable(f) => KeyPaths::FailableOwned(Arc::new(move |root: Arc<parking_lot::RwLock<Root>>| {
877 let guard = root.read();
878 Some(f(&*guard).clone())
879 })),
880 KeyPaths::Writable(_) => {
881 panic!("Cannot create writable keypath for Arc<parking_lot::RwLock> (use with_arc_parking_rwlock_mut instead)")
883 }
884 KeyPaths::FailableReadable(f) => {
885 KeyPaths::FailableOwned(Arc::new(move |root: Arc<parking_lot::RwLock<Root>>| {
886 let guard = root.read();
887 f(&*guard).map(|v| v.clone())
888 }))
889 }
890 KeyPaths::ReadableEnum { extract, embed: _ } => KeyPaths::FailableOwned(Arc::new(move |root: Arc<parking_lot::RwLock<Root>>| {
891 let guard = root.read();
892 extract(&*guard).map(|v| v.clone())
893 })),
894 other => panic!("Unsupported keypath variant for Arc<parking_lot::RwLock> adapter: {:?}", kind_name(&other)),
895 }
896 }
897
898 #[cfg(feature = "tagged_core")]
903 #[inline]
904 pub fn for_tagged<Tag>(self) -> KeyPaths<Tagged<Root, Tag>, Value>
905 where
906 Root: Clone + 'static,
907 Value: 'static,
908 Tag: 'static,
909 {
910 match self {
911 KeyPaths::Readable(f) => KeyPaths::Readable(Arc::new(move |root: &Tagged<Root, Tag>| {
912 f(&**root)
913 })),
914 KeyPaths::Writable(_) => {
915 panic!("Tagged does not support writable keypaths (Tagged only implements Deref, not DerefMut)")
916 }
917 KeyPaths::FailableReadable(f) => KeyPaths::FailableReadable(Arc::new(move |root: &Tagged<Root, Tag>| {
918 f(&**root)
919 })),
920 KeyPaths::FailableWritable(_) => {
921 panic!("Tagged does not support writable keypaths (Tagged only implements Deref, not DerefMut)")
922 }
923 KeyPaths::ReadableEnum { extract, embed } => KeyPaths::ReadableEnum {
924 extract: Arc::new(move |root: &Tagged<Root, Tag>| {
925 extract(&**root)
926 }),
927 embed: Arc::new(move |value: Value| {
928 Tagged::new(embed(value))
929 }),
930 },
931 KeyPaths::WritableEnum { .. } => {
932 panic!("Tagged does not support writable keypaths (Tagged only implements Deref, not DerefMut)")
933 }
934 KeyPaths::ReferenceWritable(_) => {
935 panic!("Tagged does not support writable keypaths (Tagged only implements Deref, not DerefMut)")
936 }
937 KeyPaths::Owned(f) => KeyPaths::Owned(Arc::new(move |root: Tagged<Root, Tag>| {
938 f((*root).clone())
940 })),
941 KeyPaths::FailableOwned(f) => KeyPaths::FailableOwned(Arc::new(move |root: Tagged<Root, Tag>| {
942 f((*root).clone())
943 })),
944 }
945 }
946
947 pub fn embed(&self, value: Value) -> Option<Root>
951 where
952 Value: Clone,
953 {
954 match self {
955 KeyPaths::ReadableEnum { embed, .. } => Some(embed(value)),
956 _ => None,
957 }
958 }
959
960 pub fn embed_mut(&self, value: Value) -> Option<Root>
961 where
962 Value: Clone,
963 {
964 match self {
965 KeyPaths::WritableEnum { embed, .. } => Some(embed(value)),
966 _ => None,
967 }
968 }
969
970
971 #[inline]
975 pub fn get_owned(self, root: Root) -> Value {
976 match self {
977 KeyPaths::Owned(f) => f(root),
978 _ => panic!("get_owned only works with owned keypaths"),
979 }
980 }
981
982 #[inline]
984 pub fn get_failable_owned(self, root: Root) -> Option<Value> {
985 match self {
986 KeyPaths::FailableOwned(f) => f(root),
987 _ => panic!("get_failable_owned only works with failable owned keypaths"),
988 }
989 }
990
991 pub fn iter<'a, T>(&'a self, root: &'a Root) -> Option<<&'a Value as IntoIterator>::IntoIter>
993 where
994 &'a Value: IntoIterator<Item = &'a T>,
995 T: 'a,
996 {
997 self.get(root).map(|v| v.into_iter())
998 }
999
1000 pub fn iter_mut<'a, T>(
1002 &'a self,
1003 root: &'a mut Root,
1004 ) -> Option<<&'a mut Value as IntoIterator>::IntoIter>
1005 where
1006 &'a mut Value: IntoIterator<Item = &'a mut T>,
1007 T: 'a,
1008 {
1009 self.get_mut(root).map(|v| v.into_iter())
1010 }
1011
1012 #[inline]
1014 pub fn into_iter<T>(self, root: Root) -> Option<<Value as IntoIterator>::IntoIter>
1015 where
1016 Value: IntoIterator<Item = T> + Clone,
1017 {
1018 match self {
1019 KeyPaths::Readable(f) => Some(f(&root).clone().into_iter()), KeyPaths::Writable(_) => None,
1021 KeyPaths::FailableReadable(f) => f(&root).map(|v| v.clone().into_iter()),
1022 KeyPaths::FailableWritable(_) => None,
1023 KeyPaths::ReadableEnum { extract, .. } => extract(&root).map(|v| v.clone().into_iter()),
1024 KeyPaths::WritableEnum { extract, .. } => extract(&root).map(|v| v.clone().into_iter()),
1025 KeyPaths::ReferenceWritable(_) => None, KeyPaths::Owned(f) => Some(f(root).into_iter()),
1028 KeyPaths::FailableOwned(f) => f(root).map(|v| v.into_iter()),
1029 }
1030 }
1031}
1032
1033impl<Root> PartialKeyPath<Root> {
1035 #[inline]
1037 pub fn get<'a>(&'a self, root: &'a Root) -> Option<&'a (dyn Any + Send + Sync)> {
1038 match self {
1039 PartialKeyPath::Readable(f) => Some(f(root)),
1040 PartialKeyPath::Writable(_) => None, PartialKeyPath::FailableReadable(f) => f(root),
1042 PartialKeyPath::FailableWritable(_) => None, PartialKeyPath::ReadableEnum { extract, .. } => extract(root),
1044 PartialKeyPath::WritableEnum { extract, .. } => extract(root),
1045 PartialKeyPath::ReferenceWritable(_) => None, PartialKeyPath::Owned(_) => None, PartialKeyPath::FailableOwned(_) => None, }
1049 }
1050
1051 #[inline]
1053 pub fn get_mut<'a>(&'a self, root: &'a mut Root) -> Option<&'a mut (dyn Any + Send + Sync)> {
1054 match self {
1055 PartialKeyPath::Readable(_) => None, PartialKeyPath::Writable(f) => Some(f(root)),
1057 PartialKeyPath::FailableReadable(_) => None, PartialKeyPath::FailableWritable(f) => f(root),
1059 PartialKeyPath::ReadableEnum { .. } => None, PartialKeyPath::WritableEnum { extract_mut, .. } => extract_mut(root),
1061 PartialKeyPath::ReferenceWritable(f) => Some(f(root)),
1062 PartialKeyPath::Owned(_) => None, PartialKeyPath::FailableOwned(_) => None, }
1065 }
1066
1067 #[inline]
1069 pub fn get_owned(self, root: Root) -> Box<dyn Any> {
1070 match self {
1071 PartialKeyPath::Owned(f) => f(root),
1072 _ => panic!("get_owned only works with owned keypaths"),
1073 }
1074 }
1075
1076 #[inline]
1078 pub fn get_failable_owned(self, root: Root) -> Option<Box<dyn Any>> {
1079 match self {
1080 PartialKeyPath::FailableOwned(f) => f(root),
1081 _ => panic!("get_failable_owned only works with failable owned keypaths"),
1082 }
1083 }
1084
1085 pub fn to_any(self) -> AnyKeyPath
1087 where
1088 Root: 'static,
1089 {
1090 match self {
1091 PartialKeyPath::Readable(f) => AnyKeyPath::Readable(Arc::new(move |root| {
1092 let typed_root = root.downcast_ref::<Root>().unwrap();
1093 f(typed_root)
1094 })),
1095 PartialKeyPath::Writable(f) => AnyKeyPath::Writable(Arc::new(move |root| {
1096 let typed_root = root.downcast_mut::<Root>().unwrap();
1097 f(typed_root)
1098 })),
1099 PartialKeyPath::FailableReadable(f) => AnyKeyPath::FailableReadable(Arc::new(move |root| {
1100 let typed_root = root.downcast_ref::<Root>().unwrap();
1101 f(typed_root)
1102 })),
1103 PartialKeyPath::FailableWritable(f) => AnyKeyPath::FailableWritable(Arc::new(move |root| {
1104 let typed_root = root.downcast_mut::<Root>().unwrap();
1105 f(typed_root)
1106 })),
1107 PartialKeyPath::ReadableEnum { extract, embed } => AnyKeyPath::ReadableEnum {
1108 extract: Arc::new(move |root| {
1109 let typed_root = root.downcast_ref::<Root>().unwrap();
1110 extract(typed_root)
1111 }),
1112 embed: Arc::new(move |value| {
1113 let typed_value = *value.downcast::<Root>().unwrap();
1114 Box::new(embed(Box::new(typed_value))) as Box<dyn Any>
1115 }),
1116 },
1117 PartialKeyPath::WritableEnum { extract, extract_mut, embed } => AnyKeyPath::WritableEnum {
1118 extract: Arc::new(move |root| {
1119 let typed_root = root.downcast_ref::<Root>().unwrap();
1120 extract(typed_root)
1121 }),
1122 extract_mut: Arc::new(move |root| {
1123 let typed_root = root.downcast_mut::<Root>().unwrap();
1124 extract_mut(typed_root)
1125 }),
1126 embed: Arc::new(move |value| {
1127 let typed_value = *value.downcast::<Root>().unwrap();
1128 Box::new(embed(Box::new(typed_value))) as Box<dyn Any>
1129 }),
1130 },
1131 PartialKeyPath::ReferenceWritable(f) => AnyKeyPath::ReferenceWritable(Arc::new(move |root| {
1132 let typed_root = root.downcast_mut::<Root>().unwrap();
1133 f(typed_root)
1134 })),
1135 PartialKeyPath::Owned(f) => AnyKeyPath::Owned(Arc::new(move |root| {
1136 let typed_root = *root.downcast::<Root>().unwrap();
1137 f(typed_root)
1138 })),
1139 PartialKeyPath::FailableOwned(f) => AnyKeyPath::FailableOwned(Arc::new(move |root| {
1140 let typed_root = *root.downcast::<Root>().unwrap();
1141 f(typed_root)
1142 })),
1143 }
1144 }
1145
1146 #[inline]
1148 pub fn kind_name(&self) -> &'static str {
1149 match self {
1150 PartialKeyPath::Readable(_) => "PartialKeyPath::Readable",
1151 PartialKeyPath::Writable(_) => "PartialKeyPath::Writable",
1152 PartialKeyPath::FailableReadable(_) => "PartialKeyPath::FailableReadable",
1153 PartialKeyPath::FailableWritable(_) => "PartialKeyPath::FailableWritable",
1154 PartialKeyPath::ReadableEnum { .. } => "PartialKeyPath::ReadableEnum",
1155 PartialKeyPath::WritableEnum { .. } => "PartialKeyPath::WritableEnum",
1156 PartialKeyPath::ReferenceWritable(_) => "PartialKeyPath::ReferenceWritable",
1157 PartialKeyPath::Owned(_) => "PartialKeyPath::Owned",
1158 PartialKeyPath::FailableOwned(_) => "PartialKeyPath::FailableOwned",
1159 }
1160 }
1161
1162 pub fn for_arc(self) -> PartialKeyPath<Arc<Root>>
1166 where
1167 Root: 'static + Clone,
1168 {
1169 match self {
1170 PartialKeyPath::Readable(f) => PartialKeyPath::Readable(Arc::new(move |arc: &Arc<Root>| f(&**arc))),
1171 PartialKeyPath::Writable(_) => {
1172 panic!("Arc does not support writable keypaths (Arc only implements Deref, not DerefMut)")
1173 }
1174 PartialKeyPath::FailableReadable(f) => PartialKeyPath::FailableReadable(Arc::new(move |arc: &Arc<Root>| f(&**arc))),
1175 PartialKeyPath::FailableWritable(_) => {
1176 panic!("Arc does not support writable keypaths (Arc only implements Deref, not DerefMut)")
1177 }
1178 PartialKeyPath::ReadableEnum { extract, embed } => PartialKeyPath::ReadableEnum {
1179 extract: Arc::new(move |arc: &Arc<Root>| extract(&**arc)),
1180 embed: Arc::new(move |value| Arc::new(embed(value))),
1181 },
1182 PartialKeyPath::WritableEnum { .. } => {
1183 panic!("Arc does not support writable keypaths (Arc only implements Deref, not DerefMut)")
1184 }
1185 PartialKeyPath::ReferenceWritable(_) => {
1186 panic!("Arc does not support writable keypaths (Arc only implements Deref, not DerefMut)")
1187 }
1188 PartialKeyPath::Owned(f) => PartialKeyPath::Owned(Arc::new(move |arc: Arc<Root>| f((*arc).clone()))),
1189 PartialKeyPath::FailableOwned(f) => PartialKeyPath::FailableOwned(Arc::new(move |arc: Arc<Root>| f((*arc).clone()))),
1190 }
1191 }
1192
1193 pub fn for_box(self) -> PartialKeyPath<Box<Root>>
1195 where
1196 Root: 'static,
1197 {
1198 match self {
1199 PartialKeyPath::Readable(f) => PartialKeyPath::Readable(Arc::new(move |boxed: &Box<Root>| f(&**boxed))),
1200 PartialKeyPath::Writable(f) => PartialKeyPath::Writable(Arc::new(move |boxed: &mut Box<Root>| f(&mut **boxed))),
1201 PartialKeyPath::FailableReadable(f) => PartialKeyPath::FailableReadable(Arc::new(move |boxed: &Box<Root>| f(&**boxed))),
1202 PartialKeyPath::FailableWritable(f) => PartialKeyPath::FailableWritable(Arc::new(move |boxed: &mut Box<Root>| f(&mut **boxed))),
1203 PartialKeyPath::ReadableEnum { extract, embed } => PartialKeyPath::ReadableEnum {
1204 extract: Arc::new(move |boxed: &Box<Root>| extract(&**boxed)),
1205 embed: Arc::new(move |value| Box::new(embed(value))),
1206 },
1207 PartialKeyPath::WritableEnum { extract, extract_mut, embed } => PartialKeyPath::WritableEnum {
1208 extract: Arc::new(move |boxed: &Box<Root>| extract(&**boxed)),
1209 extract_mut: Arc::new(move |boxed: &mut Box<Root>| extract_mut(&mut **boxed)),
1210 embed: Arc::new(move |value| Box::new(embed(value))),
1211 },
1212 PartialKeyPath::ReferenceWritable(f) => PartialKeyPath::ReferenceWritable(Arc::new(move |boxed: &mut Box<Root>| f(&mut **boxed))),
1213 PartialKeyPath::Owned(f) => PartialKeyPath::Owned(Arc::new(move |boxed: Box<Root>| f(*boxed))),
1214 PartialKeyPath::FailableOwned(f) => PartialKeyPath::FailableOwned(Arc::new(move |boxed: Box<Root>| f(*boxed))),
1215 }
1216 }
1217
1218 pub fn for_rc(self) -> PartialKeyPath<Rc<Root>>
1220 where
1221 Root: 'static + Clone,
1222 {
1223 match self {
1224 PartialKeyPath::Readable(f) => PartialKeyPath::Readable(Arc::new(move |rc: &Rc<Root>| f(&**rc))),
1225 PartialKeyPath::Writable(_) => {
1226 panic!("Rc does not support writable keypaths (Rc only implements Deref, not DerefMut)")
1227 }
1228 PartialKeyPath::FailableReadable(f) => PartialKeyPath::FailableReadable(Arc::new(move |rc: &Rc<Root>| f(&**rc))),
1229 PartialKeyPath::FailableWritable(_) => {
1230 panic!("Rc does not support writable keypaths (Rc only implements Deref, not DerefMut)")
1231 }
1232 PartialKeyPath::ReadableEnum { extract, embed } => PartialKeyPath::ReadableEnum {
1233 extract: Arc::new(move |rc: &Rc<Root>| extract(&**rc)),
1234 embed: Arc::new(move |value| Rc::new(embed(value))),
1235 },
1236 PartialKeyPath::WritableEnum { .. } => {
1237 panic!("Rc does not support writable keypaths (Rc only implements Deref, not DerefMut)")
1238 }
1239 PartialKeyPath::ReferenceWritable(_) => {
1240 panic!("Rc does not support writable keypaths (Rc only implements Deref, not DerefMut)")
1241 }
1242 PartialKeyPath::Owned(f) => PartialKeyPath::Owned(Arc::new(move |rc: Rc<Root>| f((*rc).clone()))),
1243 PartialKeyPath::FailableOwned(f) => PartialKeyPath::FailableOwned(Arc::new(move |rc: Rc<Root>| f((*rc).clone()))),
1244 }
1245 }
1246
1247 pub fn for_result<E>(self) -> PartialKeyPath<Result<Root, E>>
1249 where
1250 Root: 'static,
1251 {
1252 match self {
1253 PartialKeyPath::Readable(f) => PartialKeyPath::FailableReadable(Arc::new(move |result: &Result<Root, E>| {
1254 result.as_ref().ok().map(|root| f(root) as &(dyn Any + Send + Sync))
1255 })),
1256 PartialKeyPath::Writable(f) => PartialKeyPath::FailableWritable(Arc::new(move |result: &mut Result<Root, E>| {
1257 result.as_mut().ok().map(|root| f(root) as &mut (dyn Any + Send + Sync))
1258 })),
1259 PartialKeyPath::FailableReadable(f) => PartialKeyPath::FailableReadable(Arc::new(move |result: &Result<Root, E>| {
1260 result.as_ref().ok().and_then(|root| f(root))
1261 })),
1262 PartialKeyPath::FailableWritable(f) => PartialKeyPath::FailableWritable(Arc::new(move |result: &mut Result<Root, E>| {
1263 result.as_mut().ok().and_then(|root| f(root))
1264 })),
1265 PartialKeyPath::ReadableEnum { extract, embed } => PartialKeyPath::ReadableEnum {
1266 extract: Arc::new(move |result: &Result<Root, E>| {
1267 result.as_ref().ok().and_then(|root| extract(root))
1268 }),
1269 embed: Arc::new(move |value| Ok(embed(value))),
1270 },
1271 PartialKeyPath::WritableEnum { extract, extract_mut, embed } => PartialKeyPath::WritableEnum {
1272 extract: Arc::new(move |result: &Result<Root, E>| {
1273 result.as_ref().ok().and_then(|root| extract(root))
1274 }),
1275 extract_mut: Arc::new(move |result: &mut Result<Root, E>| {
1276 result.as_mut().ok().and_then(|root| extract_mut(root))
1277 }),
1278 embed: Arc::new(move |value| Ok(embed(value))),
1279 },
1280 PartialKeyPath::ReferenceWritable(f) => PartialKeyPath::FailableWritable(Arc::new(move |result: &mut Result<Root, E>| {
1281 result.as_mut().ok().map(|root| f(root) as &mut (dyn Any + Send + Sync))
1282 })),
1283 PartialKeyPath::Owned(f) => PartialKeyPath::FailableOwned(Arc::new(move |result: Result<Root, E>| {
1284 result.ok().map(|root| f(root))
1285 })),
1286 PartialKeyPath::FailableOwned(f) => PartialKeyPath::FailableOwned(Arc::new(move |result: Result<Root, E>| {
1287 result.ok().and_then(|root| f(root))
1288 })),
1289 }
1290 }
1291
1292 pub fn for_option(self) -> PartialKeyPath<Option<Root>>
1294 where
1295 Root: 'static,
1296 {
1297 match self {
1298 PartialKeyPath::Readable(f) => PartialKeyPath::FailableReadable(Arc::new(move |option: &Option<Root>| {
1299 option.as_ref().map(|root| f(root) as &(dyn Any + Send + Sync))
1300 })),
1301 PartialKeyPath::Writable(f) => PartialKeyPath::FailableWritable(Arc::new(move |option: &mut Option<Root>| {
1302 option.as_mut().map(|root| f(root) as &mut (dyn Any + Send + Sync))
1303 })),
1304 PartialKeyPath::FailableReadable(f) => PartialKeyPath::FailableReadable(Arc::new(move |option: &Option<Root>| {
1305 option.as_ref().and_then(|root| f(root))
1306 })),
1307 PartialKeyPath::FailableWritable(f) => PartialKeyPath::FailableWritable(Arc::new(move |option: &mut Option<Root>| {
1308 option.as_mut().and_then(|root| f(root))
1309 })),
1310 PartialKeyPath::ReadableEnum { extract, embed } => PartialKeyPath::ReadableEnum {
1311 extract: Arc::new(move |option: &Option<Root>| {
1312 option.as_ref().and_then(|root| extract(root))
1313 }),
1314 embed: Arc::new(move |value| Some(embed(value))),
1315 },
1316 PartialKeyPath::WritableEnum { extract, extract_mut, embed } => PartialKeyPath::WritableEnum {
1317 extract: Arc::new(move |option: &Option<Root>| {
1318 option.as_ref().and_then(|root| extract(root))
1319 }),
1320 extract_mut: Arc::new(move |option: &mut Option<Root>| {
1321 option.as_mut().and_then(|root| extract_mut(root))
1322 }),
1323 embed: Arc::new(move |value| Some(embed(value))),
1324 },
1325 PartialKeyPath::ReferenceWritable(f) => PartialKeyPath::FailableWritable(Arc::new(move |option: &mut Option<Root>| {
1326 option.as_mut().map(|root| f(root) as &mut (dyn Any + Send + Sync))
1327 })),
1328 PartialKeyPath::Owned(f) => PartialKeyPath::FailableOwned(Arc::new(move |option: Option<Root>| {
1329 option.map(|root| f(root))
1330 })),
1331 PartialKeyPath::FailableOwned(f) => PartialKeyPath::FailableOwned(Arc::new(move |option: Option<Root>| {
1332 option.and_then(|root| f(root))
1333 })),
1334 }
1335 }
1336
1337 pub fn for_arc_rwlock(self) -> PartialKeyPath<Arc<RwLock<Root>>>
1340 where
1341 Root: 'static + Clone,
1342 {
1343 match self {
1344 PartialKeyPath::Readable(_) => {
1345 panic!("Arc<RwLock> does not support readable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1346 }
1347 PartialKeyPath::Writable(_) => {
1348 panic!("Arc<RwLock> does not support writable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1349 }
1350 PartialKeyPath::FailableReadable(_) => {
1351 panic!("Arc<RwLock> does not support failable readable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1352 }
1353 PartialKeyPath::FailableWritable(_) => {
1354 panic!("Arc<RwLock> does not support failable writable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1355 }
1356 PartialKeyPath::ReadableEnum { .. } => {
1357 panic!("Arc<RwLock> does not support readable enum keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1358 }
1359 PartialKeyPath::WritableEnum { .. } => {
1360 panic!("Arc<RwLock> does not support writable enum keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1361 }
1362 PartialKeyPath::ReferenceWritable(_) => {
1363 panic!("Arc<RwLock> does not support reference writable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1364 }
1365 PartialKeyPath::Owned(f) => PartialKeyPath::Owned(Arc::new(move |arc_rwlock: Arc<RwLock<Root>>| {
1366 let guard = arc_rwlock.read().unwrap();
1367 let value = f((*guard).clone());
1368 drop(guard); value
1370 })),
1371 PartialKeyPath::FailableOwned(f) => PartialKeyPath::FailableOwned(Arc::new(move |arc_rwlock: Arc<RwLock<Root>>| {
1372 let guard = arc_rwlock.read().unwrap();
1373 let value = f((*guard).clone());
1374 drop(guard); value
1376 })),
1377 }
1378 }
1379
1380 pub fn for_arc_mutex(self) -> PartialKeyPath<Arc<Mutex<Root>>>
1383 where
1384 Root: 'static + Clone,
1385 {
1386 match self {
1387 PartialKeyPath::Readable(_) => {
1388 panic!("Arc<Mutex> does not support readable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1389 }
1390 PartialKeyPath::Writable(_) => {
1391 panic!("Arc<Mutex> does not support writable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1392 }
1393 PartialKeyPath::FailableReadable(_) => {
1394 panic!("Arc<Mutex> does not support failable readable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1395 }
1396 PartialKeyPath::FailableWritable(_) => {
1397 panic!("Arc<Mutex> does not support failable writable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1398 }
1399 PartialKeyPath::ReadableEnum { .. } => {
1400 panic!("Arc<Mutex> does not support readable enum keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1401 }
1402 PartialKeyPath::WritableEnum { .. } => {
1403 panic!("Arc<Mutex> does not support writable enum keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1404 }
1405 PartialKeyPath::ReferenceWritable(_) => {
1406 panic!("Arc<Mutex> does not support reference writable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1407 }
1408 PartialKeyPath::Owned(f) => PartialKeyPath::Owned(Arc::new(move |arc_mutex: Arc<Mutex<Root>>| {
1409 let guard = arc_mutex.lock().unwrap();
1410 let value = f((*guard).clone());
1411 drop(guard); value
1413 })),
1414 PartialKeyPath::FailableOwned(f) => PartialKeyPath::FailableOwned(Arc::new(move |arc_mutex: Arc<Mutex<Root>>| {
1415 let guard = arc_mutex.lock().unwrap();
1416 let value = f((*guard).clone());
1417 drop(guard); value
1419 })),
1420 }
1421 }
1422
1423 #[cfg(feature = "tagged_core")]
1425 pub fn for_tagged<Tag>(self) -> PartialKeyPath<Tagged<Root, Tag>>
1426 where
1427 Root: Clone + 'static,
1428 {
1429 match self {
1430 PartialKeyPath::Readable(f) => PartialKeyPath::Readable(Arc::new(move |tagged: &Tagged<Root, Tag>| {
1431 f(&*tagged) as &(dyn Any + Send + Sync)
1432 })),
1433 PartialKeyPath::Writable(_) => {
1434 panic!("Tagged does not support writable keypaths (Tagged only implements Deref, not DerefMut)")
1435 }
1436 PartialKeyPath::FailableReadable(f) => PartialKeyPath::FailableReadable(Arc::new(move |tagged: &Tagged<Root, Tag>| {
1437 f(&*tagged)
1438 })),
1439 PartialKeyPath::FailableWritable(_) => {
1440 panic!("Tagged does not support writable keypaths (Tagged only implements Deref, not DerefMut)")
1441 }
1442 PartialKeyPath::ReadableEnum { extract, embed } => PartialKeyPath::ReadableEnum {
1443 extract: Arc::new(move |tagged: &Tagged<Root, Tag>| {
1444 extract(&*tagged)
1445 }),
1446 embed: Arc::new(move |value| embed(value).into()),
1447 },
1448 PartialKeyPath::WritableEnum { .. } => {
1449 panic!("Tagged does not support writable keypaths (Tagged only implements Deref, not DerefMut)")
1450 }
1451 PartialKeyPath::ReferenceWritable(_) => {
1452 panic!("Tagged does not support writable keypaths (Tagged only implements Deref, not DerefMut)")
1453 }
1454 PartialKeyPath::Owned(f) => PartialKeyPath::Owned(Arc::new(move |tagged: Tagged<Root, Tag>| {
1455 f((*tagged).clone())
1456 })),
1457 PartialKeyPath::FailableOwned(f) => PartialKeyPath::FailableOwned(Arc::new(move |tagged: Tagged<Root, Tag>| {
1458 f((*tagged).clone())
1459 })),
1460 }
1461 }
1462}
1463
1464impl AnyKeyPath {
1466 #[inline]
1468 pub fn get<'a>(&'a self, root: &'a (dyn Any + Send + Sync)) -> Option<&'a (dyn Any + Send + Sync)> {
1469 match self {
1470 AnyKeyPath::Readable(f) => Some(f(root)),
1471 AnyKeyPath::Writable(_) => None, AnyKeyPath::FailableReadable(f) => f(root),
1473 AnyKeyPath::FailableWritable(_) => None, AnyKeyPath::ReadableEnum { extract, .. } => extract(root),
1475 AnyKeyPath::WritableEnum { extract, .. } => extract(root),
1476 AnyKeyPath::ReferenceWritable(_) => None, AnyKeyPath::Owned(_) => None, AnyKeyPath::FailableOwned(_) => None, }
1480 }
1481
1482 #[inline]
1484 pub fn get_mut<'a>(&'a self, root: &'a mut (dyn Any + Send + Sync)) -> Option<&'a mut (dyn Any + Send + Sync)> {
1485 match self {
1486 AnyKeyPath::Readable(_) => None, AnyKeyPath::Writable(f) => Some(f(root)),
1488 AnyKeyPath::FailableReadable(_) => None, AnyKeyPath::FailableWritable(f) => f(root),
1490 AnyKeyPath::ReadableEnum { .. } => None, AnyKeyPath::WritableEnum { extract_mut, .. } => extract_mut(root),
1492 AnyKeyPath::ReferenceWritable(f) => Some(f(root)),
1493 AnyKeyPath::Owned(_) => None, AnyKeyPath::FailableOwned(_) => None, }
1496 }
1497
1498 #[inline]
1500 pub fn get_owned(self, root: Box<dyn Any>) -> Box<dyn Any> {
1501 match self {
1502 AnyKeyPath::Owned(f) => f(root),
1503 _ => panic!("get_owned only works with owned keypaths"),
1504 }
1505 }
1506
1507 #[inline]
1509 pub fn get_failable_owned(self, root: Box<dyn Any>) -> Option<Box<dyn Any>> {
1510 match self {
1511 AnyKeyPath::FailableOwned(f) => f(root),
1512 _ => panic!("get_failable_owned only works with failable owned keypaths"),
1513 }
1514 }
1515
1516 #[inline]
1518 pub fn kind_name(&self) -> &'static str {
1519 match self {
1520 AnyKeyPath::Readable(_) => "AnyKeyPath::Readable",
1521 AnyKeyPath::Writable(_) => "AnyKeyPath::Writable",
1522 AnyKeyPath::FailableReadable(_) => "AnyKeyPath::FailableReadable",
1523 AnyKeyPath::FailableWritable(_) => "AnyKeyPath::FailableWritable",
1524 AnyKeyPath::ReadableEnum { .. } => "AnyKeyPath::ReadableEnum",
1525 AnyKeyPath::WritableEnum { .. } => "AnyKeyPath::WritableEnum",
1526 AnyKeyPath::ReferenceWritable(_) => "AnyKeyPath::ReferenceWritable",
1527 AnyKeyPath::Owned(_) => "AnyKeyPath::Owned",
1528 AnyKeyPath::FailableOwned(_) => "AnyKeyPath::FailableOwned",
1529 }
1530 }
1531
1532 pub fn for_arc<Root>(self) -> AnyKeyPath
1536 where
1537 Root: 'static + Send + Sync + Clone,
1538 {
1539 match self {
1540 AnyKeyPath::Readable(f) => AnyKeyPath::Readable(Arc::new(move |root| {
1541 let arc = root.downcast_ref::<Arc<Root>>().unwrap();
1542 f(&**arc as &(dyn Any + Send + Sync))
1543 })),
1544 AnyKeyPath::Writable(_) => {
1545 panic!("Arc does not support writable keypaths (Arc only implements Deref, not DerefMut)")
1546 }
1547 AnyKeyPath::FailableReadable(f) => AnyKeyPath::FailableReadable(Arc::new(move |root| {
1548 let arc = root.downcast_ref::<Arc<Root>>().unwrap();
1549 f(&**arc as &(dyn Any + Send + Sync))
1550 })),
1551 AnyKeyPath::FailableWritable(_) => {
1552 panic!("Arc does not support writable keypaths (Arc only implements Deref, not DerefMut)")
1553 }
1554 AnyKeyPath::ReadableEnum { extract, embed } => AnyKeyPath::ReadableEnum {
1555 extract: Arc::new(move |root| {
1556 let arc = root.downcast_ref::<Arc<Root>>().unwrap();
1557 extract(&**arc as &(dyn Any + Send + Sync))
1558 }),
1559 embed: Arc::new(move |value| {
1560 let inner = embed(value);
1561 Box::new(Arc::new(*inner.downcast::<Root>().unwrap())) as Box<dyn Any>
1562 }),
1563 },
1564 AnyKeyPath::WritableEnum { .. } => {
1565 panic!("Arc does not support writable keypaths (Arc only implements Deref, not DerefMut)")
1566 }
1567 AnyKeyPath::ReferenceWritable(_) => {
1568 panic!("Arc does not support writable keypaths (Arc only implements Deref, not DerefMut)")
1569 }
1570 AnyKeyPath::Owned(f) => AnyKeyPath::Owned(Arc::new(move |root| {
1571 let arc = *root.downcast::<Arc<Root>>().unwrap();
1572 f(Box::new((*arc).clone()) as Box<dyn Any>)
1573 })),
1574 AnyKeyPath::FailableOwned(f) => AnyKeyPath::FailableOwned(Arc::new(move |root| {
1575 let arc = *root.downcast::<Arc<Root>>().unwrap();
1576 f(Box::new((*arc).clone()) as Box<dyn Any>)
1577 })),
1578 }
1579 }
1580
1581 pub fn for_box<Root>(self) -> AnyKeyPath
1583 where
1584 Root: 'static + Send + Sync,
1585 {
1586 match self {
1587 AnyKeyPath::Readable(f) => AnyKeyPath::Readable(Arc::new(move |root| {
1588 let boxed = root.downcast_ref::<Box<Root>>().unwrap();
1589 f(&**boxed as &(dyn Any + Send + Sync))
1590 })),
1591 AnyKeyPath::Writable(f) => AnyKeyPath::Writable(Arc::new(move |root| {
1592 let boxed = root.downcast_mut::<Box<Root>>().unwrap();
1593 f(&mut **boxed as &mut (dyn Any + Send + Sync))
1594 })),
1595 AnyKeyPath::FailableReadable(f) => AnyKeyPath::FailableReadable(Arc::new(move |root| {
1596 let boxed = root.downcast_ref::<Box<Root>>().unwrap();
1597 f(&**boxed as &(dyn Any + Send + Sync))
1598 })),
1599 AnyKeyPath::FailableWritable(f) => AnyKeyPath::FailableWritable(Arc::new(move |root| {
1600 let boxed = root.downcast_mut::<Box<Root>>().unwrap();
1601 f(&mut **boxed as &mut (dyn Any + Send + Sync))
1602 })),
1603 AnyKeyPath::ReadableEnum { extract, embed } => AnyKeyPath::ReadableEnum {
1604 extract: Arc::new(move |root| {
1605 let boxed = root.downcast_ref::<Box<Root>>().unwrap();
1606 extract(&**boxed as &(dyn Any + Send + Sync))
1607 }),
1608 embed: Arc::new(move |value| {
1609 let inner = embed(value);
1610 Box::new(Box::new(*inner.downcast::<Root>().unwrap())) as Box<dyn Any>
1611 }),
1612 },
1613 AnyKeyPath::WritableEnum { extract, extract_mut, embed } => AnyKeyPath::WritableEnum {
1614 extract: Arc::new(move |root| {
1615 let boxed = root.downcast_ref::<Box<Root>>().unwrap();
1616 extract(&**boxed as &(dyn Any + Send + Sync))
1617 }),
1618 extract_mut: Arc::new(move |root| {
1619 let boxed = root.downcast_mut::<Box<Root>>().unwrap();
1620 extract_mut(&mut **boxed as &mut (dyn Any + Send + Sync))
1621 }),
1622 embed: Arc::new(move |value| {
1623 let inner = embed(value);
1624 Box::new(Box::new(*inner.downcast::<Root>().unwrap())) as Box<dyn Any>
1625 }),
1626 },
1627 AnyKeyPath::ReferenceWritable(f) => AnyKeyPath::ReferenceWritable(Arc::new(move |root| {
1628 let boxed = root.downcast_mut::<Box<Root>>().unwrap();
1629 f(&mut **boxed as &mut (dyn Any + Send + Sync))
1630 })),
1631 AnyKeyPath::Owned(f) => AnyKeyPath::Owned(Arc::new(move |root| {
1632 let boxed = *root.downcast::<Box<Root>>().unwrap();
1633 f(Box::new(*boxed) as Box<dyn Any>)
1634 })),
1635 AnyKeyPath::FailableOwned(f) => AnyKeyPath::FailableOwned(Arc::new(move |root| {
1636 let boxed = *root.downcast::<Box<Root>>().unwrap();
1637 f(Box::new(*boxed) as Box<dyn Any>)
1638 })),
1639 }
1640 }
1641
1642 pub fn for_rc<Root>(self) -> AnyKeyPath
1644 where
1645 Root: 'static + Send + Sync + Clone,
1646 {
1647 match self {
1648 AnyKeyPath::Readable(f) => AnyKeyPath::Readable(Arc::new(move |root| {
1649 let rc = root.downcast_ref::<Rc<Root>>().unwrap();
1650 f(&**rc as &(dyn Any + Send + Sync))
1651 })),
1652 AnyKeyPath::Writable(_) => {
1653 panic!("Rc does not support writable keypaths (Rc only implements Deref, not DerefMut)")
1654 }
1655 AnyKeyPath::FailableReadable(f) => AnyKeyPath::FailableReadable(Arc::new(move |root| {
1656 let rc = root.downcast_ref::<Rc<Root>>().unwrap();
1657 f(&**rc as &(dyn Any + Send + Sync))
1658 })),
1659 AnyKeyPath::FailableWritable(_) => {
1660 panic!("Rc does not support writable keypaths (Rc only implements Deref, not DerefMut)")
1661 }
1662 AnyKeyPath::ReadableEnum { extract, embed } => AnyKeyPath::ReadableEnum {
1663 extract: Arc::new(move |root| {
1664 let rc = root.downcast_ref::<Rc<Root>>().unwrap();
1665 extract(&**rc as &(dyn Any + Send + Sync))
1666 }),
1667 embed: Arc::new(move |value| {
1668 let inner = embed(value);
1669 Box::new(Rc::new(*inner.downcast::<Root>().unwrap())) as Box<dyn Any>
1670 }),
1671 },
1672 AnyKeyPath::WritableEnum { .. } => {
1673 panic!("Rc does not support writable keypaths (Rc only implements Deref, not DerefMut)")
1674 }
1675 AnyKeyPath::ReferenceWritable(_) => {
1676 panic!("Rc does not support writable keypaths (Rc only implements Deref, not DerefMut)")
1677 }
1678 AnyKeyPath::Owned(f) => AnyKeyPath::Owned(Arc::new(move |root| {
1679 let rc = *root.downcast::<Rc<Root>>().unwrap();
1680 f(Box::new((*rc).clone()) as Box<dyn Any>)
1681 })),
1682 AnyKeyPath::FailableOwned(f) => AnyKeyPath::FailableOwned(Arc::new(move |root| {
1683 let rc = *root.downcast::<Rc<Root>>().unwrap();
1684 f(Box::new((*rc).clone()) as Box<dyn Any>)
1685 })),
1686 }
1687 }
1688
1689 pub fn for_result<Root, E>(self) -> AnyKeyPath
1691 where
1692 Root: 'static + Send + Sync,
1693 E: 'static,
1694 {
1695 match self {
1696 AnyKeyPath::Readable(f) => AnyKeyPath::FailableReadable(Arc::new(move |root| {
1697 let result = root.downcast_ref::<Result<Root, E>>().unwrap();
1698 result.as_ref().ok().map(|inner| f(inner as &(dyn Any + Send + Sync)))
1699 })),
1700 AnyKeyPath::Writable(f) => AnyKeyPath::FailableWritable(Arc::new(move |root| {
1701 let result = root.downcast_mut::<Result<Root, E>>().unwrap();
1702 result.as_mut().ok().map(|inner| f(inner as &mut (dyn Any + Send + Sync)))
1703 })),
1704 AnyKeyPath::FailableReadable(f) => AnyKeyPath::FailableReadable(Arc::new(move |root| {
1705 let result = root.downcast_ref::<Result<Root, E>>().unwrap();
1706 result.as_ref().ok().and_then(|inner| f(inner as &(dyn Any + Send + Sync)))
1707 })),
1708 AnyKeyPath::FailableWritable(f) => AnyKeyPath::FailableWritable(Arc::new(move |root| {
1709 let result = root.downcast_mut::<Result<Root, E>>().unwrap();
1710 result.as_mut().ok().and_then(|inner| f(inner as &mut (dyn Any + Send + Sync)))
1711 })),
1712 AnyKeyPath::ReadableEnum { extract, embed } => AnyKeyPath::ReadableEnum {
1713 extract: Arc::new(move |root| {
1714 let result = root.downcast_ref::<Result<Root, E>>().unwrap();
1715 result.as_ref().ok().and_then(|inner| extract(inner as &(dyn Any + Send + Sync)))
1716 }),
1717 embed: Arc::new(move |value| {
1718 let inner = embed(value);
1719 Box::new(Ok::<Root, E>(*inner.downcast::<Root>().unwrap())) as Box<dyn Any>
1720 }),
1721 },
1722 AnyKeyPath::WritableEnum { extract, extract_mut, embed } => AnyKeyPath::WritableEnum {
1723 extract: Arc::new(move |root| {
1724 let result = root.downcast_ref::<Result<Root, E>>().unwrap();
1725 result.as_ref().ok().and_then(|inner| extract(inner as &(dyn Any + Send + Sync)))
1726 }),
1727 extract_mut: Arc::new(move |root| {
1728 let result = root.downcast_mut::<Result<Root, E>>().unwrap();
1729 result.as_mut().ok().and_then(|inner| extract_mut(inner as &mut (dyn Any + Send + Sync)))
1730 }),
1731 embed: Arc::new(move |value| {
1732 let inner = embed(value);
1733 Box::new(Ok::<Root, E>(*inner.downcast::<Root>().unwrap())) as Box<dyn Any>
1734 }),
1735 },
1736 AnyKeyPath::ReferenceWritable(f) => AnyKeyPath::FailableWritable(Arc::new(move |root| {
1737 let result = root.downcast_mut::<Result<Root, E>>().unwrap();
1738 result.as_mut().ok().map(|inner| f(inner as &mut (dyn Any + Send + Sync)))
1739 })),
1740 AnyKeyPath::Owned(f) => AnyKeyPath::FailableOwned(Arc::new(move |root| {
1741 let result = *root.downcast::<Result<Root, E>>().unwrap();
1742 result.ok().map(|inner| f(Box::new(inner) as Box<dyn Any>))
1743 })),
1744 AnyKeyPath::FailableOwned(f) => AnyKeyPath::FailableOwned(Arc::new(move |root| {
1745 let result = *root.downcast::<Result<Root, E>>().unwrap();
1746 result.ok().and_then(|inner| f(Box::new(inner) as Box<dyn Any>))
1747 })),
1748 }
1749 }
1750
1751 pub fn for_option<Root>(self) -> AnyKeyPath
1753 where
1754 Root: 'static + Send + Sync,
1755 {
1756 match self {
1757 AnyKeyPath::Readable(f) => AnyKeyPath::FailableReadable(Arc::new(move |root| {
1758 let option = root.downcast_ref::<Option<Root>>().unwrap();
1759 option.as_ref().map(|inner| f(inner as &(dyn Any + Send + Sync)))
1760 })),
1761 AnyKeyPath::Writable(f) => AnyKeyPath::FailableWritable(Arc::new(move |root| {
1762 let option = root.downcast_mut::<Option<Root>>().unwrap();
1763 option.as_mut().map(|inner| f(inner as &mut (dyn Any + Send + Sync)))
1764 })),
1765 AnyKeyPath::FailableReadable(f) => AnyKeyPath::FailableReadable(Arc::new(move |root| {
1766 let option = root.downcast_ref::<Option<Root>>().unwrap();
1767 option.as_ref().and_then(|inner| f(inner as &(dyn Any + Send + Sync)))
1768 })),
1769 AnyKeyPath::FailableWritable(f) => AnyKeyPath::FailableWritable(Arc::new(move |root| {
1770 let option = root.downcast_mut::<Option<Root>>().unwrap();
1771 option.as_mut().and_then(|inner| f(inner as &mut (dyn Any + Send + Sync)))
1772 })),
1773 AnyKeyPath::ReadableEnum { extract, embed } => AnyKeyPath::ReadableEnum {
1774 extract: Arc::new(move |root| {
1775 let option = root.downcast_ref::<Option<Root>>().unwrap();
1776 option.as_ref().and_then(|inner| extract(inner as &(dyn Any + Send + Sync)))
1777 }),
1778 embed: Arc::new(move |value| {
1779 let inner = embed(value);
1780 Box::new(Some(*inner.downcast::<Root>().unwrap())) as Box<dyn Any>
1781 }),
1782 },
1783 AnyKeyPath::WritableEnum { extract, extract_mut, embed } => AnyKeyPath::WritableEnum {
1784 extract: Arc::new(move |root| {
1785 let option = root.downcast_ref::<Option<Root>>().unwrap();
1786 option.as_ref().and_then(|inner| extract(inner as &(dyn Any + Send + Sync)))
1787 }),
1788 extract_mut: Arc::new(move |root| {
1789 let option = root.downcast_mut::<Option<Root>>().unwrap();
1790 option.as_mut().and_then(|inner| extract_mut(inner as &mut (dyn Any + Send + Sync)))
1791 }),
1792 embed: Arc::new(move |value| {
1793 let inner = embed(value);
1794 Box::new(Some(*inner.downcast::<Root>().unwrap())) as Box<dyn Any>
1795 }),
1796 },
1797 AnyKeyPath::ReferenceWritable(f) => AnyKeyPath::FailableWritable(Arc::new(move |root| {
1798 let option = root.downcast_mut::<Option<Root>>().unwrap();
1799 option.as_mut().map(|inner| f(inner as &mut (dyn Any + Send + Sync)))
1800 })),
1801 AnyKeyPath::Owned(f) => AnyKeyPath::FailableOwned(Arc::new(move |root| {
1802 let option = *root.downcast::<Option<Root>>().unwrap();
1803 option.map(|inner| f(Box::new(inner) as Box<dyn Any>))
1804 })),
1805 AnyKeyPath::FailableOwned(f) => AnyKeyPath::FailableOwned(Arc::new(move |root| {
1806 let option = *root.downcast::<Option<Root>>().unwrap();
1807 option.and_then(|inner| f(Box::new(inner) as Box<dyn Any>))
1808 })),
1809 }
1810 }
1811
1812 pub fn for_arc_rwlock<Root>(self) -> AnyKeyPath
1815 where
1816 Root: 'static + Send + Sync + Clone,
1817 {
1818 match self {
1819 AnyKeyPath::Readable(_) => {
1820 panic!("Arc<RwLock> does not support readable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1821 }
1822 AnyKeyPath::Writable(_) => {
1823 panic!("Arc<RwLock> does not support writable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1824 }
1825 AnyKeyPath::FailableReadable(_) => {
1826 panic!("Arc<RwLock> does not support failable readable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1827 }
1828 AnyKeyPath::FailableWritable(_) => {
1829 panic!("Arc<RwLock> does not support failable writable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1830 }
1831 AnyKeyPath::ReadableEnum { .. } => {
1832 panic!("Arc<RwLock> does not support readable enum keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1833 }
1834 AnyKeyPath::WritableEnum { .. } => {
1835 panic!("Arc<RwLock> does not support writable enum keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1836 }
1837 AnyKeyPath::ReferenceWritable(_) => {
1838 panic!("Arc<RwLock> does not support reference writable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1839 }
1840 AnyKeyPath::Owned(f) => AnyKeyPath::Owned(Arc::new(move |root| {
1841 let arc_rwlock = *root.downcast::<Arc<RwLock<Root>>>().unwrap();
1842 let guard = arc_rwlock.read().unwrap();
1843 let value = f(Box::new((*guard).clone()) as Box<dyn Any>);
1844 drop(guard); value
1846 })),
1847 AnyKeyPath::FailableOwned(f) => AnyKeyPath::FailableOwned(Arc::new(move |root| {
1848 let arc_rwlock = *root.downcast::<Arc<RwLock<Root>>>().unwrap();
1849 let guard = arc_rwlock.read().unwrap();
1850 let value = f(Box::new((*guard).clone()) as Box<dyn Any>);
1851 drop(guard); value
1853 })),
1854 }
1855 }
1856
1857 pub fn for_arc_mutex<Root>(self) -> AnyKeyPath
1860 where
1861 Root: 'static + Send + Sync + Clone,
1862 {
1863 match self {
1864 AnyKeyPath::Readable(_) => {
1865 panic!("Arc<Mutex> does not support readable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1866 }
1867 AnyKeyPath::Writable(_) => {
1868 panic!("Arc<Mutex> does not support writable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1869 }
1870 AnyKeyPath::FailableReadable(_) => {
1871 panic!("Arc<Mutex> does not support failable readable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1872 }
1873 AnyKeyPath::FailableWritable(_) => {
1874 panic!("Arc<Mutex> does not support failable writable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1875 }
1876 AnyKeyPath::ReadableEnum { .. } => {
1877 panic!("Arc<Mutex> does not support readable enum keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1878 }
1879 AnyKeyPath::WritableEnum { .. } => {
1880 panic!("Arc<Mutex> does not support writable enum keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1881 }
1882 AnyKeyPath::ReferenceWritable(_) => {
1883 panic!("Arc<Mutex> does not support reference writable keypaths due to guard lifetime constraints. Use owned keypaths instead.")
1884 }
1885 AnyKeyPath::Owned(f) => AnyKeyPath::Owned(Arc::new(move |root| {
1886 let arc_mutex = *root.downcast::<Arc<Mutex<Root>>>().unwrap();
1887 let guard = arc_mutex.lock().unwrap();
1888 let value = f(Box::new((*guard).clone()) as Box<dyn Any>);
1889 drop(guard); value
1891 })),
1892 AnyKeyPath::FailableOwned(f) => AnyKeyPath::FailableOwned(Arc::new(move |root| {
1893 let arc_mutex = *root.downcast::<Arc<Mutex<Root>>>().unwrap();
1894 let guard = arc_mutex.lock().unwrap();
1895 let value = f(Box::new((*guard).clone()) as Box<dyn Any>);
1896 drop(guard); value
1898 })),
1899 }
1900 }
1901
1902 #[cfg(feature = "tagged_core")]
1904 pub fn for_tagged<Root, Tag>(self) -> AnyKeyPath
1905 where
1906 Root: Clone + 'static + Send + Sync,
1907 Tag: Send + Sync + 'static,
1908 {
1909 match self {
1910 AnyKeyPath::Readable(f) => AnyKeyPath::Readable(Arc::new(move |root| {
1911 let tagged = root.downcast_ref::<Tagged<Root, Tag>>().unwrap();
1912 f(&*tagged as &(dyn Any + Send + Sync))
1913 })),
1914 AnyKeyPath::Writable(_) => {
1915 panic!("Tagged does not support writable keypaths (Tagged only implements Deref, not DerefMut)")
1916 }
1917 AnyKeyPath::FailableReadable(f) => AnyKeyPath::FailableReadable(Arc::new(move |root| {
1918 let tagged = root.downcast_ref::<Tagged<Root, Tag>>().unwrap();
1919 f(&*tagged as &(dyn Any + Send + Sync))
1920 })),
1921 AnyKeyPath::FailableWritable(_) => {
1922 panic!("Tagged does not support writable keypaths (Tagged only implements Deref, not DerefMut)")
1923 }
1924 AnyKeyPath::ReadableEnum { extract, embed } => AnyKeyPath::ReadableEnum {
1925 extract: Arc::new(move |root| {
1926 let tagged = root.downcast_ref::<Tagged<Root, Tag>>().unwrap();
1927 extract(&*tagged as &(dyn Any + Send + Sync))
1928 }),
1929 embed: Arc::new(move |value| {
1930 let inner = embed(value);
1931 Box::new(Tagged::<Root, Tag>::new(*inner.downcast::<Root>().unwrap())) as Box<dyn Any>
1932 }),
1933 },
1934 AnyKeyPath::WritableEnum { .. } => {
1935 panic!("Tagged does not support writable keypaths (Tagged only implements Deref, not DerefMut)")
1936 }
1937 AnyKeyPath::ReferenceWritable(_) => {
1938 panic!("Tagged does not support writable keypaths (Tagged only implements Deref, not DerefMut)")
1939 }
1940 AnyKeyPath::Owned(f) => AnyKeyPath::Owned(Arc::new(move |root| {
1941 let tagged = *root.downcast::<Tagged<Root, Tag>>().unwrap();
1942 f(Box::new((*tagged).clone()) as Box<dyn Any>)
1943 })),
1944 AnyKeyPath::FailableOwned(f) => AnyKeyPath::FailableOwned(Arc::new(move |root| {
1945 let tagged = *root.downcast::<Tagged<Root, Tag>>().unwrap();
1946 f(Box::new((*tagged).clone()) as Box<dyn Any>)
1947 })),
1948 }
1949 }
1950}
1951
1952impl<Root, Value> WithContainer<Root, Value> for KeyPaths<Root, Value> {
1954 #[inline]
1957 fn with_arc<F, R>(self, arc: &Arc<Root>, f: F) -> R
1958 where
1959 F: FnOnce(&Value) -> R,
1960 {
1961 match self {
1962 KeyPaths::Readable(get) => f(get(&**arc)),
1963 KeyPaths::FailableReadable(get) => {
1964 if let Some(value) = get(&**arc) {
1965 f(value)
1966 } else {
1967 panic!("FailableReadable keypath returned None for Arc")
1968 }
1969 }
1970 _ => panic!("with_arc only works with readable keypaths"),
1971 }
1972 }
1973
1974 #[inline]
1977 fn with_box<F, R>(self, boxed: &Box<Root>, f: F) -> R
1978 where
1979 F: FnOnce(&Value) -> R,
1980 {
1981 match self {
1982 KeyPaths::Readable(get) => f(get(&**boxed)),
1983 KeyPaths::FailableReadable(get) => {
1984 if let Some(value) = get(&**boxed) {
1985 f(value)
1986 } else {
1987 panic!("FailableReadable keypath returned None for Box")
1988 }
1989 }
1990 _ => panic!("with_box only works with readable keypaths"),
1991 }
1992 }
1993
1994 #[inline]
1997 fn with_box_mut<F, R>(self, boxed: &mut Box<Root>, f: F) -> R
1998 where
1999 F: FnOnce(&mut Value) -> R,
2000 {
2001 match self {
2002 KeyPaths::Writable(get) => f(get(&mut **boxed)),
2003 KeyPaths::FailableWritable(get) => {
2004 if let Some(value) = get(&mut **boxed) {
2005 f(value)
2006 } else {
2007 panic!("FailableWritable keypath returned None for Box")
2008 }
2009 }
2010 _ => panic!("with_box_mut only works with writable keypaths"),
2011 }
2012 }
2013
2014 #[inline]
2017 fn with_rc<F, R>(self, rc: &Rc<Root>, f: F) -> R
2018 where
2019 F: FnOnce(&Value) -> R,
2020 {
2021 match self {
2022 KeyPaths::Readable(get) => f(get(&**rc)),
2023 KeyPaths::FailableReadable(get) => {
2024 if let Some(value) = get(&**rc) {
2025 f(value)
2026 } else {
2027 panic!("FailableReadable keypath returned None for Rc")
2028 }
2029 }
2030 _ => panic!("with_rc only works with readable keypaths"),
2031 }
2032 }
2033
2034 #[inline]
2037 fn with_result<F, R, E>(self, result: &Result<Root, E>, f: F) -> Option<R>
2038 where
2039 F: FnOnce(&Value) -> R,
2040 {
2041 match self {
2042 KeyPaths::Readable(get) => {
2043 result.as_ref().ok().map(|root| f(get(root)))
2044 }
2045 KeyPaths::FailableReadable(get) => {
2046 result.as_ref().ok().and_then(|root| get(root).map(|v| f(v)))
2047 }
2048 _ => panic!("with_result only works with readable keypaths"),
2049 }
2050 }
2051
2052 #[inline]
2055 fn with_result_mut<F, R, E>(self, result: &mut Result<Root, E>, f: F) -> Option<R>
2056 where
2057 F: FnOnce(&mut Value) -> R,
2058 {
2059 match self {
2060 KeyPaths::Writable(get) => {
2061 result.as_mut().ok().map(|root| f(get(root)))
2062 }
2063 KeyPaths::FailableWritable(get) => {
2064 result.as_mut().ok().and_then(|root| get(root).map(|v| f(v)))
2065 }
2066 _ => panic!("with_result_mut only works with writable keypaths"),
2067 }
2068 }
2069
2070 #[inline]
2073 fn with_option<F, R>(self, option: &Option<Root>, f: F) -> Option<R>
2074 where
2075 F: FnOnce(&Value) -> R,
2076 {
2077 match self {
2078 KeyPaths::Readable(get) => {
2079 option.as_ref().map(|root| f(get(root)))
2080 }
2081 KeyPaths::FailableReadable(get) => {
2082 option.as_ref().and_then(|root| get(root).map(|v| f(v)))
2083 }
2084 _ => panic!("with_option only works with readable keypaths"),
2085 }
2086 }
2087
2088 #[inline]
2091 fn with_option_mut<F, R>(self, option: &mut Option<Root>, f: F) -> Option<R>
2092 where
2093 F: FnOnce(&mut Value) -> R,
2094 {
2095 match self {
2096 KeyPaths::Writable(get) => {
2097 option.as_mut().map(|root| f(get(root)))
2098 }
2099 KeyPaths::FailableWritable(get) => {
2100 option.as_mut().and_then(|root| get(root).map(|v| f(v)))
2101 }
2102 _ => panic!("with_option_mut only works with writable keypaths"),
2103 }
2104 }
2105
2106 #[inline]
2109 fn with_refcell<F, R>(self, refcell: &RefCell<Root>, f: F) -> Option<R>
2110 where
2111 F: FnOnce(&Value) -> R,
2112 {
2113 match self {
2114 KeyPaths::Readable(get) => {
2115 refcell.try_borrow().ok().map(|borrow| f(get(&*borrow)))
2116 }
2117 KeyPaths::FailableReadable(get) => {
2118 refcell.try_borrow().ok().and_then(|borrow| get(&*borrow).map(|v| f(v)))
2119 }
2120 _ => panic!("with_refcell only works with readable keypaths"),
2121 }
2122 }
2123
2124 #[inline]
2127 fn with_refcell_mut<F, R>(self, refcell: &RefCell<Root>, f: F) -> Option<R>
2128 where
2129 F: FnOnce(&mut Value) -> R,
2130 {
2131 match self {
2132 KeyPaths::Writable(get) => {
2133 refcell.try_borrow_mut().ok().map(|mut borrow| f(get(&mut *borrow)))
2134 }
2135 KeyPaths::FailableWritable(get) => {
2136 refcell.try_borrow_mut().ok().and_then(|mut borrow| get(&mut *borrow).map(|v| f(v)))
2137 }
2138 _ => panic!("with_refcell_mut only works with writable keypaths"),
2139 }
2140 }
2141
2142 #[cfg(feature = "tagged_core")]
2145 #[inline]
2146 fn with_tagged<F, R, Tag>(self, tagged: &Tagged<Root, Tag>, f: F) -> R
2147 where
2148 F: FnOnce(&Value) -> R,
2149 {
2150 match self {
2151 KeyPaths::Readable(get) => f(get(&**tagged)),
2152 KeyPaths::FailableReadable(get) => {
2153 get(&**tagged).map_or_else(|| panic!("Tagged value is None"), f)
2154 }
2155 KeyPaths::ReadableEnum { extract, .. } => {
2156 extract(&**tagged).map_or_else(|| panic!("Tagged value is None"), f)
2157 }
2158 _ => panic!("with_tagged only works with readable keypaths"),
2159 }
2160 }
2161
2162 #[inline]
2165 fn with_mutex<F, R>(self, mutex: &Mutex<Root>, f: F) -> Option<R>
2166 where
2167 F: FnOnce(&Value) -> R,
2168 {
2169 match self {
2170 KeyPaths::Readable(get) => {
2171 mutex.try_lock().ok().map(|guard| f(get(&*guard)))
2172 }
2173 KeyPaths::FailableReadable(get) => {
2174 mutex.try_lock().ok().and_then(|guard| get(&*guard).map(|v| f(v)))
2175 }
2176 _ => panic!("with_mutex only works with readable keypaths"),
2177 }
2178 }
2179
2180 #[inline]
2183 fn with_mutex_mut<F, R>(self, mutex: &mut Mutex<Root>, f: F) -> Option<R>
2184 where
2185 F: FnOnce(&mut Value) -> R,
2186 {
2187 match self {
2188 KeyPaths::Writable(get) => {
2189 mutex.try_lock().ok().map(|mut guard| f(get(&mut *guard)))
2190 }
2191 KeyPaths::FailableWritable(get) => {
2192 mutex.try_lock().ok().and_then(|mut guard| get(&mut *guard).map(|v| f(v)))
2193 }
2194 _ => panic!("with_mutex_mut only works with writable keypaths"),
2195 }
2196 }
2197
2198 #[inline]
2201 fn with_rwlock<F, R>(self, rwlock: &RwLock<Root>, f: F) -> Option<R>
2202 where
2203 F: FnOnce(&Value) -> R,
2204 {
2205 match self {
2206 KeyPaths::Readable(get) => {
2207 rwlock.try_read().ok().map(|guard| f(get(&*guard)))
2208 }
2209 KeyPaths::FailableReadable(get) => {
2210 rwlock.try_read().ok().and_then(|guard| get(&*guard).map(|v| f(v)))
2211 }
2212 _ => panic!("with_rwlock only works with readable keypaths"),
2213 }
2214 }
2215
2216 #[inline]
2219 fn with_rwlock_mut<F, R>(self, rwlock: &mut RwLock<Root>, f: F) -> Option<R>
2220 where
2221 F: FnOnce(&mut Value) -> R,
2222 {
2223 match self {
2224 KeyPaths::Writable(get) => {
2225 rwlock.try_write().ok().map(|mut guard| f(get(&mut *guard)))
2226 }
2227 KeyPaths::FailableWritable(get) => {
2228 rwlock.try_write().ok().and_then(|mut guard| get(&mut *guard).map(|v| f(v)))
2229 }
2230 _ => panic!("with_rwlock_mut only works with writable keypaths"),
2231 }
2232 }
2233
2234 fn with_arc_rwlock<F, R>(self, arc_rwlock: &Arc<RwLock<Root>>, f: F) -> Option<R>
2237 where
2238 F: FnOnce(&Value) -> R,
2239 {
2240 match self {
2241 KeyPaths::Readable(get) => {
2242 arc_rwlock.try_read().ok().map(|guard| f(get(&*guard)))
2243 }
2244 KeyPaths::FailableReadable(get) => {
2245 arc_rwlock.try_read().ok().and_then(|guard| get(&*guard).map(|v| f(v)))
2246 }
2247 _ => panic!("with_arc_rwlock only works with readable keypaths"),
2248 }
2249 }
2250
2251 fn with_arc_rwlock_mut<F, R>(self, arc_rwlock: &Arc<RwLock<Root>>, f: F) -> Option<R>
2254 where
2255 F: FnOnce(&mut Value) -> R,
2256 {
2257 match self {
2258 KeyPaths::Writable(get) => {
2259 arc_rwlock.try_write().ok().map(|mut guard| f(get(&mut *guard)))
2260 }
2261 KeyPaths::FailableWritable(get) => {
2262 arc_rwlock.try_write().ok().and_then(|mut guard| get(&mut *guard).map(|v| f(v)))
2263 }
2264 _ => panic!("with_arc_rwlock_mut only works with writable keypaths"),
2265 }
2266 }
2267}
2268
2269impl<Root, Mid> KeyPaths<Root, Mid>
2270where
2271 Root: 'static,
2272 Mid: 'static,
2273{
2274 #[inline]
2276 pub fn then<Value>(self, mid: KeyPaths<Mid, Value>) -> KeyPaths<Root, Value>
2277 where
2278 Value: 'static,
2279 {
2280 self.compose(mid)
2281 }
2282
2283 pub fn compose<Value>(self, mid: KeyPaths<Mid, Value>) -> KeyPaths<Root, Value>
2284 where
2285 Value: 'static,
2286 {
2287 use KeyPaths::*;
2288
2289 match (self, mid) {
2290 (Readable(f1), Readable(f2)) => Readable(Arc::new(move |r| f2(f1(r)))),
2291
2292 (Writable(f1), Writable(f2)) => Writable(Arc::new(move |r| f2(f1(r)))),
2293
2294 (FailableReadable(f1), Readable(f2)) => {
2295 FailableReadable(Arc::new(move |r| f1(r).map(|m| f2(m))))
2296 }
2297
2298 (Readable(f1), FailableReadable(f2)) => FailableReadable(Arc::new(move |r| f2(f1(r)))),
2299
2300 (FailableReadable(f1), FailableReadable(f2)) => {
2301 FailableReadable(Arc::new(move |r| f1(r).and_then(|m| f2(m))))
2302 }
2303
2304 (FailableWritable(f1), Writable(f2)) => {
2305 FailableWritable(Arc::new(move |r| f1(r).map(|m| f2(m))))
2306 }
2307
2308 (Writable(f1), FailableWritable(f2)) => FailableWritable(Arc::new(move |r| f2(f1(r)))),
2309
2310 (FailableWritable(f1), FailableWritable(f2)) => {
2311 FailableWritable(Arc::new(move |r| f1(r).and_then(|m| f2(m))))
2312 }
2313 (FailableReadable(f1), ReadableEnum { extract, .. }) => {
2314 FailableReadable(Arc::new(move |r| f1(r).and_then(|m| extract(m))))
2315 }
2316 (ReadableEnum { extract, .. }, Readable(f2)) => {
2320 FailableReadable(Arc::new(move |r| extract(r).map(|m| f2(m))))
2321 }
2322
2323 (ReadableEnum { extract, .. }, FailableReadable(f2)) => {
2324 FailableReadable(Arc::new(move |r| extract(r).and_then(|m| f2(m))))
2325 }
2326
2327 (WritableEnum { extract, .. }, Readable(f2)) => {
2328 FailableReadable(Arc::new(move |r| extract(r).map(|m| f2(m))))
2329 }
2330
2331 (WritableEnum { extract, .. }, FailableReadable(f2)) => {
2332 FailableReadable(Arc::new(move |r| extract(r).and_then(|m| f2(m))))
2333 }
2334
2335 (WritableEnum { extract_mut, .. }, Writable(f2)) => {
2336 FailableWritable(Arc::new(move |r| extract_mut(r).map(|m| f2(m))))
2337 }
2338
2339 (
2340 FailableWritable(f_root_mid),
2341 WritableEnum {
2342 extract_mut: exm_mid_val,
2343 ..
2344 },
2345 ) => {
2346 FailableWritable(Arc::new(move |r: &mut Root| {
2347 let intermediate_mid_ref = f_root_mid(r);
2350
2351 intermediate_mid_ref.and_then(|intermediate_mid| exm_mid_val(intermediate_mid))
2354 }))
2355 }
2356
2357 (WritableEnum { extract_mut, .. }, FailableWritable(f2)) => {
2358 FailableWritable(Arc::new(move |r| extract_mut(r).and_then(|m| f2(m))))
2359 }
2360
2361 (Writable(f1), WritableEnum { extract_mut, .. }) => {
2363 FailableWritable(Arc::new(move |r: &mut Root| {
2364 let mid: &mut Mid = f1(r);
2365 extract_mut(mid)
2366 }))
2367 }
2368
2369 (
2370 ReadableEnum {
2371 extract: ex1,
2372 embed: em1,
2373 },
2374 ReadableEnum {
2375 extract: ex2,
2376 embed: em2,
2377 },
2378 ) => ReadableEnum {
2379 extract: Arc::new(move |r| ex1(r).and_then(|m| ex2(m))),
2380 embed: Arc::new(move |v| em1(em2(v))),
2381 },
2382
2383 (
2384 WritableEnum {
2385 extract: ex1,
2386 extract_mut: _,
2387 embed: em1,
2388 },
2389 ReadableEnum {
2390 extract: ex2,
2391 embed: em2,
2392 },
2393 ) => ReadableEnum {
2394 extract: Arc::new(move |r| ex1(r).and_then(|m| ex2(m))),
2395 embed: Arc::new(move |v| em1(em2(v))),
2396 },
2397
2398 (
2399 WritableEnum {
2400 extract: ex1,
2401 extract_mut: exm1,
2402 embed: em1,
2403 },
2404 WritableEnum {
2405 extract: ex2,
2406 extract_mut: exm2,
2407 embed: em2,
2408 },
2409 ) => WritableEnum {
2410 extract: Arc::new(move |r| ex1(r).and_then(|m| ex2(m))),
2411 extract_mut: Arc::new(move |r| exm1(r).and_then(|m| exm2(m))),
2412 embed: Arc::new(move |v| em1(em2(v))),
2413 },
2414
2415
2416 (Owned(f1), Owned(f2)) => {
2418 Owned(Arc::new(move |r| f2(f1(r))))
2419 }
2420 (FailableOwned(f1), Owned(f2)) => {
2421 FailableOwned(Arc::new(move |r| f1(r).map(|m| f2(m))))
2422 }
2423 (Owned(f1), FailableOwned(f2)) => {
2424 FailableOwned(Arc::new(move |r| f2(f1(r))))
2425 }
2426 (FailableOwned(f1), FailableOwned(f2)) => {
2427 FailableOwned(Arc::new(move |r| f1(r).and_then(|m| f2(m))))
2428 }
2429
2430 (a, b) => panic!(
2435 "Unsupported composition: {:?} then {:?}",
2436 kind_name(&a),
2437 kind_name(&b)
2438 ),
2439 }
2440 }
2441
2442 #[inline]
2444 pub fn kind_name(&self) -> &'static str {
2445 kind_name(self)
2446 }
2447}
2448
2449fn kind_name<Root, Value>(k: &KeyPaths<Root, Value>) -> &'static str {
2450 use KeyPaths::*;
2451 match k {
2452 Readable(_) => "Readable",
2453 Writable(_) => "Writable",
2454 FailableReadable(_) => "FailableReadable",
2455 FailableWritable(_) => "FailableWritable",
2456 ReadableEnum { .. } => "ReadableEnum",
2457 WritableEnum { .. } => "WritableEnum",
2458 ReferenceWritable(_) => "ReferenceWritable",
2459 Owned(_) => "Owned",
2461 FailableOwned(_) => "FailableOwned",
2462 }
2463}
2464
2465pub fn compose<Root, Mid, Value>(
2474 kp1: KeyPaths<Root, Mid>,
2475 kp2: KeyPaths<Mid, Value>,
2476) -> KeyPaths<Root, Value>
2477where
2478 Root: 'static,
2479 Mid: 'static,
2480 Value: 'static,
2481{
2482 kp1.compose(kp2)
2483}
2484
2485#[macro_export]
2488macro_rules! readable_enum_macro {
2489 ($enum:path, $variant:ident) => {{
2491 $crate::KeyPaths::readable_enum(
2492 |_| <$enum>::$variant,
2493 |e: &$enum| match e {
2494 <$enum>::$variant => Some(&()),
2495 _ => None,
2496 },
2497 )
2498 }};
2499 ($enum:path, $variant:ident($inner:ty)) => {{
2501 $crate::KeyPaths::readable_enum(
2502 |v: $inner| <$enum>::$variant(v),
2503 |e: &$enum| match e {
2504 <$enum>::$variant(v) => Some(v),
2505 _ => None,
2506 },
2507 )
2508 }};
2509}
2510
2511#[macro_export]
2512macro_rules! writable_enum_macro {
2513 ($enum:path, $variant:ident) => {{
2515 $crate::KeyPaths::writable_enum(
2516 |_| <$enum>::$variant,
2517 |e: &$enum| match e {
2518 <$enum>::$variant => Some(&()),
2519 _ => None,
2520 },
2521 |e: &mut $enum| match e {
2522 <$enum>::$variant => Some(&mut ()),
2523 _ => None,
2524 },
2525 )
2526 }};
2527 ($enum:path, $variant:ident($inner:ty)) => {{
2529 $crate::KeyPaths::writable_enum(
2530 |v: $inner| <$enum>::$variant(v),
2531 |e: &$enum| match e {
2532 <$enum>::$variant(v) => Some(v),
2533 _ => None,
2534 },
2535 |e: &mut $enum| match e {
2536 <$enum>::$variant(v) => Some(v),
2537 _ => None,
2538 },
2539 )
2540 }};
2541}