Skip to main content

rust_key_paths/
kptrait.rs

1//! Keypath traits: read/write surfaces, chaining, coercion, and higher-order helpers.
2//!
3//! [`KpTrait`] composes [`KpReadable`] (getter path) and [`KPWritable`] (setter path, exposed as
4//! [`KPWritable::set`]) plus [`KpTrait::then`].
5
6use std::any::TypeId;
7
8use crate::Kp;
9
10/// Used so that `then_async` can infer `V2` from `AsyncKp::Value` without ambiguity
11/// (e.g. `&i32` has both `Borrow<i32>` and `Borrow<&i32>`; this picks the referent).
12/// Implemented only for reference types so there is no overlap with the blanket impl.
13pub trait KeyPathValueTarget {
14    type Target: Sized;
15}
16impl<T> KeyPathValueTarget for &T {
17    type Target = T;
18}
19impl<T> KeyPathValueTarget for &mut T {
20    type Target = T;
21}
22
23/// Read-only keypath surface: navigate from `Root` to `Value` (logical value type `V`).
24pub trait KpReadable<R, V, Root, Value> {
25    fn get(&self, root: Root) -> Option<Value>;
26}
27
28/// Mutable keypath surface: setter path (same closure as [`Kp::get_mut`]).
29pub trait KPWritable<R, V, MutRoot, MutValue> {
30    fn set(&self, root: MutRoot) -> Option<MutValue>;
31}
32
33pub trait KpTrait<R, V, Root, Value, MutRoot, MutValue, G, S>:
34    KpReadable<R, V, Root, Value> + KPWritable<R, V, MutRoot, MutValue>
35{
36    fn type_id_of_root() -> TypeId
37    where
38        R: 'static,
39    {
40        TypeId::of::<R>()
41    }
42    fn type_id_of_value() -> TypeId
43    where
44        V: 'static,
45    {
46        TypeId::of::<V>()
47    }
48    fn then<SV, SubValue, MutSubValue, G2, S2>(
49        self,
50        next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
51    ) -> Kp<
52        R,
53        SV,
54        Root,
55        SubValue,
56        MutRoot,
57        MutSubValue,
58        impl Fn(Root) -> Option<SubValue>,
59        impl Fn(MutRoot) -> Option<MutSubValue>,
60    >
61    where
62        Self: Sized,
63        Root: std::borrow::Borrow<R>,
64        Value: std::borrow::Borrow<V>,
65        MutRoot: std::borrow::BorrowMut<R>,
66        MutValue: std::borrow::BorrowMut<V>,
67        SubValue: std::borrow::Borrow<SV>,
68        MutSubValue: std::borrow::BorrowMut<SV>,
69        G2: Fn(Value) -> Option<SubValue>,
70        S2: Fn(MutValue) -> Option<MutSubValue>;
71}
72
73pub trait ChainExt<R, V, Root, Value, MutRoot, MutValue> {
74    /// Chain with a sync [`crate::sync_kp::SyncKp`]. Use `.get(root)` / `.get_mut(root)` on the returned keypath.
75    fn then_sync<
76        Lock,
77        Mid,
78        V2,
79        LockValue,
80        MidValue,
81        Value2,
82        MutLock,
83        MutMid,
84        MutValue2,
85        G1,
86        S1,
87        L,
88        G2,
89        S2,
90    >(
91        self,
92        lock_kp: crate::sync_kp::SyncKp<
93            V,
94            Lock,
95            Mid,
96            V2,
97            Value,
98            LockValue,
99            MidValue,
100            Value2,
101            MutValue,
102            MutLock,
103            MutMid,
104            MutValue2,
105            G1,
106            S1,
107            L,
108            G2,
109            S2,
110        >,
111    ) -> crate::sync_kp::KpThenSyncKp<
112        R,
113        V,
114        V2,
115        Root,
116        Value,
117        Value2,
118        MutRoot,
119        MutValue,
120        MutValue2,
121        Self,
122        crate::sync_kp::SyncKp<
123            V,
124            Lock,
125            Mid,
126            V2,
127            Value,
128            LockValue,
129            MidValue,
130            Value2,
131            MutValue,
132            MutLock,
133            MutMid,
134            MutValue2,
135            G1,
136            S1,
137            L,
138            G2,
139            S2,
140        >,
141    >
142    where
143        V: 'static,
144        V2: 'static,
145        Value: std::borrow::Borrow<V>,
146        Value2: std::borrow::Borrow<V2>,
147        MutValue: std::borrow::BorrowMut<V>,
148        MutValue2: std::borrow::BorrowMut<V2>,
149        LockValue: std::borrow::Borrow<Lock>,
150        MidValue: std::borrow::Borrow<Mid>,
151        MutLock: std::borrow::BorrowMut<Lock>,
152        MutMid: std::borrow::BorrowMut<Mid>,
153        G1: Fn(Value) -> Option<LockValue>,
154        S1: Fn(MutValue) -> Option<MutLock>,
155        L: crate::sync_kp::LockAccess<Lock, MidValue> + crate::sync_kp::LockAccess<Lock, MutMid>,
156        G2: Fn(MidValue) -> Option<Value2>,
157        S2: Fn(MutMid) -> Option<MutValue2>,
158        Self: Sized;
159
160    /// Chain with a `#[pin]` Future field await (pin_project pattern). Use `.get_mut(&mut root).await` on the returned keypath.
161    #[cfg(feature = "pin_project")]
162    fn then_pin_future<Struct, Output, L>(
163        self,
164        pin_fut: L,
165    ) -> crate::pin::KpThenPinFuture<R, Struct, Output, Root, MutRoot, Value, MutValue, Self, L>
166    where
167        Struct: std::marker::Unpin + 'static,
168        Output: 'static,
169        Value: std::borrow::Borrow<Struct>,
170        MutValue: std::borrow::BorrowMut<Struct>,
171        L: crate::pin::PinFutureAwaitLike<Struct, Output> + Sync,
172        Self: Sized;
173
174    /// Chain with an async keypath (e.g. [`crate::async_lock::AsyncLockKp`]). Use `.get(&root).await` on the returned keypath.
175    fn then_async<AsyncKp>(
176        self,
177        async_kp: AsyncKp,
178    ) -> crate::async_lock::KpThenAsyncKeyPath<
179        R,
180        V,
181        <AsyncKp::Value as KeyPathValueTarget>::Target,
182        Root,
183        Value,
184        AsyncKp::Value,
185        MutRoot,
186        MutValue,
187        AsyncKp::MutValue,
188        Self,
189        AsyncKp,
190    >
191    where
192        Value: std::borrow::Borrow<V>,
193        MutValue: std::borrow::BorrowMut<V>,
194        AsyncKp: crate::async_lock::AsyncKeyPathLike<Value, MutValue>,
195        AsyncKp::Value: KeyPathValueTarget
196            + std::borrow::Borrow<<AsyncKp::Value as KeyPathValueTarget>::Target>,
197        AsyncKp::MutValue: std::borrow::BorrowMut<<AsyncKp::Value as KeyPathValueTarget>::Target>,
198        <AsyncKp::Value as KeyPathValueTarget>::Target: 'static,
199        Self: Sized;
200}
201
202impl<R, V, Root, Value, MutRoot, MutValue, G, S> ChainExt<R, V, Root, Value, MutRoot, MutValue>
203    for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
204where
205    Root: std::borrow::Borrow<R>,
206    Value: std::borrow::Borrow<V>,
207    MutRoot: std::borrow::BorrowMut<R>,
208    MutValue: std::borrow::BorrowMut<V>,
209    G: Fn(Root) -> Option<Value>,
210    S: Fn(MutRoot) -> Option<MutValue>,
211{
212    fn then_sync<
213        Lock,
214        Mid,
215        V2,
216        LockValue,
217        MidValue,
218        Value2,
219        MutLock,
220        MutMid,
221        MutValue2,
222        G1,
223        S1,
224        L,
225        G2,
226        S2,
227    >(
228        self,
229        lock_kp: crate::sync_kp::SyncKp<
230            V,
231            Lock,
232            Mid,
233            V2,
234            Value,
235            LockValue,
236            MidValue,
237            Value2,
238            MutValue,
239            MutLock,
240            MutMid,
241            MutValue2,
242            G1,
243            S1,
244            L,
245            G2,
246            S2,
247        >,
248    ) -> crate::sync_kp::KpThenSyncKp<
249        R,
250        V,
251        V2,
252        Root,
253        Value,
254        Value2,
255        MutRoot,
256        MutValue,
257        MutValue2,
258        Self,
259        crate::sync_kp::SyncKp<
260            V,
261            Lock,
262            Mid,
263            V2,
264            Value,
265            LockValue,
266            MidValue,
267            Value2,
268            MutValue,
269            MutLock,
270            MutMid,
271            MutValue2,
272            G1,
273            S1,
274            L,
275            G2,
276            S2,
277        >,
278    >
279    where
280        V: 'static,
281        V2: 'static,
282        Value: std::borrow::Borrow<V>,
283        Value2: std::borrow::Borrow<V2>,
284        MutValue: std::borrow::BorrowMut<V>,
285        MutValue2: std::borrow::BorrowMut<V2>,
286        LockValue: std::borrow::Borrow<Lock>,
287        MidValue: std::borrow::Borrow<Mid>,
288        MutLock: std::borrow::BorrowMut<Lock>,
289        MutMid: std::borrow::BorrowMut<Mid>,
290        G1: Fn(Value) -> Option<LockValue>,
291        S1: Fn(MutValue) -> Option<MutLock>,
292        L: crate::sync_kp::LockAccess<Lock, MidValue> + crate::sync_kp::LockAccess<Lock, MutMid>,
293        G2: Fn(MidValue) -> Option<Value2>,
294        S2: Fn(MutMid) -> Option<MutValue2>,
295    {
296        let first = self;
297        let second = lock_kp;
298
299        crate::sync_kp::KpThenSyncKp::new(first, second)
300    }
301
302    #[cfg(feature = "pin_project")]
303    fn then_pin_future<Struct, Output, L>(
304        self,
305        pin_fut: L,
306    ) -> crate::pin::KpThenPinFuture<R, Struct, Output, Root, MutRoot, Value, MutValue, Self, L>
307    where
308        Struct: std::marker::Unpin + 'static,
309        Output: 'static,
310        Value: std::borrow::Borrow<Struct>,
311        MutValue: std::borrow::BorrowMut<Struct>,
312        L: crate::pin::PinFutureAwaitLike<Struct, Output> + Sync,
313    {
314        let first = self;
315        let second = pin_fut;
316
317        crate::pin::KpThenPinFuture::new(first, second)
318    }
319
320    fn then_async<AsyncKp>(
321        self,
322        async_kp: AsyncKp,
323    ) -> crate::async_lock::KpThenAsyncKeyPath<
324        R,
325        V,
326        <AsyncKp::Value as KeyPathValueTarget>::Target,
327        Root,
328        Value,
329        AsyncKp::Value,
330        MutRoot,
331        MutValue,
332        AsyncKp::MutValue,
333        Self,
334        AsyncKp,
335    >
336    where
337        Value: std::borrow::Borrow<V>,
338        MutValue: std::borrow::BorrowMut<V>,
339        AsyncKp: crate::async_lock::AsyncKeyPathLike<Value, MutValue>,
340        AsyncKp::Value: KeyPathValueTarget
341            + std::borrow::Borrow<<AsyncKp::Value as KeyPathValueTarget>::Target>,
342        AsyncKp::MutValue: std::borrow::BorrowMut<<AsyncKp::Value as KeyPathValueTarget>::Target>,
343        <AsyncKp::Value as KeyPathValueTarget>::Target: 'static,
344    {
345        let first = self;
346        let second = async_kp;
347
348        crate::async_lock::KpThenAsyncKeyPath::new(first, second)
349    }
350}
351
352pub trait AccessorTrait<R, V, Root, Value, MutRoot, MutValue, G, S>:
353    KpTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
354{
355    /// Like [`Kp::get`], but takes an optional root: returns `None` if `root` is `None`.
356    fn get_optional(&self, root: Option<Root>) -> Option<Value>;
357
358    /// Like [`Kp::get_mut`], but takes an optional root: returns `None` if `root` is `None`.
359    fn get_mut_optional(&self, root: Option<MutRoot>) -> Option<MutValue>;
360
361    /// Returns the value if the keypath succeeds, otherwise calls `f` and returns its result.
362    fn get_or_else<F>(&self, root: Root, f: F) -> Value
363    where
364        F: FnOnce() -> Value;
365
366    /// Returns the mutable value if the keypath succeeds, otherwise calls `f` and returns its result.
367    fn get_mut_or_else<F>(&self, root: MutRoot, f: F) -> MutValue
368    where
369        F: FnOnce() -> MutValue;
370}
371
372pub trait CoercionTrait<R, V, Root, Value, MutRoot, MutValue, G, S>:
373    KpTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
374where
375    Root: std::borrow::Borrow<R>,
376    Value: std::borrow::Borrow<V>,
377    MutRoot: std::borrow::BorrowMut<R>,
378    MutValue: std::borrow::BorrowMut<V>,
379    G: Fn(Root) -> Option<Value>,
380    S: Fn(MutRoot) -> Option<MutValue>,
381{
382    fn for_arc<'b>(
383        &self,
384    ) -> Kp<
385        std::sync::Arc<R>,
386        V,
387        std::sync::Arc<R>,
388        Value,
389        std::sync::Arc<R>,
390        MutValue,
391        impl Fn(std::sync::Arc<R>) -> Option<Value>,
392        impl Fn(std::sync::Arc<R>) -> Option<MutValue>,
393    >
394    where
395        R: 'b,
396        V: 'b,
397        Root: for<'a> From<&'a R>,
398        MutRoot: for<'a> From<&'a mut R>;
399
400    fn for_box<'a>(
401        &self,
402    ) -> Kp<
403        Box<R>,
404        V,
405        Box<R>,
406        Value,
407        Box<R>,
408        MutValue,
409        impl Fn(Box<R>) -> Option<Value>,
410        impl Fn(Box<R>) -> Option<MutValue>,
411    >
412    where
413        R: 'a,
414        V: 'a,
415        Root: for<'b> From<&'b R>,
416        MutRoot: for<'b> From<&'b mut R>;
417
418    fn into_set(self) -> impl Fn(MutRoot) -> Option<MutValue>;
419
420    fn into_get(self) -> impl Fn(Root) -> Option<Value>;
421}
422
423pub trait HofTrait<R, V, Root, Value, MutRoot, MutValue, G, S>:
424    KpTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
425where
426    Root: std::borrow::Borrow<R>,
427    Value: std::borrow::Borrow<V>,
428    MutRoot: std::borrow::BorrowMut<R>,
429    MutValue: std::borrow::BorrowMut<V>,
430    G: Fn(Root) -> Option<Value>,
431    S: Fn(MutRoot) -> Option<MutValue>,
432{
433    fn map<MappedValue, F>(
434        &self,
435        mapper: F,
436    ) -> Kp<
437        R,
438        MappedValue,
439        Root,
440        MappedValue,
441        MutRoot,
442        MappedValue,
443        impl Fn(Root) -> Option<MappedValue> + '_,
444        impl Fn(MutRoot) -> Option<MappedValue> + '_,
445    >
446    where
447        F: Fn(&V) -> MappedValue + Copy + 'static,
448        MappedValue: 'static,
449    {
450        Kp::new(
451            move |root: Root| {
452                KpReadable::get(self, root).map(|value| {
453                    let v: &V = value.borrow();
454                    mapper(v)
455                })
456            },
457            move |root: MutRoot| {
458                KPWritable::set(self, root).map(|value| {
459                    let v: &V = value.borrow();
460                    mapper(v)
461                })
462            },
463        )
464    }
465
466    fn filter<F>(
467        &self,
468        predicate: F,
469    ) -> Kp<
470        R,
471        V,
472        Root,
473        Value,
474        MutRoot,
475        MutValue,
476        impl Fn(Root) -> Option<Value> + '_,
477        impl Fn(MutRoot) -> Option<MutValue> + '_,
478    >
479    where
480        F: Fn(&V) -> bool + Copy + 'static,
481    {
482        Kp::new(
483            move |root: Root| {
484                KpReadable::get(self, root).filter(|value| {
485                    let v: &V = value.borrow();
486                    predicate(v)
487                })
488            },
489            move |root: MutRoot| {
490                KPWritable::set(self, root).filter(|value| {
491                    let v: &V = value.borrow();
492                    predicate(v)
493                })
494            },
495        )
496    }
497
498    fn filter_map<MappedValue, F>(
499        &self,
500        mapper: F,
501    ) -> Kp<
502        R,
503        MappedValue,
504        Root,
505        MappedValue,
506        MutRoot,
507        MappedValue,
508        impl Fn(Root) -> Option<MappedValue> + '_,
509        impl Fn(MutRoot) -> Option<MappedValue> + '_,
510    >
511    where
512        F: Fn(&V) -> Option<MappedValue> + Copy + 'static,
513    {
514        Kp::new(
515            move |root: Root| {
516                KpReadable::get(self, root).and_then(|value| {
517                    let v: &V = value.borrow();
518                    mapper(v)
519                })
520            },
521            move |root: MutRoot| {
522                KPWritable::set(self, root).and_then(|value| {
523                    let v: &V = value.borrow();
524                    mapper(v)
525                })
526            },
527        )
528    }
529
530    fn inspect<F>(
531        &self,
532        inspector: F,
533    ) -> Kp<
534        R,
535        V,
536        Root,
537        Value,
538        MutRoot,
539        MutValue,
540        impl Fn(Root) -> Option<Value> + '_,
541        impl Fn(MutRoot) -> Option<MutValue> + '_,
542    >
543    where
544        F: Fn(&V) + Clone + 'static,
545    {
546        let inspector_for_get = inspector.clone();
547        Kp::new(
548            move |root: Root| {
549                KpReadable::get(self, root).map(|value| {
550                    let v: &V = value.borrow();
551                    inspector_for_get(v);
552                    value
553                })
554            },
555            move |root: MutRoot| {
556                KPWritable::set(self, root).map(|value| {
557                    let v: &V = value.borrow();
558                    inspector(v);
559                    value
560                })
561            },
562        )
563    }
564
565    fn flat_map<I, Item, F>(&self, mapper: F) -> impl Fn(Root) -> Vec<Item> + '_
566    where
567        F: Fn(&V) -> I + 'static,
568        I: IntoIterator<Item = Item>,
569    {
570        move |root: Root| {
571            KpReadable::get(self, root)
572                .map(|value| {
573                    let v: &V = value.borrow();
574                    mapper(v).into_iter().collect()
575                })
576                .unwrap_or_else(Vec::new)
577        }
578    }
579
580    fn fold_value<Acc, F>(&self, init: Acc, folder: F) -> impl Fn(Root) -> Acc + '_
581    where
582        F: Fn(Acc, &V) -> Acc + 'static,
583        Acc: Copy + 'static,
584    {
585        move |root: Root| {
586            KpReadable::get(self, root)
587                .map(|value| {
588                    let v: &V = value.borrow();
589                    folder(init, v)
590                })
591                .unwrap_or(init)
592        }
593    }
594
595    fn any<F>(&self, predicate: F) -> impl Fn(Root) -> bool + '_
596    where
597        F: Fn(&V) -> bool + 'static,
598    {
599        move |root: Root| {
600            KpReadable::get(self, root)
601                .map(|value| {
602                    let v: &V = value.borrow();
603                    predicate(v)
604                })
605                .unwrap_or(false)
606        }
607    }
608
609    fn all<F>(&self, predicate: F) -> impl Fn(Root) -> bool + '_
610    where
611        F: Fn(&V) -> bool + 'static,
612    {
613        move |root: Root| {
614            KpReadable::get(self, root)
615                .map(|value| {
616                    let v: &V = value.borrow();
617                    predicate(v)
618                })
619                .unwrap_or(true)
620        }
621    }
622
623    fn count_items<F>(&self, counter: F) -> impl Fn(Root) -> Option<usize> + '_
624    where
625        F: Fn(&V) -> usize + 'static,
626    {
627        move |root: Root| {
628            KpReadable::get(self, root).map(|value| {
629                let v: &V = value.borrow();
630                counter(v)
631            })
632        }
633    }
634
635    fn find_in<Item, F>(&self, finder: F) -> impl Fn(Root) -> Option<Item> + '_
636    where
637        F: Fn(&V) -> Option<Item> + 'static,
638    {
639        move |root: Root| {
640            KpReadable::get(self, root).and_then(|value| {
641                let v: &V = value.borrow();
642                finder(v)
643            })
644        }
645    }
646
647    fn take<Output, F>(&self, n: usize, taker: F) -> impl Fn(Root) -> Option<Output> + '_
648    where
649        F: Fn(&V, usize) -> Output + 'static,
650    {
651        move |root: Root| {
652            KpReadable::get(self, root).map(|value| {
653                let v: &V = value.borrow();
654                taker(v, n)
655            })
656        }
657    }
658
659    fn skip<Output, F>(&self, n: usize, skipper: F) -> impl Fn(Root) -> Option<Output> + '_
660    where
661        F: Fn(&V, usize) -> Output + 'static,
662    {
663        move |root: Root| {
664            KpReadable::get(self, root).map(|value| {
665                let v: &V = value.borrow();
666                skipper(v, n)
667            })
668        }
669    }
670
671    fn partition_value<Output, F>(&self, partitioner: F) -> impl Fn(Root) -> Option<Output> + '_
672    where
673        F: Fn(&V) -> Output + 'static,
674    {
675        move |root: Root| {
676            KpReadable::get(self, root).map(|value| {
677                let v: &V = value.borrow();
678                partitioner(v)
679            })
680        }
681    }
682
683    fn min_value<Item, F>(&self, min_fn: F) -> impl Fn(Root) -> Option<Item> + '_
684    where
685        F: Fn(&V) -> Option<Item> + 'static,
686    {
687        move |root: Root| {
688            KpReadable::get(self, root).and_then(|value| {
689                let v: &V = value.borrow();
690                min_fn(v)
691            })
692        }
693    }
694
695    fn max_value<Item, F>(&self, max_fn: F) -> impl Fn(Root) -> Option<Item> + '_
696    where
697        F: Fn(&V) -> Option<Item> + 'static,
698    {
699        move |root: Root| {
700            KpReadable::get(self, root).and_then(|value| {
701                let v: &V = value.borrow();
702                max_fn(v)
703            })
704        }
705    }
706
707    fn sum_value<Sum, F>(&self, sum_fn: F) -> impl Fn(Root) -> Option<Sum> + '_
708    where
709        F: Fn(&V) -> Sum + 'static,
710    {
711        move |root: Root| {
712            KpReadable::get(self, root).map(|value| {
713                let v: &V = value.borrow();
714                sum_fn(v)
715            })
716        }
717    }
718}
719
720impl<R, V, Root, Value, MutRoot, MutValue, G, S> KpReadable<R, V, Root, Value>
721    for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
722where
723    Root: std::borrow::Borrow<R>,
724    Value: std::borrow::Borrow<V>,
725    MutRoot: std::borrow::BorrowMut<R>,
726    MutValue: std::borrow::BorrowMut<V>,
727    G: Fn(Root) -> Option<Value>,
728    S: Fn(MutRoot) -> Option<MutValue>,
729{
730    #[inline]
731    fn get(&self, root: Root) -> Option<Value> {
732        (self.get)(root)
733    }
734}
735
736impl<R, V, Root, Value, MutRoot, MutValue, G, S> KPWritable<R, V, MutRoot, MutValue>
737    for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
738where
739    Root: std::borrow::Borrow<R>,
740    Value: std::borrow::Borrow<V>,
741    MutRoot: std::borrow::BorrowMut<R>,
742    MutValue: std::borrow::BorrowMut<V>,
743    G: Fn(Root) -> Option<Value>,
744    S: Fn(MutRoot) -> Option<MutValue>,
745{
746    #[inline]
747    fn set(&self, root: MutRoot) -> Option<MutValue> {
748        (self.set)(root)
749    }
750}
751
752impl<R, V, Root, Value, MutRoot, MutValue, G, S> KpTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
753    for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
754where
755    Root: std::borrow::Borrow<R>,
756    Value: std::borrow::Borrow<V>,
757    MutRoot: std::borrow::BorrowMut<R>,
758    MutValue: std::borrow::BorrowMut<V>,
759    G: Fn(Root) -> Option<Value>,
760    S: Fn(MutRoot) -> Option<MutValue>,
761{
762    fn then<SV, SubValue, MutSubValue, G2, S2>(
763        self,
764        next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
765    ) -> Kp<
766        R,
767        SV,
768        Root,
769        SubValue,
770        MutRoot,
771        MutSubValue,
772        impl Fn(Root) -> Option<SubValue>,
773        impl Fn(MutRoot) -> Option<MutSubValue>,
774    >
775    where
776        SubValue: std::borrow::Borrow<SV>,
777        MutSubValue: std::borrow::BorrowMut<SV>,
778        G2: Fn(Value) -> Option<SubValue>,
779        S2: Fn(MutValue) -> Option<MutSubValue>,
780    {
781        let first_get = self.get;
782        let first_set = self.set;
783        let second_get = next.get;
784        let second_set = next.set;
785
786        Kp::new(
787            move |root: Root| first_get(root).and_then(|value| second_get(value)),
788            move |root: MutRoot| first_set(root).and_then(|value| second_set(value)),
789        )
790    }
791}
792
793impl<R, V, Root, Value, MutRoot, MutValue, G, S>
794    CoercionTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
795    for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
796where
797    Root: std::borrow::Borrow<R>,
798    Value: std::borrow::Borrow<V>,
799    MutRoot: std::borrow::BorrowMut<R>,
800    MutValue: std::borrow::BorrowMut<V>,
801    G: Fn(Root) -> Option<Value>,
802    S: Fn(MutRoot) -> Option<MutValue>,
803{
804    fn for_arc<'b>(
805        &self,
806    ) -> Kp<
807        std::sync::Arc<R>,
808        V,
809        std::sync::Arc<R>,
810        Value,
811        std::sync::Arc<R>,
812        MutValue,
813        impl Fn(std::sync::Arc<R>) -> Option<Value>,
814        impl Fn(std::sync::Arc<R>) -> Option<MutValue>,
815    >
816    where
817        R: 'b,
818        V: 'b,
819        Root: for<'a> From<&'a R>,
820        MutRoot: for<'a> From<&'a mut R>,
821    {
822        Kp::new(
823            move |arc_root: std::sync::Arc<R>| {
824                let r_ref: &R = &*arc_root;
825                (self.get)(Root::from(r_ref))
826            },
827            move |mut arc_root: std::sync::Arc<R>| {
828                std::sync::Arc::get_mut(&mut arc_root)
829                    .and_then(|r_mut| (self.set)(MutRoot::from(r_mut)))
830            },
831        )
832    }
833
834    fn for_box<'a>(
835        &self,
836    ) -> Kp<
837        Box<R>,
838        V,
839        Box<R>,
840        Value,
841        Box<R>,
842        MutValue,
843        impl Fn(Box<R>) -> Option<Value>,
844        impl Fn(Box<R>) -> Option<MutValue>,
845    >
846    where
847        R: 'a,
848        V: 'a,
849        Root: for<'b> From<&'b R>,
850        MutRoot: for<'b> From<&'b mut R>,
851    {
852        Kp::new(
853            move |r: Box<R>| {
854                let r_ref: &R = r.as_ref();
855                (self.get)(Root::from(r_ref))
856            },
857            move |mut r: Box<R>| (self.set)(MutRoot::from(r.as_mut())),
858        )
859    }
860
861    #[inline]
862    fn into_set(self) -> impl Fn(MutRoot) -> Option<MutValue> {
863        self.set
864    }
865
866    #[inline]
867    fn into_get(self) -> impl Fn(Root) -> Option<Value> {
868        self.get
869    }
870}
871
872impl<R, V, Root, Value, MutRoot, MutValue, G, S>
873    HofTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
874    for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
875where
876    Root: std::borrow::Borrow<R>,
877    Value: std::borrow::Borrow<V>,
878    MutRoot: std::borrow::BorrowMut<R>,
879    MutValue: std::borrow::BorrowMut<V>,
880    G: Fn(Root) -> Option<Value>,
881    S: Fn(MutRoot) -> Option<MutValue>,
882{
883}
884
885impl<R, V, Root, Value, MutRoot, MutValue, G, S>
886    AccessorTrait<R, V, Root, Value, MutRoot, MutValue, G, S>
887    for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
888where
889    Root: std::borrow::Borrow<R>,
890    Value: std::borrow::Borrow<V>,
891    MutRoot: std::borrow::BorrowMut<R>,
892    MutValue: std::borrow::BorrowMut<V>,
893    G: Fn(Root) -> Option<Value>,
894    S: Fn(MutRoot) -> Option<MutValue>,
895{
896    #[inline]
897    fn get_optional(&self, root: Option<Root>) -> Option<Value> {
898        root.and_then(|r| (self.get)(r))
899    }
900
901    #[inline]
902    fn get_mut_optional(&self, root: Option<MutRoot>) -> Option<MutValue> {
903        root.and_then(|r| (self.set)(r))
904    }
905
906    #[inline]
907    fn get_or_else<F>(&self, root: Root, f: F) -> Value
908    where
909        F: FnOnce() -> Value,
910    {
911        (self.get)(root).unwrap_or_else(f)
912    }
913
914    #[inline]
915    fn get_mut_or_else<F>(&self, root: MutRoot, f: F) -> MutValue
916    where
917        F: FnOnce() -> MutValue,
918    {
919        (self.set)(root).unwrap_or_else(f)
920    }
921}