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