mvutils2/
once.rs

1use std::any::Any;
2use std::cell::UnsafeCell;
3use std::error::Error;
4use std::fmt::{Display, Formatter};
5use std::ops::{Deref, DerefMut};
6use std::panic;
7use std::panic::{catch_unwind, RefUnwindSafe, UnwindSafe};
8use std::sync::{
9    atomic::{AtomicBool, Ordering},
10    Arc, Mutex, Once,
11};
12use crate::save::{Loader, Savable, Saver};
13
14#[derive(Debug, Default)]
15pub struct AlreadyInitialized;
16
17impl Display for AlreadyInitialized {
18    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
19        f.write_str("Value already initialized!")
20    }
21}
22
23impl Error for AlreadyInitialized {}
24
25pub enum InitError {
26    AlreadyInitialized(AlreadyInitialized),
27    Panicked(Box<dyn Any + Send + 'static>),
28}
29
30pub struct InitOnce<T> {
31    value: UnsafeCell<T>,
32    once: Once,
33    init_called: AtomicBool,
34}
35
36impl<T> InitOnce<T> {
37    pub const fn new(value: T) -> Self {
38        Self {
39            value: UnsafeCell::new(value),
40            once: Once::new(),
41            init_called: AtomicBool::new(false),
42        }
43    }
44
45    pub fn initialized(&self) -> bool {
46        self.init_called.load(Ordering::Relaxed)
47    }
48
49    pub fn init<F>(&self, f: F)
50    where
51        F: FnOnce(&mut T),
52    {
53        if self.init_called.swap(true, Ordering::SeqCst) {
54            panic!("InitOnce::init called twice");
55        }
56
57        self.once.call_once(|| {
58            let value = unsafe { &mut *self.value.get() };
59            f(value);
60        });
61    }
62
63    pub fn safe_init<F>(&self, f: F) -> Result<(), Box<dyn Any + Send + 'static>>
64    where
65        F: FnOnce(&mut T) + UnwindSafe,
66    {
67        if self.init_called.swap(true, Ordering::SeqCst) {
68            panic!("InitOnce::init called twice");
69        }
70
71        let panicked = Arc::new(Mutex::new(Some(Ok(()))));
72        let clone = panicked.clone();
73
74        self.once.call_once(|| {
75            let result = catch_unwind(|| {
76                let value = unsafe { &mut *self.value.get() };
77                f(value);
78            });
79
80            if let Err(e) = result {
81                clone.lock().unwrap().replace(Err(e));
82            }
83        });
84        let res = panicked.lock().unwrap().take().unwrap();
85        res
86    }
87
88    pub fn try_init<F>(&self, f: F) -> Result<(), AlreadyInitialized>
89    where
90        F: FnOnce(&mut T),
91    {
92        if self.init_called.swap(true, Ordering::SeqCst) {
93            return Err(AlreadyInitialized);
94        }
95
96        self.once.call_once(|| {
97            let value = unsafe { &mut *self.value.get() };
98            f(value);
99        });
100
101        Ok(())
102    }
103
104    pub fn try_safe_init<F>(&self, f: F) -> Result<(), InitError>
105    where
106        F: FnOnce(&mut T) + UnwindSafe,
107    {
108        if self.init_called.swap(true, Ordering::SeqCst) {
109            return Err(InitError::AlreadyInitialized(AlreadyInitialized));
110        }
111
112        let panicked = Arc::new(Mutex::new(Some(Ok(()))));
113
114        self.once.call_once(|| {
115            let result = catch_unwind(|| {
116                let value = unsafe { &mut *self.value.get() };
117                f(value);
118            });
119
120            if let Err(e) = result {
121                panicked
122                    .lock()
123                    .unwrap()
124                    .replace(Err(InitError::Panicked(e)));
125            }
126        });
127        let res = panicked.lock().unwrap().take().unwrap();
128        res
129    }
130}
131
132impl<T> Deref for InitOnce<T> {
133    type Target = T;
134
135    fn deref(&self) -> &Self::Target {
136        if !self.init_called.load(Ordering::Relaxed) {
137            panic!("InitOnce::deref called before InitOnce::init");
138        }
139        unsafe { &*self.value.get() }
140    }
141}
142
143impl<T: Display> Display for InitOnce<T> {
144    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
145        (**self).fmt(f)
146    }
147}
148
149impl<T> From<T> for InitOnce<T> {
150    fn from(value: T) -> Self {
151        Self::new(value)
152    }
153}
154
155impl<T: Savable> Savable for InitOnce<T> {
156    fn save(&self, saver: &mut impl Saver) {
157        self.value.save(saver);
158        self.init_called.load(Ordering::Acquire).save(saver);
159    }
160
161    fn load(loader: &mut impl Loader) -> Result<Self, String> {
162        let value = T::load(loader)?;
163        let init_called = AtomicBool::new(bool::load(loader)?);
164        Ok(InitOnce {
165            value: UnsafeCell::new(value),
166            once: Once::new(),
167            init_called,
168        })
169    }
170}
171
172unsafe impl<T: Send> Send for InitOnce<T> {}
173unsafe impl<T: Sync> Sync for InitOnce<T> {}
174impl<T> RefUnwindSafe for InitOnce<T> {}
175
176pub struct CreateOnce<T> {
177    value: UnsafeCell<Option<T>>,
178    once: Once,
179    init_called: AtomicBool,
180}
181
182impl<T> CreateOnce<T> {
183    pub const fn new() -> Self {
184        Self {
185            value: UnsafeCell::new(None),
186            once: Once::new(),
187            init_called: AtomicBool::new(false),
188        }
189    }
190    
191    pub const fn new_created(t: T) -> Self {
192        Self {
193            value: UnsafeCell::new(Some(t)),
194            once: Once::new(),
195            init_called: AtomicBool::new(true),
196        }
197    }
198
199    pub fn created(&self) -> bool {
200        self.init_called.load(Ordering::Relaxed)
201    }
202
203    pub fn create<F>(&self, f: F)
204    where
205        F: FnOnce() -> T,
206    {
207        if self.init_called.swap(true, Ordering::SeqCst) {
208            panic!("CreateOnce::create called twice");
209        }
210
211        self.once.call_once(|| {
212            let value = f();
213            unsafe { &mut *self.value.get() }.replace(value);
214        });
215    }
216
217    pub fn safe_create<F>(&self, f: F) -> Result<(), Box<dyn Any + Send + 'static>>
218    where
219        F: FnOnce() -> T + UnwindSafe,
220    {
221        if self.init_called.swap(true, Ordering::SeqCst) {
222            panic!("InitOnce::init called twice");
223        }
224
225        let panicked = Arc::new(Mutex::new(Some(Ok(()))));
226        let clone = panicked.clone();
227
228        self.once.call_once(|| {
229            let result = catch_unwind(|| {
230                let value = f();
231                unsafe { &mut *self.value.get() }.replace(value);
232            });
233
234            if let Err(e) = result {
235                clone.lock().unwrap().replace(Err(e));
236            }
237        });
238        let res = panicked.lock().unwrap().take().unwrap();
239        res
240    }
241
242    pub fn try_create<F>(&self, f: F) -> Result<(), AlreadyInitialized>
243    where
244        F: FnOnce() -> T,
245    {
246        if self.init_called.swap(true, Ordering::SeqCst) {
247            return Err(AlreadyInitialized);
248        }
249
250        self.once.call_once(|| {
251            let value = f();
252            unsafe { &mut *self.value.get() }.replace(value);
253        });
254
255        Ok(())
256    }
257
258    pub fn try_safe_create<F>(&self, f: F) -> Result<(), InitError>
259    where
260        F: FnOnce() -> T + UnwindSafe,
261    {
262        if self.init_called.swap(true, Ordering::SeqCst) {
263            return Err(InitError::AlreadyInitialized(AlreadyInitialized));
264        }
265
266        let panicked = Arc::new(Mutex::new(Some(Ok(()))));
267
268        self.once.call_once(|| {
269            let result = catch_unwind(|| {
270                let value = f();
271                unsafe { &mut *self.value.get() }.replace(value);
272            });
273
274            if let Err(e) = result {
275                panicked
276                    .lock()
277                    .unwrap()
278                    .replace(Err(InitError::Panicked(e)));
279            }
280        });
281        let res = panicked.lock().unwrap().take().unwrap();
282        res
283    }
284}
285
286impl<T: Default> CreateOnce<T> {
287    pub fn create_default(&self) {
288        self.create(T::default);
289    }
290
291    pub fn try_create_default(&self) -> Result<(), AlreadyInitialized> {
292        self.try_create(T::default)
293    }
294}
295
296impl<T> Default for CreateOnce<T> {
297    fn default() -> Self {
298        Self::new()
299    }
300}
301
302impl<T: Clone> Clone for CreateOnce<T> {
303    fn clone(&self) -> Self {
304        Self {
305            value: UnsafeCell::new(unsafe { &*self.value.get() }.clone()),
306            once: Once::new(),
307            init_called: AtomicBool::new(self.init_called.load(Ordering::Relaxed)),
308        }
309    }
310}
311
312impl<T> Deref for CreateOnce<T> {
313    type Target = T;
314
315    fn deref(&self) -> &Self::Target {
316        if !self.init_called.load(Ordering::Relaxed) {
317            panic!("CreateOnce::deref called before CreateOnce::create");
318        }
319
320        unsafe { self.value.get().as_ref().unwrap() }
321            .as_ref()
322            .unwrap()
323    }
324}
325
326impl<T> DerefMut for CreateOnce<T> {
327    fn deref_mut(&mut self) -> &mut Self::Target {
328        if !self.init_called.load(Ordering::Relaxed) {
329            panic!("CreateOnce::deref called before CreateOnce::create");
330        }
331
332        unsafe { self.value.get().as_mut().unwrap() }
333            .as_mut()
334            .unwrap()
335    }
336}
337
338impl<T: Display> Display for CreateOnce<T> {
339    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
340        (**self).fmt(f)
341    }
342}
343
344impl<T: Savable> Savable for CreateOnce<T> {
345    fn save(&self, saver: &mut impl Saver) {
346        self.value.save(saver);
347    }
348
349    fn load(loader: &mut impl Loader) -> Result<Self, String> {
350        let value = <Option<T>>::load(loader)?;
351        Ok(CreateOnce {
352            init_called: AtomicBool::new(value.is_some()),
353            value: UnsafeCell::new(value),
354            once: Once::new(),
355        })
356    }
357}
358
359unsafe impl<T: Send> Send for CreateOnce<T> {}
360unsafe impl<T: Sync> Sync for CreateOnce<T> {}
361impl<T> RefUnwindSafe for CreateOnce<T> {}
362
363pub struct Lazy<T> {
364    value: CreateOnce<T>,
365    init: Mutex<Option<fn() -> T>>,
366}
367
368impl<T> Lazy<T> {
369    pub const fn new(f: fn() -> T) -> Self {
370        Self {
371            value: CreateOnce::new(),
372            init: Mutex::new(Some(f)),
373        }
374    }
375    
376    pub const fn new_initialized(t: T) -> Self {
377        Lazy {
378            value: CreateOnce::new_created(t),
379            init: Mutex::new(None),
380        }
381    }
382
383    pub fn created(&self) -> bool {
384        self.value.created()
385    }
386}
387
388impl<T: Default> Lazy<T> {
389    pub const fn default() -> Self {
390        Self {
391            value: CreateOnce::new(),
392            init: Mutex::new(Some(T::default)),
393        }
394    }
395}
396
397impl<T> Deref for Lazy<T> {
398    type Target = T;
399
400    fn deref(&self) -> &Self::Target {
401        let mut f = self.init.lock().unwrap_or_else(|e| e.into_inner());
402        if let Some(f) = f.take() {
403            self.value.create(f);
404        }
405        &self.value
406    }
407}
408
409impl<T> DerefMut for Lazy<T> {
410    fn deref_mut(&mut self) -> &mut Self::Target {
411        let mut f = self.init.lock().unwrap_or_else(|e| e.into_inner());
412        if let Some(f) = f.take() {
413            self.value.create(f);
414        }
415        &mut self.value
416    }
417}
418
419impl<T: Display> Display for Lazy<T> {
420    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
421        (**self).fmt(f)
422    }
423}
424
425impl<T: Savable> Savable for Lazy<T> {
426    fn save(&self, saver: &mut impl Saver) {
427        Deref::deref(self).save(saver);
428    }
429
430    fn load(loader: &mut impl Loader) -> Result<Self, String> {
431        let value = T::load(loader)?;
432        Ok(Lazy {
433            value: CreateOnce {
434                value: UnsafeCell::new(Some(value)),
435                once: Once::new(),
436                init_called: AtomicBool::new(true),
437            },
438            init: Mutex::new(None),
439        })
440    }
441}
442
443unsafe impl<T: Send> Send for Lazy<T> {}
444unsafe impl<T: Sync> Sync for Lazy<T> {}
445impl<T> RefUnwindSafe for Lazy<T> {}
446
447pub struct LazyInitOnce<T> {
448    value: CreateOnce<InitOnce<T>>,
449    init: Mutex<Option<fn() -> T>>,
450}
451
452impl<T> LazyInitOnce<T> {
453    pub const fn new(f: fn() -> T) -> Self {
454        Self {
455            value: CreateOnce::new(),
456            init: Mutex::new(Some(f)),
457        }
458    }
459
460    pub fn created(&self) -> bool {
461        self.value.created()
462    }
463
464    pub fn initialized(&self) -> bool {
465        self.value.initialized()
466    }
467
468    pub fn init<F>(&self, f: F)
469    where
470        F: FnOnce(&mut T),
471    {
472        let mut init = self.init.lock().unwrap_or_else(|e| e.into_inner());
473        if let Some(init) = init.take() {
474            self.value.create(|| InitOnce::new(init()));
475        }
476        self.value.init(f);
477    }
478
479    pub fn safe_init<F>(&self, f: F) -> Result<(), Box<dyn Any + Send + 'static>>
480    where
481        F: FnOnce(&mut T) + UnwindSafe,
482    {
483        let mut init = self.init.lock().unwrap_or_else(|e| e.into_inner());
484        if let Some(init) = init.take() {
485            self.value.create(|| InitOnce::new(init()));
486        }
487        self.value.safe_init(f)
488    }
489
490    pub fn try_init<F>(&self, f: F) -> Result<(), AlreadyInitialized>
491    where
492        F: FnOnce(&mut T),
493    {
494        let mut init = self.init.lock().unwrap_or_else(|e| e.into_inner());
495        if let Some(init) = init.take() {
496            self.value.create(|| InitOnce::new(init()));
497        }
498        self.value.try_init(f)
499    }
500
501    pub fn try_safe_init<F>(&self, f: F) -> Result<(), InitError>
502    where
503        F: FnOnce(&mut T) + UnwindSafe,
504    {
505        let mut init = self.init.lock().unwrap_or_else(|e| e.into_inner());
506        if let Some(init) = init.take() {
507            self.value.create(|| InitOnce::new(init()));
508        }
509        self.value.try_safe_init(f)
510    }
511}
512
513impl<T: Default> LazyInitOnce<T> {
514    pub const fn default() -> Self {
515        Self {
516            value: CreateOnce::new(),
517            init: Mutex::new(Some(T::default)),
518        }
519    }
520}
521
522impl<T> Deref for LazyInitOnce<T> {
523    type Target = T;
524
525    fn deref(&self) -> &Self::Target {
526        if self
527            .init
528            .lock()
529            .unwrap_or_else(|e| e.into_inner())
530            .is_some()
531        {
532            panic!("InitOnce::deref called before InitOnce::init");
533        }
534        &self.value
535    }
536}
537
538impl<T: Display> Display for LazyInitOnce<T> {
539    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
540        (**self).fmt(f)
541    }
542}
543
544impl<T: Savable> Savable for LazyInitOnce<T> {
545    fn save(&self, saver: &mut impl Saver) {
546        Deref::deref(self).save(saver);
547    }
548
549    fn load(loader: &mut impl Loader) -> Result<Self, String> {
550        let value = T::load(loader)?;
551        Ok(LazyInitOnce {
552            value: CreateOnce {
553                value: UnsafeCell::new(Some(InitOnce {
554                    value: UnsafeCell::new(value),
555                    once: Once::new(),
556                    init_called: AtomicBool::new(true),
557                })),
558                once: Once::new(),
559                init_called: AtomicBool::new(true),
560            },
561            init: Mutex::new(None),
562        })
563    }
564}
565
566unsafe impl<T: Send> Send for LazyInitOnce<T> {}
567unsafe impl<T: Sync> Sync for LazyInitOnce<T> {}
568impl<T> RefUnwindSafe for LazyInitOnce<T> {}
569
570#[macro_export]
571macro_rules! lazy_init {
572    {
573        $(
574            $v:vis static $n:ident $($k:ident)?: $t:ty = $init:expr;
575        )*
576    } => {
577        $(
578            $v static $n $($k)?: $crate::once::LazyInitOnce<$t> = $crate::once::LazyInitOnce::new(|| { $init });
579        )*
580    };
581    {
582        $(
583            let $n:ident $($k:ident)?$(: $t:ty)? = $init:expr;
584        )*
585    } => {
586        $(
587            let $n $($k)?$(: $crate::once::LazyInitOnce<$t>)? = $crate::once::LazyInitOnce::new(|| { $init });
588        )*
589    };
590}
591
592#[macro_export]
593macro_rules! lazy {
594    {
595        $(
596            $v:vis static $n:ident $($k:ident)?: $t:ty = $init:expr;
597        )*
598    } => {
599        $(
600            $v static $n $($k)?: $crate::once::Lazy<$t> = $crate::once::Lazy::new(|| { $init });
601        )*
602    };
603    {
604        $(
605            let $n:ident $($k:ident)?$(: $t:ty)? = $init:expr;
606        )*
607    } => {
608        $(
609            let $n $($k)?$(: $crate::once::Lazy<$t>)? = $crate::once::Lazy::new(|| { $init });
610        )*
611    };
612}
613
614#[macro_export]
615macro_rules! create_once {
616     {
617        $(
618            $v:vis static $n:ident $($k:ident)?: $t:ty;
619        )*
620    } => {
621        $(
622            $v static $n $($k)?: $crate::once::CreateOnce<$t> = $crate::once::CreateOnce::new();
623        )*
624    };
625    {
626        $(
627            let $n:ident $($k:ident)?: $t:ty;
628        )*
629    } => {
630        $(
631            let $n $($k)?: $crate::once::CreateOnce<$t> = $crate::once::CreateOnce::new();
632        )*
633    };
634}