1use crate::sealed;
2use crate::sync::OnceExt;
3
4#[cfg(wip_feature_std)]
7#[allow(clippy::disallowed_types)]
8type OnceInner = std::sync::Once;
9
10#[cfg(all(not(wip_feature_std), feature = "parking_lot"))]
11type OnceInner = parking_lot::Once;
12
13#[cfg(all(not(wip_feature_std), not(feature = "parking_lot")))]
14compile_error!("Please enable at least one of the following features: std, parking_lot");
15
16pub struct Once(OnceInner);
17
18impl Default for Once {
19 fn default() -> Self {
20 Self::new()
21 }
22}
23
24impl Once {
25 #[inline(always)]
27 #[must_use]
28 pub const fn new() -> Once {
29 Once(OnceInner::new())
30 }
31
32 #[inline]
33 pub fn call_once(&self, f: impl FnOnce()) {
34 self.0.call_once(f);
35 }
36
37 #[inline]
38 pub fn call_once_force(&self, f: impl FnOnce()) {
39 self.0.call_once_force(move |_| f());
40 }
41
42 #[inline(always)]
43 pub fn is_completed(&self) -> bool {
44 cfg_select! {
45 wip_feature_std => self.0.is_completed(),
46 feature = "parking_lot" => matches!(self.0.state(), parking_lot::OnceState::Done),
47 _ => compile_error!("Please enable at least one of the following features: std, parking_lot"),
48 }
49 }
50}
51
52impl sealed::Sealed for Once {}
53impl OnceExt for Once {
54 type OnceState = ();
55
56 fn call_once_py_attached(&self, py: crate::prelude::Python<'_>, f: impl FnOnce()) {
57 self.0.call_once_force_py_attached(py, move |_| f());
58 }
59
60 fn call_once_force_py_attached(
61 &self,
62 py: crate::prelude::Python<'_>,
63 f: impl FnOnce(&Self::OnceState),
64 ) {
65 self.0.call_once_force_py_attached(py, |_| f(&()));
66 }
67}
68
69pub mod non_poison {
70 #[cfg(wip_feature_std)]
72 pub use std::sync::MutexGuard;
73
74 #[cfg(all(not(wip_feature_std), feature = "parking_lot"))]
75 pub use parking_lot::{Mutex, MutexGuard};
76
77 #[cfg(all(not(wip_feature_std), not(feature = "parking_lot")))]
78 compile_error!("Please enable at least one of the following features: std, parking_lot");
79
80 #[cfg(wip_feature_std)]
81 #[derive(Default, Debug)]
82 pub struct Mutex<T: ?Sized> {
83 #[allow(clippy::disallowed_types)]
84 inner: std::sync::Mutex<T>,
85 }
86
87 #[cfg(wip_feature_std)]
88 impl<T> Mutex<T> {
89 #[inline(always)]
90 pub const fn new(t: T) -> Mutex<T> {
91 Mutex {
92 #[allow(clippy::disallowed_types)]
93 inner: std::sync::Mutex::new(t),
94 }
95 }
96
97 pub fn into_inner(self) -> T {
98 self.inner.into_inner().unwrap_or_else(|e| e.into_inner())
99 }
100 }
101
102 #[cfg(wip_feature_std)]
103 impl<T: ?Sized> Mutex<T> {
104 #[inline(always)]
105 pub fn lock(&self) -> std::sync::MutexGuard<'_, T> {
106 self.inner.lock().unwrap_or_else(|e| e.into_inner())
107 }
108
109 }
111
112 #[cfg(wip_feature_std)]
113 impl<T> From<T> for Mutex<T> {
114 #[inline(always)]
115 fn from(t: T) -> Self {
116 Mutex {
117 #[allow(clippy::disallowed_types)]
118 inner: std::sync::Mutex::new(t),
119 }
120 }
121 }
122
123 #[cfg(wip_feature_std)]
124 impl<T> crate::sealed::Sealed for Mutex<T> {}
125
126 #[cfg(wip_feature_std)]
127 impl<T> crate::sync::MutexExt<T> for Mutex<T> {
128 type LockResult<'a>
129 = MutexGuard<'a, T>
130 where
131 T: 'a;
132
133 fn lock_py_attached(&self, py: crate::prelude::Python<'_>) -> Self::LockResult<'_> {
134 self.inner
135 .lock_py_attached(py)
136 .unwrap_or_else(|e| e.into_inner())
137 }
138 }
139}