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)]
9type Inner<T> = LazyLock<T, fn() -> T>;
10#[cfg(no_std)]
11type Inner<T> = OnceBox<T>;
12
13pub struct RacyLock<T: 'static> {
18 inner: Inner<T>,
19 #[cfg(no_std)]
20 init: fn() -> T,
21}
22
23impl<T: 'static> RacyLock<T> {
24 #[cfg(std)]
25 pub const fn new(init: fn() -> T) -> Self {
27 Self {
28 inner: LazyLock::new(init),
29 }
30 }
31
32 #[cfg(no_std)]
33 pub const fn new(init: fn() -> T) -> Self {
35 Self {
36 inner: OnceBox::new(),
37 init,
38 }
39 }
40}
41
42#[cfg(std)]
43impl<T: 'static> core::ops::Deref for RacyLock<T> {
44 type Target = T;
45
46 fn deref(&self) -> &Self::Target {
48 &self.inner
49 }
50}
51
52#[cfg(no_std)]
53impl<T: 'static> core::ops::Deref for RacyLock<T> {
54 type Target = T;
55
56 fn deref(&self) -> &Self::Target {
58 self.inner.get_or_init(|| Box::new((self.init)()))
59 }
60}