Skip to main content

hexga_utils/
lazy.rs

1use std::fmt::Debug;
2
3pub mod prelude
4{
5    pub use super::{LazyAccess, LazyFnMutValue, LazyFnOnceValue, LazyFnValue, LazyNew};
6}
7
8pub trait LazyAccess<T, F>
9{
10    fn is_init(&self) -> bool { self.observe().is_some() }
11    fn into_value(self) -> T;
12
13    fn as_ref(&mut self) -> &T { self.as_mut() }
14    fn as_mut(&mut self) -> &mut T;
15
16    fn observe(&self) -> Option<&T>;
17    fn observe_mut(&mut self) -> Option<&mut T>;
18}
19pub trait LazyNew<T, F>: LazyAccess<T, F>
20{
21    fn new(init: F) -> Self;
22}
23pub trait LazyWithValue<T, F>: LazyNew<T, F>
24{
25    fn with_value(value: T) -> Self;
26}
27
28pub struct LazyFnOnceValue<T, F>
29where
30    F: FnOnce() -> T,
31{
32    inner: LazyFnOnceValueInner<T, F>,
33}
34impl<T> Debug for LazyFnOnceValue<T, fn() -> T>
35where
36    T: Debug,
37{
38    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
39    {
40        write!(f, "{:?}", &self.inner)
41    }
42}
43impl<T> Default for LazyFnOnceValue<T, fn() -> T>
44where
45    T: Default,
46{
47    fn default() -> Self
48    {
49        Self {
50            inner: LazyFnOnceValueInner::default(),
51        }
52    }
53}
54impl<T, F> From<T> for LazyFnOnceValue<T, F>
55where
56    F: FnOnce() -> T,
57{
58    fn from(value: T) -> Self
59    {
60        Self {
61            inner: LazyFnOnceValueInner::from(value),
62        }
63    }
64}
65impl<T, F> LazyNew<T, F> for LazyFnOnceValue<T, F>
66where
67    F: FnOnce() -> T,
68{
69    fn new(init: F) -> Self
70    {
71        Self {
72            inner: LazyFnOnceValueInner::new(init),
73        }
74    }
75}
76impl<T, F> LazyWithValue<T, F> for LazyFnOnceValue<T, F>
77where
78    F: FnOnce() -> T,
79{
80    fn with_value(value: T) -> Self
81    {
82        Self {
83            inner: LazyFnOnceValueInner::with_value(value),
84        }
85    }
86}
87impl<T, F> LazyAccess<T, F> for LazyFnOnceValue<T, F>
88where
89    F: FnOnce() -> T,
90{
91    fn into_value(self) -> T { self.inner.into_value() }
92
93    fn as_mut(&mut self) -> &mut T { self.inner.as_mut() }
94
95    fn observe(&self) -> Option<&T> { self.inner.observe() }
96
97    fn observe_mut(&mut self) -> Option<&mut T> { self.inner.observe_mut() }
98}
99
100#[derive(Debug)]
101pub(crate) enum LazyFnOnceValueInner<T, F>
102where
103    F: FnOnce() -> T,
104{
105    Waiting(Option<F>),
106    Ready(T),
107}
108impl<T> Default for LazyFnOnceValueInner<T, fn() -> T>
109where
110    T: Default,
111{
112    fn default() -> Self { Self::new(T::default) }
113}
114impl<T, F> From<T> for LazyFnOnceValueInner<T, F>
115where
116    F: FnOnce() -> T,
117{
118    fn from(value: T) -> Self { Self::Ready(value) }
119}
120impl<T, F> LazyNew<T, F> for LazyFnOnceValueInner<T, F>
121where
122    F: FnOnce() -> T,
123{
124    fn new(init: F) -> Self { Self::Waiting(Some(init)) }
125}
126impl<T, F> LazyWithValue<T, F> for LazyFnOnceValueInner<T, F>
127where
128    F: FnOnce() -> T,
129{
130    fn with_value(value: T) -> Self { Self::Ready(value) }
131}
132impl<T, F> LazyAccess<T, F> for LazyFnOnceValueInner<T, F>
133where
134    F: FnOnce() -> T,
135{
136    fn as_mut(&mut self) -> &mut T
137    {
138        match self
139        {
140            LazyFnOnceValueInner::Ready(v) => v,
141            LazyFnOnceValueInner::Waiting(opt) =>
142            {
143                let f = opt.take().expect("should be defined");
144                let v = f();
145                *self = LazyFnOnceValueInner::Ready(v);
146                match self
147                {
148                    LazyFnOnceValueInner::Ready(v) => v,
149                    _ => unreachable!(),
150                }
151            }
152        }
153    }
154
155    fn into_value(mut self) -> T
156    {
157        self.as_mut();
158        match self
159        {
160            LazyFnOnceValueInner::Waiting(_) => unreachable!(),
161            LazyFnOnceValueInner::Ready(val) => val,
162        }
163    }
164
165    fn observe(&self) -> Option<&T>
166    {
167        match self
168        {
169            LazyFnOnceValueInner::Waiting(_) => None,
170            LazyFnOnceValueInner::Ready(v) => Some(v),
171        }
172    }
173
174    fn observe_mut(&mut self) -> Option<&mut T>
175    {
176        match self
177        {
178            LazyFnOnceValueInner::Waiting(_) => None,
179            LazyFnOnceValueInner::Ready(v) => Some(v),
180        }
181    }
182}
183
184pub struct LazyFnValue<T, F>
185where
186    F: Fn() -> T,
187{
188    init: F,
189    value: Option<T>,
190}
191impl<T> Debug for LazyFnValue<T, fn() -> T>
192where
193    T: Debug,
194{
195    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
196    {
197        write!(f, "{:?}", &self.value)
198    }
199}
200impl<T> Default for LazyFnValue<T, fn() -> T>
201where
202    T: Default,
203{
204    fn default() -> Self
205    {
206        Self {
207            init: Default::default,
208            value: None,
209        }
210    }
211}
212impl<T, F> LazyNew<T, F> for LazyFnValue<T, F>
213where
214    F: Fn() -> T,
215{
216    fn new(init: F) -> Self { Self { init, value: None } }
217}
218impl<T, F> LazyAccess<T, F> for LazyFnValue<T, F>
219where
220    F: Fn() -> T,
221{
222    fn into_value(self) -> T
223    {
224        match self.value
225        {
226            Some(v) => v,
227            None => (self.init)(),
228        }
229    }
230
231    fn as_mut(&mut self) -> &mut T
232    {
233        if self.value.is_none()
234        {
235            let val = (self.init)();
236            self.value = Some(val);
237        }
238
239        match self.value.as_mut()
240        {
241            Some(v) => v,
242            None => unreachable!(),
243        }
244    }
245
246    fn observe(&self) -> Option<&T> { self.value.as_ref() }
247
248    fn observe_mut(&mut self) -> Option<&mut T> { self.value.as_mut() }
249}
250
251pub struct LazyFnMutValue<T, F>
252where
253    F: FnMut() -> T,
254{
255    init: F,
256    value: Option<T>,
257}
258impl<T> Debug for LazyFnMutValue<T, fn() -> T>
259where
260    T: Debug,
261{
262    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
263    {
264        write!(f, "{:?}", &self.value)
265    }
266}
267impl<T> Default for LazyFnMutValue<T, fn() -> T>
268where
269    T: Default,
270{
271    fn default() -> Self
272    {
273        Self {
274            init: Default::default,
275            value: None,
276        }
277    }
278}
279impl<T, F> LazyNew<T, F> for LazyFnMutValue<T, F>
280where
281    F: FnMut() -> T,
282{
283    fn new(init: F) -> Self { Self { init, value: None } }
284}
285impl<T, F> LazyAccess<T, F> for LazyFnMutValue<T, F>
286where
287    F: FnMut() -> T,
288{
289    fn into_value(mut self) -> T
290    {
291        match self.value
292        {
293            Some(v) => v,
294            None => (self.init)(),
295        }
296    }
297
298    fn as_mut(&mut self) -> &mut T
299    {
300        if self.value.is_none()
301        {
302            let val = (self.init)();
303            self.value = Some(val);
304        }
305
306        match self.value.as_mut()
307        {
308            Some(v) => v,
309            None => unreachable!(),
310        }
311    }
312
313    fn observe(&self) -> Option<&T> { self.value.as_ref() }
314
315    fn observe_mut(&mut self) -> Option<&mut T> { self.value.as_mut() }
316}