1
2pub trait Readable<Root, Value> {
3 fn get<'a>(&self, root: &'a Root) -> &'a Value;
4
5 fn iter<'a>(&self, slice: &'a [Root]) -> Box<dyn Iterator<Item = &'a Value> + 'a>
6 where
7 Self: Sized,
8 {
9 let f = self.get_fn(); Box::new(slice.iter().map(move |root| f(root)))
11 }
12
13 fn get_fn(&self) -> for<'a> fn(&'a Root) -> &'a Value;
14}
15
16pub struct ReadableKeyPath<Root, Value> {
18 pub get: for<'a> fn(&'a Root) -> &'a Value,
19}
20
21impl<Root, Value> ReadableKeyPath<Root, Value> {
22 pub fn new(get: for<'a> fn(&'a Root) -> &'a Value) -> Self {
23 Self { get }
24 }
25}
26
27impl<Root, Value> Readable<Root, Value> for ReadableKeyPath<Root, Value> {
28 fn get<'a>(&self, root: &'a Root) -> &'a Value {
29 (self.get)(root)
30 }
31
32 fn get_fn(&self) -> for<'a> fn(&'a Root) -> &'a Value {
33 self.get
34 }
35}
36
37
38pub struct WritableKeyPath<Root, Value> {
40 pub get: for<'a> fn(&'a Root) -> &'a Value,
41 pub get_mut: for<'a> fn(&'a mut Root) -> &'a mut Value,
42}
43
44pub trait Writable<Root, Value>: Readable<Root, Value> {
45 fn get_mut<'a>(&self, root: &'a mut Root) -> &'a mut Value;
46
47 fn iter_mut<'a>(&self, slice: &'a mut [Root]) -> Box<dyn Iterator<Item = &'a mut Value> + 'a>
48 where
49 Self: Sized,
50 {
51 let f = self.get_mut_fn(); Box::new(slice.iter_mut().map(move |root| f(root)))
53 }
54
55 fn get_mut_fn(&self) -> for<'a> fn(&'a mut Root) -> &'a mut Value;
56}
57
58impl<Root, Value> WritableKeyPath<Root, Value> {
59 pub fn new(
60 get: for<'a> fn(&'a Root) -> &'a Value,
61 get_mut: for<'a> fn(&'a mut Root) -> &'a mut Value,
62 ) -> Self {
63 Self { get, get_mut }
64 }
65}
66
67impl<Root, Value> Readable<Root, Value> for WritableKeyPath<Root, Value> {
68 fn get<'a>(&self, root: &'a Root) -> &'a Value {
69 (self.get)(root)
70 }
71
72 fn get_fn(&self) -> for<'a> fn(&'a Root) -> &'a Value {
73 self.get
74 }
75}
76
77impl<Root, Value> Writable<Root, Value> for WritableKeyPath<Root, Value> {
78 fn get_mut<'a>(&self, root: &'a mut Root) -> &'a mut Value {
79 (self.get_mut)(root)
80 }
81
82 fn get_mut_fn(&self) -> for<'a> fn(&'a mut Root) -> &'a mut Value {
83 self.get_mut
84 }
85}
86
87
88pub struct EnumKeyPath<Enum, Inner> {
89 pub extract: fn(&Enum) -> Option<&Inner>,
90 pub embed: fn(Inner) -> Enum,
91}
92
93impl<Enum, Inner> EnumKeyPath<Enum, Inner> {
94 pub fn new(extract: fn(&Enum) -> Option<&Inner>, embed: fn(Inner) -> Enum) -> Self {
95 Self { extract, embed }
96 }
97
98 pub fn extract<'a>(&self, e: &'a Enum) -> Option<&'a Inner> {
99 (self.extract)(e)
100 }
101
102 pub fn embed(&self, inner: Inner) -> Enum {
103 (self.embed)(inner)
104 }
105}
106
107#[macro_export]
108macro_rules! enum_keypath {
109 ($enum:ident :: $variant:ident ( $inner:ty )) => {{
111 EnumKeyPath::<$enum, $inner>::new(
112 |root: &$enum| {
113 if let $enum::$variant(inner) = root {
114 Some(inner)
115 } else {
116 None
117 }
118 },
119 |inner: $inner| $enum::$variant(inner),
120 )
121 }};
122 ($enum:ident :: $variant:ident) => {{
124 EnumKeyPath::<$enum, ()>::new(
125 |root: &$enum| {
126 if let $enum::$variant = root {
127 Some(&())
128 } else {
129 None
130 }
131 },
132 |_| $enum::$variant,
133 )
134 }};
135}
136
137#[macro_export]
139macro_rules! readable_keypath {
140 ($Root:ty, $field:ident) => {
141 ReadableKeyPath::new(|root: &$Root| &root.$field)
142 };
143}
144
145#[macro_export]
147macro_rules! writable_keypath {
148 ($Root:ty, $field:ident) => {
149 WritableKeyPath::new(
150 |root: &$Root| &root.$field,
151 |root: &mut $Root| &mut root.$field,
152 )
153 };
154}
155