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}