qubit_dcl/double_checked/
double_checked_lock.rs1use std::fmt::Display;
19
20use qubit_function::{Callable, CallableWith, Runnable, RunnableWith, Tester};
21
22use super::{
23 DoubleCheckedLockExecutor, ExecutionContext, executor_lock_builder::ExecutorLockBuilder,
24 executor_ready_builder::ExecutorReadyBuilder,
25};
26use crate::lock::Lock;
27
28#[derive(Debug, Clone, Copy, Default)]
58pub struct DoubleCheckedLock;
59
60impl DoubleCheckedLock {
61 #[inline]
63 pub fn on<L, T>(lock: L) -> DoubleCheckedLockBuilder<L, T>
64 where
65 L: Lock<T>,
66 {
67 DoubleCheckedLockBuilder {
68 inner: DoubleCheckedLockExecutor::builder().on(lock),
69 }
70 }
71}
72
73#[derive(Clone)]
75pub struct DoubleCheckedLockBuilder<L, T> {
76 inner: ExecutorLockBuilder<L, T>,
77}
78
79impl<L, T> DoubleCheckedLockBuilder<L, T>
80where
81 L: Lock<T>,
82{
83 #[inline]
85 pub fn log_unmet_condition(mut self, level: log::Level, message: impl Into<String>) -> Self {
86 self.inner = self.inner.log_unmet_condition(level, message);
87 self
88 }
89
90 #[inline]
92 pub fn disable_unmet_condition_logging(mut self) -> Self {
93 self.inner = self.inner.disable_unmet_condition_logging();
94 self
95 }
96
97 #[inline]
99 pub fn log_prepare_failure(
100 mut self,
101 level: log::Level,
102 message_prefix: impl Into<String>,
103 ) -> Self {
104 self.inner = self.inner.log_prepare_failure(level, message_prefix);
105 self
106 }
107
108 #[inline]
110 pub fn disable_prepare_failure_logging(mut self) -> Self {
111 self.inner = self.inner.disable_prepare_failure_logging();
112 self
113 }
114
115 #[inline]
117 pub fn log_prepare_commit_failure(
118 mut self,
119 level: log::Level,
120 message_prefix: impl Into<String>,
121 ) -> Self {
122 self.inner = self.inner.log_prepare_commit_failure(level, message_prefix);
123 self
124 }
125
126 #[inline]
128 pub fn disable_prepare_commit_failure_logging(mut self) -> Self {
129 self.inner = self.inner.disable_prepare_commit_failure_logging();
130 self
131 }
132
133 #[inline]
135 pub fn log_prepare_rollback_failure(
136 mut self,
137 level: log::Level,
138 message_prefix: impl Into<String>,
139 ) -> Self {
140 self.inner = self
141 .inner
142 .log_prepare_rollback_failure(level, message_prefix);
143 self
144 }
145
146 #[inline]
148 pub fn disable_prepare_rollback_failure_logging(mut self) -> Self {
149 self.inner = self.inner.disable_prepare_rollback_failure_logging();
150 self
151 }
152
153 #[inline]
155 pub fn catch_panics(mut self) -> Self {
156 self.inner = self.inner.catch_panics();
157 self
158 }
159
160 #[inline]
163 pub fn set_catch_panics(mut self, catch_panics: bool) -> Self {
164 self.inner = self.inner.set_catch_panics(catch_panics);
165 self
166 }
167
168 #[inline]
170 pub fn disable_catch_panics(mut self) -> Self {
171 self.inner = self.inner.disable_catch_panics();
172 self
173 }
174
175 #[inline]
177 pub fn when<Tst>(self, tester: Tst) -> DoubleCheckedLockReadyBuilder<L, T>
178 where
179 Tst: Tester + Send + Sync + 'static,
180 {
181 DoubleCheckedLockReadyBuilder {
182 inner: self.inner.when(tester),
183 }
184 }
185}
186
187#[derive(Clone)]
189pub struct DoubleCheckedLockReadyBuilder<L, T> {
190 inner: ExecutorReadyBuilder<L, T>,
191}
192
193impl<L, T> DoubleCheckedLockReadyBuilder<L, T>
194where
195 L: Lock<T>,
196{
197 #[inline]
199 pub fn log_unmet_condition(mut self, level: log::Level, message: impl Into<String>) -> Self {
200 self.inner = self.inner.log_unmet_condition(level, message);
201 self
202 }
203
204 #[inline]
206 pub fn disable_unmet_condition_logging(mut self) -> Self {
207 self.inner = self.inner.disable_unmet_condition_logging();
208 self
209 }
210
211 #[inline]
213 pub fn log_prepare_failure(
214 mut self,
215 level: log::Level,
216 message_prefix: impl Into<String>,
217 ) -> Self {
218 self.inner = self.inner.log_prepare_failure(level, message_prefix);
219 self
220 }
221
222 #[inline]
224 pub fn disable_prepare_failure_logging(mut self) -> Self {
225 self.inner = self.inner.disable_prepare_failure_logging();
226 self
227 }
228
229 #[inline]
231 pub fn log_prepare_commit_failure(
232 mut self,
233 level: log::Level,
234 message_prefix: impl Into<String>,
235 ) -> Self {
236 self.inner = self.inner.log_prepare_commit_failure(level, message_prefix);
237 self
238 }
239
240 #[inline]
242 pub fn disable_prepare_commit_failure_logging(mut self) -> Self {
243 self.inner = self.inner.disable_prepare_commit_failure_logging();
244 self
245 }
246
247 #[inline]
249 pub fn log_prepare_rollback_failure(
250 mut self,
251 level: log::Level,
252 message_prefix: impl Into<String>,
253 ) -> Self {
254 self.inner = self
255 .inner
256 .log_prepare_rollback_failure(level, message_prefix);
257 self
258 }
259
260 #[inline]
262 pub fn disable_prepare_rollback_failure_logging(mut self) -> Self {
263 self.inner = self.inner.disable_prepare_rollback_failure_logging();
264 self
265 }
266
267 #[inline]
269 pub fn catch_panics(mut self) -> Self {
270 self.inner = self.inner.catch_panics();
271 self
272 }
273
274 #[inline]
277 pub fn set_catch_panics(mut self, catch_panics: bool) -> Self {
278 self.inner = self.inner.set_catch_panics(catch_panics);
279 self
280 }
281
282 #[inline]
284 pub fn disable_catch_panics(mut self) -> Self {
285 self.inner = self.inner.disable_catch_panics();
286 self
287 }
288
289 #[inline]
291 pub fn prepare<Rn, E>(mut self, prepare_action: Rn) -> Self
292 where
293 Rn: Runnable<E> + Send + 'static,
294 E: Display,
295 {
296 self.inner = self.inner.prepare(prepare_action);
297 self
298 }
299
300 #[inline]
302 pub fn rollback_prepare<Rn, E>(mut self, rollback_prepare_action: Rn) -> Self
303 where
304 Rn: Runnable<E> + Send + 'static,
305 E: Display,
306 {
307 self.inner = self.inner.rollback_prepare(rollback_prepare_action);
308 self
309 }
310
311 #[inline]
313 pub fn commit_prepare<Rn, E>(mut self, commit_prepare_action: Rn) -> Self
314 where
315 Rn: Runnable<E> + Send + 'static,
316 E: Display,
317 {
318 self.inner = self.inner.commit_prepare(commit_prepare_action);
319 self
320 }
321
322 #[inline]
324 pub fn build(self) -> DoubleCheckedLockExecutor<L, T> {
325 self.inner.build()
326 }
327
328 #[inline]
330 pub fn call<C, R, E>(self, task: C) -> ExecutionContext<R, E>
331 where
332 C: Callable<R, E>,
333 E: Display,
334 {
335 self.inner.build().call(task)
336 }
337
338 #[inline]
340 pub fn execute<Rn, E>(self, task: Rn) -> ExecutionContext<(), E>
341 where
342 Rn: Runnable<E>,
343 E: Display,
344 {
345 self.inner.build().execute(task)
346 }
347
348 #[inline]
350 pub fn call_with<C, R, E>(self, task: C) -> ExecutionContext<R, E>
351 where
352 C: CallableWith<T, R, E>,
353 E: Display,
354 {
355 self.inner.build().call_with(task)
356 }
357
358 #[inline]
360 pub fn execute_with<Rn, E>(self, task: Rn) -> ExecutionContext<(), E>
361 where
362 Rn: RunnableWith<T, E>,
363 E: Display,
364 {
365 self.inner.build().execute_with(task)
366 }
367}