1#[cfg(no_std)]
2use alloc::boxed::Box;
3#[cfg(no_std)]
4use once_cell::race::OnceBox;
5#[cfg(std)]
6use std::sync::LazyLock;
7
8#[cfg(std)]
9use once_cell as _;
12
13#[cfg(std)]
14type Inner<T> = LazyLock<T, fn() -> T>;
15#[cfg(no_std)]
16type Inner<T> = OnceBox<T>;
17
18#[derive(Debug)]
23pub struct RacyLock<T: 'static> {
24 inner: Inner<T>,
25 #[cfg(no_std)]
26 init: fn() -> T,
27}
28
29impl<T: 'static> RacyLock<T> {
30 #[cfg(std)]
31 pub const fn new(init: fn() -> T) -> Self {
33 Self {
34 inner: LazyLock::new(init),
35 }
36 }
37
38 #[cfg(no_std)]
39 pub const fn new(init: fn() -> T) -> Self {
41 Self {
42 inner: OnceBox::new(),
43 init,
44 }
45 }
46}
47
48#[cfg(std)]
49impl<T: 'static> core::ops::Deref for RacyLock<T> {
50 type Target = T;
51
52 fn deref(&self) -> &Self::Target {
54 &self.inner
55 }
56}
57
58#[cfg(no_std)]
59impl<T: 'static> core::ops::Deref for RacyLock<T> {
60 type Target = T;
61
62 fn deref(&self) -> &Self::Target {
64 self.inner.get_or_init(|| Box::new((self.init)()))
65 }
66}