1use std::rc::Rc;
2use std::sync::{Arc, Mutex, RwLock};
3use std::cell::RefCell;
4
5#[cfg(feature = "tagged_core")]
6use tagged_core::Tagged;
7
8pub trait WithContainer<Root, Value> {
12 fn with_arc<F, R>(self, arc: &Arc<Root>, f: F) -> R
15 where
16 F: FnOnce(&Value) -> R;
17
18 fn with_box<F, R>(self, boxed: &Box<Root>, f: F) -> R
21 where
22 F: FnOnce(&Value) -> R;
23
24 fn with_box_mut<F, R>(self, boxed: &mut Box<Root>, f: F) -> R
27 where
28 F: FnOnce(&mut Value) -> R;
29
30 fn with_rc<F, R>(self, rc: &Rc<Root>, f: F) -> R
33 where
34 F: FnOnce(&Value) -> R;
35
36 fn with_result<F, R, E>(self, result: &Result<Root, E>, f: F) -> Option<R>
39 where
40 F: FnOnce(&Value) -> R;
41
42 fn with_result_mut<F, R, E>(self, result: &mut Result<Root, E>, f: F) -> Option<R>
45 where
46 F: FnOnce(&mut Value) -> R;
47
48 fn with_option<F, R>(self, option: &Option<Root>, f: F) -> Option<R>
51 where
52 F: FnOnce(&Value) -> R;
53
54 fn with_option_mut<F, R>(self, option: &mut Option<Root>, f: F) -> Option<R>
57 where
58 F: FnOnce(&mut Value) -> R;
59
60 fn with_refcell<F, R>(self, refcell: &RefCell<Root>, f: F) -> Option<R>
63 where
64 F: FnOnce(&Value) -> R;
65
66 fn with_refcell_mut<F, R>(self, refcell: &RefCell<Root>, f: F) -> Option<R>
69 where
70 F: FnOnce(&mut Value) -> R;
71
72 #[cfg(feature = "tagged_core")]
75 fn with_tagged<F, R, Tag>(self, tagged: &Tagged<Root, Tag>, f: F) -> R
76 where
77 F: FnOnce(&Value) -> R;
78
79 fn with_mutex<F, R>(self, mutex: &Mutex<Root>, f: F) -> Option<R>
82 where
83 F: FnOnce(&Value) -> R;
84
85 fn with_mutex_mut<F, R>(self, mutex: &mut Mutex<Root>, f: F) -> Option<R>
88 where
89 F: FnOnce(&mut Value) -> R;
90
91 fn with_rwlock<F, R>(self, rwlock: &RwLock<Root>, f: F) -> Option<R>
94 where
95 F: FnOnce(&Value) -> R;
96
97 fn with_rwlock_mut<F, R>(self, rwlock: &mut RwLock<Root>, f: F) -> Option<R>
100 where
101 F: FnOnce(&mut Value) -> R;
102
103 fn with_arc_rwlock<F, R>(self, arc_rwlock: &Arc<RwLock<Root>>, f: F) -> Option<R>
106 where
107 F: FnOnce(&Value) -> R;
108
109 fn with_arc_rwlock_mut<F, R>(self, arc_rwlock: &Arc<RwLock<Root>>, f: F) -> Option<R>
112 where
113 F: FnOnce(&mut Value) -> R;
114}
115
116#[derive(Clone)]
117pub enum KeyPaths<Root, Value> {
120 Readable(Rc<dyn for<'a> Fn(&'a Root) -> &'a Value>),
121 ReadableEnum {
122 extract: Rc<dyn for<'a> Fn(&'a Root) -> Option<&'a Value>>,
123 embed: Rc<dyn Fn(Value) -> Root>,
124 },
125 FailableReadable(Rc<dyn for<'a> Fn(&'a Root) -> Option<&'a Value>>),
126
127 Writable(Rc<dyn for<'a> Fn(&'a mut Root) -> &'a mut Value>),
128 FailableWritable(Rc<dyn for<'a> Fn(&'a mut Root) -> Option<&'a mut Value>>),
129 WritableEnum {
130 extract: Rc<dyn for<'a> Fn(&'a Root) -> Option<&'a Value>>,
131 extract_mut: Rc<dyn for<'a> Fn(&'a mut Root) -> Option<&'a mut Value>>,
132 embed: Rc<dyn Fn(Value) -> Root>,
133 },
134
135
136
137 Owned(Rc<dyn Fn(Root) -> Value>),
139 FailableOwned(Rc<dyn Fn(Root) -> Option<Value>>),
140}
141
142impl<Root, Value> KeyPaths<Root, Value> {
143 #[inline]
144 pub fn readable(get: impl for<'a> Fn(&'a Root) -> &'a Value + 'static) -> Self {
145 Self::Readable(Rc::new(get))
146 }
147
148 #[inline]
149 pub fn writable(get_mut: impl for<'a> Fn(&'a mut Root) -> &'a mut Value + 'static) -> Self {
150 Self::Writable(Rc::new(get_mut))
151 }
152
153 #[inline]
154 pub fn failable_readable(
155 get: impl for<'a> Fn(&'a Root) -> Option<&'a Value> + 'static,
156 ) -> Self {
157 Self::FailableReadable(Rc::new(get))
158 }
159
160 #[inline]
161 pub fn failable_writable(
162 get_mut: impl for<'a> Fn(&'a mut Root) -> Option<&'a mut Value> + 'static,
163 ) -> Self {
164 Self::FailableWritable(Rc::new(get_mut))
165 }
166
167 #[inline]
168 pub fn readable_enum(
169 embed: impl Fn(Value) -> Root + 'static,
170 extract: impl for<'a> Fn(&'a Root) -> Option<&'a Value> + 'static,
171 ) -> Self {
172 Self::ReadableEnum {
173 extract: Rc::new(extract),
174 embed: Rc::new(embed),
175 }
176 }
177
178 #[inline]
179 pub fn writable_enum(
180 embed: impl Fn(Value) -> Root + 'static,
181 extract: impl for<'a> Fn(&'a Root) -> Option<&'a Value> + 'static,
182 extract_mut: impl for<'a> Fn(&'a mut Root) -> Option<&'a mut Value> + 'static,
183 ) -> Self {
184 Self::WritableEnum {
185 extract: Rc::new(extract),
186 embed: Rc::new(embed),
187 extract_mut: Rc::new(extract_mut),
188 }
189 }
190
191
192 #[inline]
194 pub fn owned(get: impl Fn(Root) -> Value + 'static) -> Self {
195 Self::Owned(Rc::new(get))
196 }
197
198 #[inline]
199 pub fn failable_owned(get: impl Fn(Root) -> Option<Value> + 'static) -> Self {
200 Self::FailableOwned(Rc::new(get))
201 }
202
203 #[inline]
204 pub fn owned_writable(get: impl Fn(Root) -> Value + 'static) -> Self {
205 Self::Owned(Rc::new(get))
206 }
207
208 #[inline]
209 pub fn failable_owned_writable(get: impl Fn(Root) -> Option<Value> + 'static) -> Self {
210 Self::FailableOwned(Rc::new(get))
211 }
212}
213
214impl<Root, Value> KeyPaths<Root, Value> {
215 #[inline]
217 pub fn get<'a>(&'a self, root: &'a Root) -> Option<&'a Value> {
218 match self {
219 KeyPaths::Readable(f) => Some(f(root)),
220 KeyPaths::Writable(_) => None, KeyPaths::FailableReadable(f) => f(root),
222 KeyPaths::FailableWritable(_) => None, KeyPaths::ReadableEnum { extract, .. } => extract(root),
224 KeyPaths::WritableEnum { extract, .. } => extract(root),
225 KeyPaths::Owned(_) => None, KeyPaths::FailableOwned(_) => None, }
229 }
230
231 #[inline]
234 pub fn get_ref<'a, 'b>(&'a self, root: &'b &Root) -> Option<&'b Value>
235 where
236 'a: 'b,
237 {
238 self.get(*root)
239 }
240
241 #[inline]
243 pub fn get_mut<'a>(&'a self, root: &'a mut Root) -> Option<&'a mut Value> {
244 match self {
245 KeyPaths::Readable(_) => None, KeyPaths::Writable(f) => Some(f(root)),
247 KeyPaths::FailableReadable(_) => None, KeyPaths::FailableWritable(f) => f(root),
249 KeyPaths::ReadableEnum { .. } => None, KeyPaths::WritableEnum { extract_mut, .. } => extract_mut(root),
251 KeyPaths::Owned(_) => None, KeyPaths::FailableOwned(_) => None, }
255 }
256
257 #[inline]
260 pub fn get_mut_ref<'a, 'b>(&'a self, root: &'b mut &mut Root) -> Option<&'b mut Value>
261 where
262 'a: 'b,
263 {
264 self.get_mut(*root)
265 }
266
267 #[inline]
274 pub fn for_arc(self) -> KeyPaths<Arc<Root>, Value>
275 where
276 Root: 'static,
277 Value: 'static,
278 {
279 match self {
280 KeyPaths::Readable(f) => KeyPaths::Readable(Rc::new(move |root: &Arc<Root>| {
281 f(&**root)
282 })),
283 KeyPaths::Writable(_) => {
284 panic!("Cannot create writable keypath for Arc (Arc is immutable)")
286 }
287 KeyPaths::FailableReadable(f) => {
288 KeyPaths::FailableReadable(Rc::new(move |root: &Arc<Root>| f(&**root)))
289 }
290 KeyPaths::ReadableEnum { extract, embed } => KeyPaths::ReadableEnum {
291 extract: Rc::new(move |root: &Arc<Root>| extract(&**root)),
292 embed: Rc::new(move |value| Arc::new(embed(value))),
293 },
294 other => panic!("Unsupported keypath variant for Arc adapter: {:?}", kind_name(&other)),
295 }
296 }
297
298 #[inline]
301 pub fn for_box(self) -> KeyPaths<Box<Root>, Value>
302 where
303 Root: 'static,
304 Value: 'static,
305 {
306 match self {
307 KeyPaths::Readable(f) => KeyPaths::Readable(Rc::new(move |root: &Box<Root>| {
308 f(&**root)
309 })),
310 KeyPaths::Writable(f) => KeyPaths::Writable(Rc::new(move |root: &mut Box<Root>| {
311 f(&mut **root)
312 })),
313 KeyPaths::FailableReadable(f) => {
314 KeyPaths::FailableReadable(Rc::new(move |root: &Box<Root>| f(&**root)))
315 }
316 KeyPaths::FailableWritable(f) => {
317 KeyPaths::FailableWritable(Rc::new(move |root: &mut Box<Root>| f(&mut **root)))
318 }
319 KeyPaths::ReadableEnum { extract, embed } => KeyPaths::ReadableEnum {
320 extract: Rc::new(move |root: &Box<Root>| extract(&**root)),
321 embed: Rc::new(move |value| Box::new(embed(value))),
322 },
323 KeyPaths::WritableEnum { extract, extract_mut, embed } => KeyPaths::WritableEnum {
324 extract: Rc::new(move |root: &Box<Root>| extract(&**root)),
325 extract_mut: Rc::new(move |root: &mut Box<Root>| extract_mut(&mut **root)),
326 embed: Rc::new(move |value| Box::new(embed(value))),
327 },
328 other => panic!("Unsupported keypath variant for Box adapter: {:?}", kind_name(&other)),
329 }
330 }
331
332 #[inline]
335 pub fn for_rc(self) -> KeyPaths<Rc<Root>, Value>
336 where
337 Root: 'static,
338 Value: 'static,
339 {
340 match self {
341 KeyPaths::Readable(f) => KeyPaths::Readable(Rc::new(move |root: &Rc<Root>| {
342 f(&**root)
343 })),
344 KeyPaths::Writable(_) => {
345 panic!("Cannot create writable keypath for Rc (Rc is immutable)")
347 }
348 KeyPaths::FailableReadable(f) => {
349 KeyPaths::FailableReadable(Rc::new(move |root: &Rc<Root>| f(&**root)))
350 }
351 KeyPaths::ReadableEnum { extract, embed } => KeyPaths::ReadableEnum {
352 extract: Rc::new(move |root: &Rc<Root>| extract(&**root)),
353 embed: Rc::new(move |value| Rc::new(embed(value))),
354 },
355 other => panic!("Unsupported keypath variant for Rc adapter: {:?}", kind_name(&other)),
356 }
357 }
358
359 #[inline]
363 pub fn for_result<E>(self) -> KeyPaths<Result<Root, E>, Value>
364 where
365 Root: 'static,
366 Value: 'static,
367 E: 'static,
368 {
369 match self {
370 KeyPaths::Readable(f) => KeyPaths::FailableReadable(Rc::new(move |root: &Result<Root, E>| {
371 root.as_ref().ok().map(|r| f(r))
372 })),
373 KeyPaths::Writable(f) => KeyPaths::FailableWritable(Rc::new(move |root: &mut Result<Root, E>| {
374 root.as_mut().ok().map(|r| f(r))
375 })),
376 KeyPaths::FailableReadable(f) => {
377 KeyPaths::FailableReadable(Rc::new(move |root: &Result<Root, E>| {
378 root.as_ref().ok().and_then(|r| f(r))
379 }))
380 }
381 KeyPaths::FailableWritable(f) => {
382 KeyPaths::FailableWritable(Rc::new(move |root: &mut Result<Root, E>| {
383 root.as_mut().ok().and_then(|r| f(r))
384 }))
385 }
386 KeyPaths::ReadableEnum { extract, embed } => KeyPaths::ReadableEnum {
387 extract: Rc::new(move |root: &Result<Root, E>| {
388 root.as_ref().ok().and_then(|r| extract(r))
389 }),
390 embed: Rc::new(move |value| Ok(embed(value))),
391 },
392 KeyPaths::WritableEnum { extract, extract_mut, embed } => KeyPaths::WritableEnum {
393 extract: Rc::new(move |root: &Result<Root, E>| {
394 root.as_ref().ok().and_then(|r| extract(r))
395 }),
396 extract_mut: Rc::new(move |root: &mut Result<Root, E>| {
397 root.as_mut().ok().and_then(|r| extract_mut(r))
398 }),
399 embed: Rc::new(move |value| Ok(embed(value))),
400 },
401 other => panic!("Unsupported keypath variant for Result adapter: {:?}", kind_name(&other)),
402 }
403 }
404
405 #[inline]
409 pub fn for_option(self) -> KeyPaths<Option<Root>, Value>
410 where
411 Root: 'static,
412 Value: 'static,
413 {
414 match self {
415 KeyPaths::Readable(f) => KeyPaths::FailableReadable(Rc::new(move |root: &Option<Root>| {
416 root.as_ref().map(|r| f(r))
417 })),
418 KeyPaths::Writable(f) => KeyPaths::FailableWritable(Rc::new(move |root: &mut Option<Root>| {
419 root.as_mut().map(|r| f(r))
420 })),
421 KeyPaths::FailableReadable(f) => {
422 KeyPaths::FailableReadable(Rc::new(move |root: &Option<Root>| {
423 root.as_ref().and_then(|r| f(r))
424 }))
425 }
426 KeyPaths::FailableWritable(f) => {
427 KeyPaths::FailableWritable(Rc::new(move |root: &mut Option<Root>| {
428 root.as_mut().and_then(|r| f(r))
429 }))
430 }
431 KeyPaths::ReadableEnum { extract, embed } => KeyPaths::ReadableEnum {
432 extract: Rc::new(move |root: &Option<Root>| {
433 root.as_ref().and_then(|r| extract(r))
434 }),
435 embed: Rc::new(move |value| Some(embed(value))),
436 },
437 KeyPaths::WritableEnum { extract, extract_mut, embed } => KeyPaths::WritableEnum {
438 extract: Rc::new(move |root: &Option<Root>| {
439 root.as_ref().and_then(|r| extract(r))
440 }),
441 extract_mut: Rc::new(move |root: &mut Option<Root>| {
442 root.as_mut().and_then(|r| extract_mut(r))
443 }),
444 embed: Rc::new(move |value| Some(embed(value))),
445 },
446 other => panic!("Unsupported keypath variant for Option adapter: {:?}", kind_name(&other)),
447 }
448 }
449
450 #[inline]
454 pub fn for_arc_rwlock(self) -> KeyPaths<Arc<RwLock<Root>>, Value>
455 where
456 Root: 'static,
457 Value: Clone + 'static,
458 {
459 match self {
460 KeyPaths::Readable(f) => KeyPaths::FailableOwned(Rc::new(move |root: Arc<RwLock<Root>>| {
461 let guard = root.read().ok()?;
462 Some(f(&*guard).clone())
463 })),
464 KeyPaths::Writable(_) => {
465 panic!("Cannot create writable keypath for Arc<RwLock> (use with_arc_rwlock_mut instead)")
467 }
468 KeyPaths::FailableReadable(f) => {
469 KeyPaths::FailableOwned(Rc::new(move |root: Arc<RwLock<Root>>| {
470 let guard = root.read().ok()?;
471 f(&*guard).map(|v| v.clone())
472 }))
473 }
474 KeyPaths::ReadableEnum { extract, embed: _ } => KeyPaths::FailableOwned(Rc::new(move |root: Arc<RwLock<Root>>| {
475 let guard = root.read().ok()?;
476 extract(&*guard).map(|v| v.clone())
477 })),
478 other => panic!("Unsupported keypath variant for Arc<RwLock> adapter: {:?}", kind_name(&other)),
479 }
480 }
481
482 #[inline]
486 pub fn for_arc_mutex(self) -> KeyPaths<Arc<Mutex<Root>>, Value>
487 where
488 Root: 'static,
489 Value: Clone + 'static,
490 {
491 match self {
492 KeyPaths::Readable(f) => KeyPaths::FailableOwned(Rc::new(move |root: Arc<Mutex<Root>>| {
493 let guard = root.lock().ok()?;
494 Some(f(&*guard).clone())
495 })),
496 KeyPaths::Writable(_) => {
497 panic!("Cannot create writable keypath for Arc<Mutex> (use with_arc_mutex_mut instead)")
499 }
500 KeyPaths::FailableReadable(f) => {
501 KeyPaths::FailableOwned(Rc::new(move |root: Arc<Mutex<Root>>| {
502 let guard = root.lock().ok()?;
503 f(&*guard).map(|v| v.clone())
504 }))
505 }
506 KeyPaths::ReadableEnum { extract, embed: _ } => KeyPaths::FailableOwned(Rc::new(move |root: Arc<Mutex<Root>>| {
507 let guard = root.lock().ok()?;
508 extract(&*guard).map(|v| v.clone())
509 })),
510 other => panic!("Unsupported keypath variant for Arc<Mutex> adapter: {:?}", kind_name(&other)),
511 }
512 }
513
514 #[cfg(feature = "parking_lot")]
519 #[inline]
520 pub fn for_arc_parking_mutex(self) -> KeyPaths<Arc<parking_lot::Mutex<Root>>, Value>
521 where
522 Root: 'static,
523 Value: Clone + 'static,
524 {
525 match self {
526 KeyPaths::Readable(f) => KeyPaths::FailableOwned(Rc::new(move |root: Arc<parking_lot::Mutex<Root>>| {
527 let guard = root.lock();
528 Some(f(&*guard).clone())
529 })),
530 KeyPaths::Writable(_) => {
531 panic!("Cannot create writable keypath for Arc<parking_lot::Mutex> (use with_arc_parking_mutex_mut instead)")
533 }
534 KeyPaths::FailableReadable(f) => {
535 KeyPaths::FailableOwned(Rc::new(move |root: Arc<parking_lot::Mutex<Root>>| {
536 let guard = root.lock();
537 f(&*guard).map(|v| v.clone())
538 }))
539 }
540 KeyPaths::ReadableEnum { extract, embed: _ } => KeyPaths::FailableOwned(Rc::new(move |root: Arc<parking_lot::Mutex<Root>>| {
541 let guard = root.lock();
542 extract(&*guard).map(|v| v.clone())
543 })),
544 other => panic!("Unsupported keypath variant for Arc<parking_lot::Mutex> adapter: {:?}", kind_name(&other)),
545 }
546 }
547
548 #[cfg(feature = "parking_lot")]
553 #[inline]
554 pub fn for_arc_parking_rwlock(self) -> KeyPaths<Arc<parking_lot::RwLock<Root>>, Value>
555 where
556 Root: 'static,
557 Value: Clone + 'static,
558 {
559 match self {
560 KeyPaths::Readable(f) => KeyPaths::FailableOwned(Rc::new(move |root: Arc<parking_lot::RwLock<Root>>| {
561 let guard = root.read();
562 Some(f(&*guard).clone())
563 })),
564 KeyPaths::Writable(_) => {
565 panic!("Cannot create writable keypath for Arc<parking_lot::RwLock> (use with_arc_parking_rwlock_mut instead)")
567 }
568 KeyPaths::FailableReadable(f) => {
569 KeyPaths::FailableOwned(Rc::new(move |root: Arc<parking_lot::RwLock<Root>>| {
570 let guard = root.read();
571 f(&*guard).map(|v| v.clone())
572 }))
573 }
574 KeyPaths::ReadableEnum { extract, embed: _ } => KeyPaths::FailableOwned(Rc::new(move |root: Arc<parking_lot::RwLock<Root>>| {
575 let guard = root.read();
576 extract(&*guard).map(|v| v.clone())
577 })),
578 other => panic!("Unsupported keypath variant for Arc<parking_lot::RwLock> adapter: {:?}", kind_name(&other)),
579 }
580 }
581
582 #[cfg(feature = "tagged_core")]
587 #[inline]
588 pub fn for_tagged<Tag>(self) -> KeyPaths<Tagged<Root, Tag>, Value>
589 where
590 Root: Clone + 'static,
591 Value: 'static,
592 Tag: 'static,
593 {
594 match self {
595 KeyPaths::Readable(f) => KeyPaths::Readable(Rc::new(move |root: &Tagged<Root, Tag>| {
596 f(&**root)
597 })),
598 KeyPaths::Writable(_) => {
599 panic!("Tagged does not support writable keypaths (Tagged only implements Deref, not DerefMut)")
600 }
601 KeyPaths::FailableReadable(f) => KeyPaths::FailableReadable(Rc::new(move |root: &Tagged<Root, Tag>| {
602 f(&**root)
603 })),
604 KeyPaths::FailableWritable(_) => {
605 panic!("Tagged does not support writable keypaths (Tagged only implements Deref, not DerefMut)")
606 }
607 KeyPaths::Owned(f) => KeyPaths::Owned(Rc::new(move |root: Tagged<Root, Tag>| {
608 f((*root).clone())
610 })),
611 KeyPaths::FailableOwned(f) => KeyPaths::FailableOwned(Rc::new(move |root: Tagged<Root, Tag>| {
612 f((*root).clone())
613 })),
614 KeyPaths::ReadableEnum { extract, embed } => KeyPaths::ReadableEnum {
615 extract: Rc::new(move |root: &Tagged<Root, Tag>| {
616 extract(&**root)
617 }),
618 embed: Rc::new(move |value: Value| {
619 Tagged::new(embed(value))
620 }),
621 },
622 KeyPaths::WritableEnum { .. } => {
623 panic!("Tagged does not support writable keypaths (Tagged only implements Deref, not DerefMut)")
624 }
625 }
626 }
627
628 pub fn embed(&self, value: Value) -> Option<Root>
632 where
633 Value: Clone,
634 {
635 match self {
636 KeyPaths::ReadableEnum { embed, .. } => Some(embed(value)),
637 _ => None,
638 }
639 }
640
641 pub fn embed_mut(&self, value: Value) -> Option<Root>
642 where
643 Value: Clone,
644 {
645 match self {
646 KeyPaths::WritableEnum { embed, .. } => Some(embed(value)),
647 _ => None,
648 }
649 }
650
651
652 #[inline]
656 pub fn get_owned(self, root: Root) -> Value {
657 match self {
658 KeyPaths::Owned(f) => f(root),
659 _ => panic!("get_owned only works with owned keypaths"),
660 }
661 }
662
663 #[inline]
665 pub fn get_failable_owned(self, root: Root) -> Option<Value> {
666 match self {
667 KeyPaths::FailableOwned(f) => f(root),
668 _ => panic!("get_failable_owned only works with failable owned keypaths"),
669 }
670 }
671
672 pub fn iter<'a, T>(&'a self, root: &'a Root) -> Option<<&'a Value as IntoIterator>::IntoIter>
674 where
675 &'a Value: IntoIterator<Item = &'a T>,
676 T: 'a,
677 {
678 self.get(root).map(|v| v.into_iter())
679 }
680
681 pub fn iter_mut<'a, T>(
683 &'a self,
684 root: &'a mut Root,
685 ) -> Option<<&'a mut Value as IntoIterator>::IntoIter>
686 where
687 &'a mut Value: IntoIterator<Item = &'a mut T>,
688 T: 'a,
689 {
690 self.get_mut(root).map(|v| v.into_iter())
691 }
692
693 #[inline]
695 pub fn into_iter<T>(self, root: Root) -> Option<<Value as IntoIterator>::IntoIter>
696 where
697 Value: IntoIterator<Item = T> + Clone,
698 {
699 match self {
700 KeyPaths::Readable(f) => Some(f(&root).clone().into_iter()), KeyPaths::Writable(_) => None,
702 KeyPaths::FailableReadable(f) => f(&root).map(|v| v.clone().into_iter()),
703 KeyPaths::FailableWritable(_) => None,
704 KeyPaths::ReadableEnum { extract, .. } => extract(&root).map(|v| v.clone().into_iter()),
705 KeyPaths::WritableEnum { extract, .. } => extract(&root).map(|v| v.clone().into_iter()),
706 KeyPaths::Owned(f) => Some(f(root).into_iter()),
708 KeyPaths::FailableOwned(f) => f(root).map(|v| v.into_iter()),
709 }
710 }
711}
712
713impl<Root, Value> WithContainer<Root, Value> for KeyPaths<Root, Value> {
715 #[inline]
718 fn with_arc<F, R>(self, arc: &Arc<Root>, f: F) -> R
719 where
720 F: FnOnce(&Value) -> R,
721 {
722 match self {
723 KeyPaths::Readable(get) => f(get(&**arc)),
724 KeyPaths::FailableReadable(get) => {
725 if let Some(value) = get(&**arc) {
726 f(value)
727 } else {
728 panic!("FailableReadable keypath returned None for Arc")
729 }
730 }
731 _ => panic!("with_arc only works with readable keypaths"),
732 }
733 }
734
735 #[inline]
738 fn with_box<F, R>(self, boxed: &Box<Root>, f: F) -> R
739 where
740 F: FnOnce(&Value) -> R,
741 {
742 match self {
743 KeyPaths::Readable(get) => f(get(&**boxed)),
744 KeyPaths::FailableReadable(get) => {
745 if let Some(value) = get(&**boxed) {
746 f(value)
747 } else {
748 panic!("FailableReadable keypath returned None for Box")
749 }
750 }
751 _ => panic!("with_box only works with readable keypaths"),
752 }
753 }
754
755 #[inline]
758 fn with_box_mut<F, R>(self, boxed: &mut Box<Root>, f: F) -> R
759 where
760 F: FnOnce(&mut Value) -> R,
761 {
762 match self {
763 KeyPaths::Writable(get) => f(get(&mut **boxed)),
764 KeyPaths::FailableWritable(get) => {
765 if let Some(value) = get(&mut **boxed) {
766 f(value)
767 } else {
768 panic!("FailableWritable keypath returned None for Box")
769 }
770 }
771 _ => panic!("with_box_mut only works with writable keypaths"),
772 }
773 }
774
775 #[inline]
778 fn with_rc<F, R>(self, rc: &Rc<Root>, f: F) -> R
779 where
780 F: FnOnce(&Value) -> R,
781 {
782 match self {
783 KeyPaths::Readable(get) => f(get(&**rc)),
784 KeyPaths::FailableReadable(get) => {
785 if let Some(value) = get(&**rc) {
786 f(value)
787 } else {
788 panic!("FailableReadable keypath returned None for Rc")
789 }
790 }
791 _ => panic!("with_rc only works with readable keypaths"),
792 }
793 }
794
795 #[inline]
798 fn with_result<F, R, E>(self, result: &Result<Root, E>, f: F) -> Option<R>
799 where
800 F: FnOnce(&Value) -> R,
801 {
802 match self {
803 KeyPaths::Readable(get) => {
804 result.as_ref().ok().map(|root| f(get(root)))
805 }
806 KeyPaths::FailableReadable(get) => {
807 result.as_ref().ok().and_then(|root| get(root).map(|v| f(v)))
808 }
809 _ => panic!("with_result only works with readable keypaths"),
810 }
811 }
812
813 #[inline]
816 fn with_result_mut<F, R, E>(self, result: &mut Result<Root, E>, f: F) -> Option<R>
817 where
818 F: FnOnce(&mut Value) -> R,
819 {
820 match self {
821 KeyPaths::Writable(get) => {
822 result.as_mut().ok().map(|root| f(get(root)))
823 }
824 KeyPaths::FailableWritable(get) => {
825 result.as_mut().ok().and_then(|root| get(root).map(|v| f(v)))
826 }
827 _ => panic!("with_result_mut only works with writable keypaths"),
828 }
829 }
830
831 #[inline]
834 fn with_option<F, R>(self, option: &Option<Root>, f: F) -> Option<R>
835 where
836 F: FnOnce(&Value) -> R,
837 {
838 match self {
839 KeyPaths::Readable(get) => {
840 option.as_ref().map(|root| f(get(root)))
841 }
842 KeyPaths::FailableReadable(get) => {
843 option.as_ref().and_then(|root| get(root).map(|v| f(v)))
844 }
845 _ => panic!("with_option only works with readable keypaths"),
846 }
847 }
848
849 #[inline]
852 fn with_option_mut<F, R>(self, option: &mut Option<Root>, f: F) -> Option<R>
853 where
854 F: FnOnce(&mut Value) -> R,
855 {
856 match self {
857 KeyPaths::Writable(get) => {
858 option.as_mut().map(|root| f(get(root)))
859 }
860 KeyPaths::FailableWritable(get) => {
861 option.as_mut().and_then(|root| get(root).map(|v| f(v)))
862 }
863 _ => panic!("with_option_mut only works with writable keypaths"),
864 }
865 }
866
867 #[inline]
870 fn with_refcell<F, R>(self, refcell: &RefCell<Root>, f: F) -> Option<R>
871 where
872 F: FnOnce(&Value) -> R,
873 {
874 match self {
875 KeyPaths::Readable(get) => {
876 refcell.try_borrow().ok().map(|borrow| f(get(&*borrow)))
877 }
878 KeyPaths::FailableReadable(get) => {
879 refcell.try_borrow().ok().and_then(|borrow| get(&*borrow).map(|v| f(v)))
880 }
881 _ => panic!("with_refcell only works with readable keypaths"),
882 }
883 }
884
885 #[inline]
888 fn with_refcell_mut<F, R>(self, refcell: &RefCell<Root>, f: F) -> Option<R>
889 where
890 F: FnOnce(&mut Value) -> R,
891 {
892 match self {
893 KeyPaths::Writable(get) => {
894 refcell.try_borrow_mut().ok().map(|mut borrow| f(get(&mut *borrow)))
895 }
896 KeyPaths::FailableWritable(get) => {
897 refcell.try_borrow_mut().ok().and_then(|mut borrow| get(&mut *borrow).map(|v| f(v)))
898 }
899 _ => panic!("with_refcell_mut only works with writable keypaths"),
900 }
901 }
902
903 #[cfg(feature = "tagged_core")]
906 #[inline]
907 fn with_tagged<F, R, Tag>(self, tagged: &Tagged<Root, Tag>, f: F) -> R
908 where
909 F: FnOnce(&Value) -> R,
910 {
911 match self {
912 KeyPaths::Readable(get) => f(get(&**tagged)),
913 KeyPaths::FailableReadable(get) => {
914 get(&**tagged).map_or_else(|| panic!("Tagged value is None"), f)
915 }
916 KeyPaths::ReadableEnum { extract, .. } => {
917 extract(&**tagged).map_or_else(|| panic!("Tagged value is None"), f)
918 }
919 _ => panic!("with_tagged only works with readable keypaths"),
920 }
921 }
922
923 #[inline]
926 fn with_mutex<F, R>(self, mutex: &Mutex<Root>, f: F) -> Option<R>
927 where
928 F: FnOnce(&Value) -> R,
929 {
930 match self {
931 KeyPaths::Readable(get) => {
932 mutex.try_lock().ok().map(|guard| f(get(&*guard)))
933 }
934 KeyPaths::FailableReadable(get) => {
935 mutex.try_lock().ok().and_then(|guard| get(&*guard).map(|v| f(v)))
936 }
937 _ => panic!("with_mutex only works with readable keypaths"),
938 }
939 }
940
941 #[inline]
944 fn with_mutex_mut<F, R>(self, mutex: &mut Mutex<Root>, f: F) -> Option<R>
945 where
946 F: FnOnce(&mut Value) -> R,
947 {
948 match self {
949 KeyPaths::Writable(get) => {
950 mutex.try_lock().ok().map(|mut guard| f(get(&mut *guard)))
951 }
952 KeyPaths::FailableWritable(get) => {
953 mutex.try_lock().ok().and_then(|mut guard| get(&mut *guard).map(|v| f(v)))
954 }
955 _ => panic!("with_mutex_mut only works with writable keypaths"),
956 }
957 }
958
959 #[inline]
962 fn with_rwlock<F, R>(self, rwlock: &RwLock<Root>, f: F) -> Option<R>
963 where
964 F: FnOnce(&Value) -> R,
965 {
966 match self {
967 KeyPaths::Readable(get) => {
968 rwlock.try_read().ok().map(|guard| f(get(&*guard)))
969 }
970 KeyPaths::FailableReadable(get) => {
971 rwlock.try_read().ok().and_then(|guard| get(&*guard).map(|v| f(v)))
972 }
973 _ => panic!("with_rwlock only works with readable keypaths"),
974 }
975 }
976
977 #[inline]
980 fn with_rwlock_mut<F, R>(self, rwlock: &mut RwLock<Root>, f: F) -> Option<R>
981 where
982 F: FnOnce(&mut Value) -> R,
983 {
984 match self {
985 KeyPaths::Writable(get) => {
986 rwlock.try_write().ok().map(|mut guard| f(get(&mut *guard)))
987 }
988 KeyPaths::FailableWritable(get) => {
989 rwlock.try_write().ok().and_then(|mut guard| get(&mut *guard).map(|v| f(v)))
990 }
991 _ => panic!("with_rwlock_mut only works with writable keypaths"),
992 }
993 }
994
995 fn with_arc_rwlock<F, R>(self, arc_rwlock: &Arc<RwLock<Root>>, f: F) -> Option<R>
998 where
999 F: FnOnce(&Value) -> R,
1000 {
1001 match self {
1002 KeyPaths::Readable(get) => {
1003 arc_rwlock.try_read().ok().map(|guard| f(get(&*guard)))
1004 }
1005 KeyPaths::FailableReadable(get) => {
1006 arc_rwlock.try_read().ok().and_then(|guard| get(&*guard).map(|v| f(v)))
1007 }
1008 _ => panic!("with_arc_rwlock only works with readable keypaths"),
1009 }
1010 }
1011
1012 fn with_arc_rwlock_mut<F, R>(self, arc_rwlock: &Arc<RwLock<Root>>, f: F) -> Option<R>
1015 where
1016 F: FnOnce(&mut Value) -> R,
1017 {
1018 match self {
1019 KeyPaths::Writable(get) => {
1020 arc_rwlock.try_write().ok().map(|mut guard| f(get(&mut *guard)))
1021 }
1022 KeyPaths::FailableWritable(get) => {
1023 arc_rwlock.try_write().ok().and_then(|mut guard| get(&mut *guard).map(|v| f(v)))
1024 }
1025 _ => panic!("with_arc_rwlock_mut only works with writable keypaths"),
1026 }
1027 }
1028}
1029
1030impl<Root, Mid> KeyPaths<Root, Mid>
1031where
1032 Root: 'static,
1033 Mid: 'static,
1034{
1035 #[inline]
1037 pub fn then<Value>(self, mid: KeyPaths<Mid, Value>) -> KeyPaths<Root, Value>
1038 where
1039 Value: 'static,
1040 {
1041 self.compose(mid)
1042 }
1043
1044 pub fn compose<Value>(self, mid: KeyPaths<Mid, Value>) -> KeyPaths<Root, Value>
1045 where
1046 Value: 'static,
1047 {
1048 use KeyPaths::*;
1049
1050 match (self, mid) {
1051 (Readable(f1), Readable(f2)) => Readable(Rc::new(move |r| f2(f1(r)))),
1052
1053 (Writable(f1), Writable(f2)) => Writable(Rc::new(move |r| f2(f1(r)))),
1054
1055 (FailableReadable(f1), Readable(f2)) => {
1056 FailableReadable(Rc::new(move |r| f1(r).map(|m| f2(m))))
1057 }
1058
1059 (Readable(f1), FailableReadable(f2)) => FailableReadable(Rc::new(move |r| f2(f1(r)))),
1060
1061 (FailableReadable(f1), FailableReadable(f2)) => {
1062 FailableReadable(Rc::new(move |r| f1(r).and_then(|m| f2(m))))
1063 }
1064
1065 (FailableWritable(f1), Writable(f2)) => {
1066 FailableWritable(Rc::new(move |r| f1(r).map(|m| f2(m))))
1067 }
1068
1069 (Writable(f1), FailableWritable(f2)) => FailableWritable(Rc::new(move |r| f2(f1(r)))),
1070
1071 (FailableWritable(f1), FailableWritable(f2)) => {
1072 FailableWritable(Rc::new(move |r| f1(r).and_then(|m| f2(m))))
1073 }
1074 (FailableReadable(f1), ReadableEnum { extract, .. }) => {
1075 FailableReadable(Rc::new(move |r| f1(r).and_then(|m| extract(m))))
1076 }
1077 (ReadableEnum { extract, .. }, Readable(f2)) => {
1081 FailableReadable(Rc::new(move |r| extract(r).map(|m| f2(m))))
1082 }
1083
1084 (ReadableEnum { extract, .. }, FailableReadable(f2)) => {
1085 FailableReadable(Rc::new(move |r| extract(r).and_then(|m| f2(m))))
1086 }
1087
1088 (WritableEnum { extract, .. }, Readable(f2)) => {
1089 FailableReadable(Rc::new(move |r| extract(r).map(|m| f2(m))))
1090 }
1091
1092 (WritableEnum { extract, .. }, FailableReadable(f2)) => {
1093 FailableReadable(Rc::new(move |r| extract(r).and_then(|m| f2(m))))
1094 }
1095
1096 (WritableEnum { extract_mut, .. }, Writable(f2)) => {
1097 FailableWritable(Rc::new(move |r| extract_mut(r).map(|m| f2(m))))
1098 }
1099
1100 (
1101 FailableWritable(f_root_mid),
1102 WritableEnum {
1103 extract_mut: exm_mid_val,
1104 ..
1105 },
1106 ) => {
1107 FailableWritable(Rc::new(move |r: &mut Root| {
1108 let intermediate_mid_ref = f_root_mid(r);
1111
1112 intermediate_mid_ref.and_then(|intermediate_mid| exm_mid_val(intermediate_mid))
1115 }))
1116 }
1117
1118 (WritableEnum { extract_mut, .. }, FailableWritable(f2)) => {
1119 FailableWritable(Rc::new(move |r| extract_mut(r).and_then(|m| f2(m))))
1120 }
1121
1122 (Writable(f1), WritableEnum { extract_mut, .. }) => {
1124 FailableWritable(Rc::new(move |r: &mut Root| {
1125 let mid: &mut Mid = f1(r);
1126 extract_mut(mid)
1127 }))
1128 }
1129
1130 (
1131 ReadableEnum {
1132 extract: ex1,
1133 embed: em1,
1134 },
1135 ReadableEnum {
1136 extract: ex2,
1137 embed: em2,
1138 },
1139 ) => ReadableEnum {
1140 extract: Rc::new(move |r| ex1(r).and_then(|m| ex2(m))),
1141 embed: Rc::new(move |v| em1(em2(v))),
1142 },
1143
1144 (
1145 WritableEnum {
1146 extract: ex1,
1147 extract_mut: _,
1148 embed: em1,
1149 },
1150 ReadableEnum {
1151 extract: ex2,
1152 embed: em2,
1153 },
1154 ) => ReadableEnum {
1155 extract: Rc::new(move |r| ex1(r).and_then(|m| ex2(m))),
1156 embed: Rc::new(move |v| em1(em2(v))),
1157 },
1158
1159 (
1160 WritableEnum {
1161 extract: ex1,
1162 extract_mut: exm1,
1163 embed: em1,
1164 },
1165 WritableEnum {
1166 extract: ex2,
1167 extract_mut: exm2,
1168 embed: em2,
1169 },
1170 ) => WritableEnum {
1171 extract: Rc::new(move |r| ex1(r).and_then(|m| ex2(m))),
1172 extract_mut: Rc::new(move |r| exm1(r).and_then(|m| exm2(m))),
1173 embed: Rc::new(move |v| em1(em2(v))),
1174 },
1175
1176
1177 (Owned(f1), Owned(f2)) => {
1179 Owned(Rc::new(move |r| f2(f1(r))))
1180 }
1181 (FailableOwned(f1), Owned(f2)) => {
1182 FailableOwned(Rc::new(move |r| f1(r).map(|m| f2(m))))
1183 }
1184 (Owned(f1), FailableOwned(f2)) => {
1185 FailableOwned(Rc::new(move |r| f2(f1(r))))
1186 }
1187 (FailableOwned(f1), FailableOwned(f2)) => {
1188 FailableOwned(Rc::new(move |r| f1(r).and_then(|m| f2(m))))
1189 }
1190
1191 (a, b) => panic!(
1196 "Unsupported composition: {:?} then {:?}",
1197 kind_name(&a),
1198 kind_name(&b)
1199 ),
1200 }
1201 }
1202
1203 #[inline]
1205 pub fn kind_name(&self) -> &'static str {
1206 kind_name(self)
1207 }
1208}
1209
1210fn kind_name<Root, Value>(k: &KeyPaths<Root, Value>) -> &'static str {
1211 use KeyPaths::*;
1212 match k {
1213 Readable(_) => "Readable",
1214 Writable(_) => "Writable",
1215 FailableReadable(_) => "FailableReadable",
1216 FailableWritable(_) => "FailableWritable",
1217 ReadableEnum { .. } => "ReadableEnum",
1218 WritableEnum { .. } => "WritableEnum",
1219 Owned(_) => "Owned",
1221 FailableOwned(_) => "FailableOwned",
1222 }
1223}
1224
1225pub fn compose<Root, Mid, Value>(
1234 kp1: KeyPaths<Root, Mid>,
1235 kp2: KeyPaths<Mid, Value>,
1236) -> KeyPaths<Root, Value>
1237where
1238 Root: 'static,
1239 Mid: 'static,
1240 Value: 'static,
1241{
1242 kp1.compose(kp2)
1243}
1244
1245#[macro_export]
1248macro_rules! readable_enum_macro {
1249 ($enum:path, $variant:ident) => {{
1251 $crate::KeyPaths::readable_enum(
1252 |_| <$enum>::$variant,
1253 |e: &$enum| match e {
1254 <$enum>::$variant => Some(&()),
1255 _ => None,
1256 },
1257 )
1258 }};
1259 ($enum:path, $variant:ident($inner:ty)) => {{
1261 $crate::KeyPaths::readable_enum(
1262 |v: $inner| <$enum>::$variant(v),
1263 |e: &$enum| match e {
1264 <$enum>::$variant(v) => Some(v),
1265 _ => None,
1266 },
1267 )
1268 }};
1269}
1270
1271#[macro_export]
1272macro_rules! writable_enum_macro {
1273 ($enum:path, $variant:ident) => {{
1275 $crate::KeyPaths::writable_enum(
1276 |_| <$enum>::$variant,
1277 |e: &$enum| match e {
1278 <$enum>::$variant => Some(&()),
1279 _ => None,
1280 },
1281 |e: &mut $enum| match e {
1282 <$enum>::$variant => Some(&mut ()),
1283 _ => None,
1284 },
1285 )
1286 }};
1287 ($enum:path, $variant:ident($inner:ty)) => {{
1289 $crate::KeyPaths::writable_enum(
1290 |v: $inner| <$enum>::$variant(v),
1291 |e: &$enum| match e {
1292 <$enum>::$variant(v) => Some(v),
1293 _ => None,
1294 },
1295 |e: &mut $enum| match e {
1296 <$enum>::$variant(v) => Some(v),
1297 _ => None,
1298 },
1299 )
1300 }};
1301}