ribir_core/state/
map_state.rs

1use std::convert::Infallible;
2
3use rxrust::ops::box_it::CloneableBoxOp;
4
5use super::{
6  state_cell::PartData, ModifyScope, ReadRef, StateReader, StateWatcher, StateWriter, WriteRef,
7};
8use crate::{
9  context::BuildCtx,
10  render_helper::{RenderProxy, RenderTarget},
11  widget::{Render, RenderBuilder, Widget},
12};
13
14/// A state reader that map a reader to another by applying a function on the
15/// value. This reader is the same reader with the origin reader.
16pub struct MapReader<S, F> {
17  pub(super) origin: S,
18  pub(super) part_map: F,
19}
20
21pub struct MapWriter<W, WM> {
22  pub(super) origin: W,
23  pub(super) part_map: WM,
24}
25
26pub struct MapWriterAsReader<W, M> {
27  pub(super) origin: W,
28  pub(super) part_map: M,
29}
30
31impl<S, V, M> StateReader for MapReader<S, M>
32where
33  Self: 'static,
34  S: StateReader,
35  M: Fn(&S::Value) -> PartData<V> + Clone + 'static,
36{
37  type Value = V;
38  type OriginReader = S;
39  type Reader = MapReader<S::Reader, M>;
40
41  #[inline]
42  fn read(&self) -> ReadRef<Self::Value> { ReadRef::map(self.origin.read(), &self.part_map) }
43
44  #[inline]
45  fn clone_reader(&self) -> Self::Reader {
46    MapReader { origin: self.origin.clone_reader(), part_map: self.part_map.clone() }
47  }
48
49  #[inline]
50  fn origin_reader(&self) -> &Self::OriginReader { &self.origin }
51
52  #[inline]
53  fn try_into_value(self) -> Result<Self::Value, Self>
54  where
55    Self::Value: Sized,
56  {
57    Err(self)
58  }
59}
60
61impl<S, V, M> StateReader for MapWriterAsReader<S, M>
62where
63  Self: 'static,
64  S: StateReader,
65  M: Fn(&mut S::Value) -> PartData<V> + Clone,
66{
67  type Value = V;
68  type OriginReader = S;
69  type Reader = MapWriterAsReader<S::Reader, M>;
70
71  #[inline]
72  fn read(&self) -> ReadRef<Self::Value> {
73    ReadRef::mut_as_ref_map(self.origin.read(), &self.part_map)
74  }
75
76  #[inline]
77  fn clone_reader(&self) -> Self::Reader {
78    MapWriterAsReader { origin: self.origin.clone_reader(), part_map: self.part_map.clone() }
79  }
80
81  #[inline]
82  fn origin_reader(&self) -> &Self::OriginReader { &self.origin }
83
84  #[inline]
85  fn try_into_value(self) -> Result<Self::Value, Self>
86  where
87    Self::Value: Sized,
88  {
89    Err(self)
90  }
91}
92
93impl<V, S, M> StateReader for MapWriter<S, M>
94where
95  Self: 'static,
96  S: StateWriter,
97  M: Fn(&mut S::Value) -> PartData<V> + Clone,
98{
99  type Value = V;
100  type OriginReader = S;
101  type Reader = MapWriterAsReader<S::Reader, M>;
102
103  #[inline]
104  fn read(&self) -> ReadRef<Self::Value> {
105    ReadRef::mut_as_ref_map(self.origin.read(), &self.part_map)
106  }
107
108  #[inline]
109  fn clone_reader(&self) -> Self::Reader {
110    MapWriterAsReader { origin: self.origin.clone_reader(), part_map: self.part_map.clone() }
111  }
112
113  #[inline]
114  fn origin_reader(&self) -> &Self::OriginReader { &self.origin }
115
116  #[inline]
117  fn try_into_value(self) -> Result<Self::Value, Self>
118  where
119    Self::Value: Sized,
120  {
121    Err(self)
122  }
123}
124
125impl<V, W, M> StateWatcher for MapWriter<W, M>
126where
127  Self: 'static,
128  W: StateWriter,
129  M: Fn(&mut W::Value) -> PartData<V> + Clone,
130{
131  #[inline]
132  fn raw_modifies(&self) -> CloneableBoxOp<'static, ModifyScope, Infallible> {
133    self.origin.raw_modifies()
134  }
135}
136
137impl<V, W, M> StateWriter for MapWriter<W, M>
138where
139  Self: 'static,
140  W: StateWriter,
141  M: Fn(&mut W::Value) -> PartData<V> + Clone,
142{
143  type Writer = MapWriter<W::Writer, M>;
144  type OriginWriter = W;
145
146  #[inline]
147  fn write(&self) -> WriteRef<Self::Value> { WriteRef::map(self.origin.write(), &self.part_map) }
148
149  #[inline]
150  fn silent(&self) -> WriteRef<Self::Value> { WriteRef::map(self.origin.silent(), &self.part_map) }
151
152  #[inline]
153  fn shallow(&self) -> WriteRef<Self::Value> {
154    WriteRef::map(self.origin.shallow(), &self.part_map)
155  }
156
157  #[inline]
158  fn clone_writer(&self) -> Self::Writer {
159    MapWriter { origin: self.origin.clone_writer(), part_map: self.part_map.clone() }
160  }
161
162  #[inline]
163  fn origin_writer(&self) -> &Self::OriginWriter { &self.origin }
164}
165
166impl<V, S, F> RenderTarget for MapReader<S, F>
167where
168  S: StateReader,
169  F: Fn(&S::Value) -> PartData<V> + Clone + 'static,
170  V: Render,
171{
172  type Target = V;
173
174  fn proxy<T>(&self, f: impl FnOnce(&Self::Target) -> T) -> T {
175    let v = self.read();
176    f(&*v)
177  }
178}
179
180impl<V, S, F> RenderTarget for MapWriterAsReader<S, F>
181where
182  S: StateReader,
183  F: Fn(&mut S::Value) -> PartData<V> + Clone + 'static,
184  V: Render,
185{
186  type Target = V;
187
188  fn proxy<T>(&self, f: impl FnOnce(&Self::Target) -> T) -> T {
189    let v = self.read();
190    f(&*v)
191  }
192}
193
194impl<V, S, F> RenderBuilder for MapReader<S, F>
195where
196  S: StateReader,
197  F: Fn(&S::Value) -> PartData<V> + Clone + 'static,
198  V: Render,
199{
200  #[inline]
201  fn build(self, ctx: &BuildCtx) -> Widget { RenderProxy::new(self).build(ctx) }
202}
203
204impl<V, S, F> RenderBuilder for MapWriterAsReader<S, F>
205where
206  S: StateReader,
207  F: Fn(&mut S::Value) -> PartData<V> + Clone + 'static,
208  V: Render,
209{
210  #[inline]
211  fn build(self, ctx: &BuildCtx) -> Widget { RenderProxy::new(self).build(ctx) }
212}
213
214impl<V, S, WM> RenderBuilder for MapWriter<S, WM>
215where
216  Self: 'static,
217  S: StateWriter,
218  WM: Fn(&mut S::Value) -> PartData<V> + Clone,
219  V: Render,
220{
221  #[inline]
222  fn build(self, ctx: &BuildCtx) -> Widget { self.clone_reader().build(ctx) }
223}