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}