1use std::{
2 cell::UnsafeCell,
3 ops::{self},
4};
5
6pub trait DerefExt: ops::Deref {
8 fn deref_map<F, R>(self, f: F) -> MapDeref<Self, F>
9 where
10 Self: Sized,
11 F: Fn(&Self::Target) -> &R,
12 {
13 MapDeref { deref: self, f }
14 }
15}
16
17pub struct MapDeref<T, F> {
19 deref: T,
20 f: F,
21}
22
23impl<T, F, R> ops::Deref for MapDeref<T, F>
24where
25 F: Fn(&T::Target) -> &R,
26 T: ops::Deref,
27{
28 type Target = R;
29
30 fn deref(&self) -> &Self::Target {
31 (self.f)(self.deref.deref())
32 }
33}
34
35impl<T> DerefExt for T where T: ops::Deref {}
37
38pub trait DerefMutExt: ops::DerefMut {
40 fn deref_mut_map<F, R>(self, f: F) -> MapDerefMut<Self, F>
41 where
42 Self: Sized,
43 F: Fn(&mut Self::Target) -> &mut R,
44 {
45 MapDerefMut {
46 deref: UnsafeCell::new(self),
47 f,
48 }
49 }
50}
51
52pub struct MapDerefMut<T, F> {
54 deref: UnsafeCell<T>,
55 f: F,
56}
57
58impl<T, F, R> ops::Deref for MapDerefMut<T, F>
59where
60 F: Fn(&mut T::Target) -> &mut R,
61 T: ops::DerefMut,
62{
63 type Target = R;
64
65 fn deref(&self) -> &Self::Target {
66 (self.f)(unsafe { &mut *self.deref.get() })
68 }
69}
70
71impl<T, F, R> ops::DerefMut for MapDerefMut<T, F>
72where
73 F: Fn(&mut T::Target) -> &mut R,
74 T: ops::DerefMut,
75{
76 fn deref_mut(&mut self) -> &mut Self::Target {
77 (self.f)(unsafe { &mut *self.deref.get() })
79 }
80}
81
82impl<T> DerefMutExt for T where T: ops::DerefMut {}