qubit_dcl/double_checked/double_checked_lock_ready_builder.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10//! Convenience ready-builder state for [`super::DoubleCheckedLock`].
11
12use std::fmt::Display;
13
14use qubit_function::{
15 Callable,
16 CallableWith,
17 Runnable,
18 RunnableWith,
19};
20
21use super::{
22 DoubleCheckedLockExecutor,
23 ExecutionContext,
24 executor_ready_builder::ExecutorReadyBuilder,
25};
26use crate::lock::Lock;
27
28/// Convenience builder state with tester attached.
29#[derive(Clone)]
30pub struct DoubleCheckedLockReadyBuilder<L, T> {
31 /// Reusable-executor builder delegated to by the convenience API.
32 pub(in crate::double_checked) inner: ExecutorReadyBuilder<L, T>,
33}
34
35impl<L, T> DoubleCheckedLockReadyBuilder<L, T>
36where
37 L: Lock<T>,
38{
39 /// Configures logging when the double-checked condition is not met.
40 ///
41 /// # Parameters
42 ///
43 /// * `level` - Log level used for unmet-condition messages.
44 /// * `message` - Full log message emitted when the condition is not met.
45 ///
46 /// # Returns
47 ///
48 /// This builder with unmet-condition logging configured.
49 #[inline]
50 #[must_use = "assign or chain the returned builder"]
51 pub fn log_unmet_condition(mut self, level: log::Level, message: impl Into<String>) -> Self {
52 self.inner = self.inner.log_unmet_condition(level, message);
53 self
54 }
55
56 /// Disables logging when the double-checked condition is not met.
57 ///
58 /// # Returns
59 ///
60 /// This builder with unmet-condition logging disabled.
61 #[inline]
62 #[must_use = "assign or chain the returned builder"]
63 pub fn disable_unmet_condition_logging(mut self) -> Self {
64 self.inner = self.inner.disable_unmet_condition_logging();
65 self
66 }
67
68 /// Configures logging when the prepare action fails.
69 ///
70 /// # Parameters
71 ///
72 /// * `level` - Log level used for prepare failure messages.
73 /// * `message_prefix` - Prefix placed before the prepare failure text.
74 ///
75 /// # Returns
76 ///
77 /// This builder with prepare failure logging configured.
78 #[inline]
79 #[must_use = "assign or chain the returned builder"]
80 pub fn log_prepare_failure(
81 mut self,
82 level: log::Level,
83 message_prefix: impl Into<String>,
84 ) -> Self {
85 self.inner = self.inner.log_prepare_failure(level, message_prefix);
86 self
87 }
88
89 /// Disables logging when the prepare action fails.
90 ///
91 /// # Returns
92 ///
93 /// This builder with prepare failure logging disabled.
94 #[inline]
95 #[must_use = "assign or chain the returned builder"]
96 pub fn disable_prepare_failure_logging(mut self) -> Self {
97 self.inner = self.inner.disable_prepare_failure_logging();
98 self
99 }
100
101 /// Configures logging when the prepare commit action fails.
102 ///
103 /// # Parameters
104 ///
105 /// * `level` - Log level used for prepare-commit failure messages.
106 /// * `message_prefix` - Prefix placed before the prepare-commit failure
107 /// text.
108 ///
109 /// # Returns
110 ///
111 /// This builder with prepare-commit failure logging configured.
112 #[inline]
113 #[must_use = "assign or chain the returned builder"]
114 pub fn log_prepare_commit_failure(
115 mut self,
116 level: log::Level,
117 message_prefix: impl Into<String>,
118 ) -> Self {
119 self.inner = self.inner.log_prepare_commit_failure(level, message_prefix);
120 self
121 }
122
123 /// Disables logging when the prepare commit action fails.
124 ///
125 /// # Returns
126 ///
127 /// This builder with prepare-commit failure logging disabled.
128 #[inline]
129 #[must_use = "assign or chain the returned builder"]
130 pub fn disable_prepare_commit_failure_logging(mut self) -> Self {
131 self.inner = self.inner.disable_prepare_commit_failure_logging();
132 self
133 }
134
135 /// Configures logging when the prepare rollback action fails.
136 ///
137 /// # Parameters
138 ///
139 /// * `level` - Log level used for prepare-rollback failure messages.
140 /// * `message_prefix` - Prefix placed before the prepare-rollback failure
141 /// text.
142 ///
143 /// # Returns
144 ///
145 /// This builder with prepare-rollback failure logging configured.
146 #[inline]
147 #[must_use = "assign or chain the returned builder"]
148 pub fn log_prepare_rollback_failure(
149 mut self,
150 level: log::Level,
151 message_prefix: impl Into<String>,
152 ) -> Self {
153 self.inner = self
154 .inner
155 .log_prepare_rollback_failure(level, message_prefix);
156 self
157 }
158
159 /// Disables logging when the prepare rollback action fails.
160 ///
161 /// # Returns
162 ///
163 /// This builder with prepare-rollback failure logging disabled.
164 #[inline]
165 #[must_use = "assign or chain the returned builder"]
166 pub fn disable_prepare_rollback_failure_logging(mut self) -> Self {
167 self.inner = self.inner.disable_prepare_rollback_failure_logging();
168 self
169 }
170
171 /// Enables panic capture for tester, prepare callbacks, and task execution.
172 ///
173 /// # Returns
174 ///
175 /// This builder with panic capture enabled.
176 #[inline]
177 #[must_use = "assign or chain the returned builder"]
178 pub fn catch_panics(mut self) -> Self {
179 self.inner = self.inner.catch_panics();
180 self
181 }
182
183 /// Derives a builder with panic capture enabled or disabled for tester,
184 /// prepare callbacks, and task execution.
185 ///
186 /// # Parameters
187 ///
188 /// * `catch_panics` - `true` to capture panics as execution errors, or
189 /// `false` to let panics unwind.
190 ///
191 /// # Returns
192 ///
193 /// A reconfigured builder with the updated panic-capture setting.
194 #[inline]
195 #[must_use = "assign or chain the returned builder"]
196 pub fn with_panic_capture(mut self, catch_panics: bool) -> Self {
197 self.inner = self.inner.with_panic_capture(catch_panics);
198 self
199 }
200
201 /// Disables panic capture for tester, prepare callbacks, and task execution.
202 ///
203 /// # Returns
204 ///
205 /// This builder with panic capture disabled.
206 #[inline]
207 #[must_use = "assign or chain the returned builder"]
208 pub fn disable_catch_panics(mut self) -> Self {
209 self.inner = self.inner.disable_catch_panics();
210 self
211 }
212
213 /// Sets the prepare action.
214 ///
215 /// # Parameters
216 ///
217 /// * `prepare_action` - Fallible action to run after the first condition
218 /// check and before locking.
219 ///
220 /// # Returns
221 ///
222 /// This builder with prepare configured.
223 ///
224 /// # Errors
225 ///
226 /// This builder method does not return errors. If `prepare_action` later
227 /// returns an error during execution, the execution result becomes
228 /// [`super::ExecutionResult::Failed`] with
229 /// [`super::ExecutorError::PrepareFailed`].
230 #[inline]
231 #[must_use = "assign or chain the returned builder"]
232 pub fn prepare<Rn, E>(mut self, prepare_action: Rn) -> Self
233 where
234 Rn: Runnable<E> + Send + 'static,
235 E: Display,
236 {
237 self.inner = self.inner.prepare(prepare_action);
238 self
239 }
240
241 /// Sets the rollback action for prepare.
242 ///
243 /// # Parameters
244 ///
245 /// * `rollback_prepare_action` - Fallible action to run when prepare
246 /// completed but the second condition check or task fails.
247 ///
248 /// # Returns
249 ///
250 /// This builder with prepare rollback configured.
251 ///
252 /// # Errors
253 ///
254 /// This builder method does not return errors. If
255 /// `rollback_prepare_action` later returns an error during execution, the
256 /// execution result becomes [`super::ExecutionResult::Failed`] with
257 /// [`super::ExecutorError::PrepareRollbackFailed`].
258 #[inline]
259 #[must_use = "assign or chain the returned builder"]
260 pub fn rollback_prepare<Rn, E>(mut self, rollback_prepare_action: Rn) -> Self
261 where
262 Rn: Runnable<E> + Send + 'static,
263 E: Display,
264 {
265 self.inner = self.inner.rollback_prepare(rollback_prepare_action);
266 self
267 }
268
269 /// Sets the commit action for prepare.
270 ///
271 /// # Parameters
272 ///
273 /// * `commit_prepare_action` - Fallible action to run when prepare
274 /// completed and the task succeeds.
275 ///
276 /// # Returns
277 ///
278 /// This builder with prepare commit configured.
279 ///
280 /// # Errors
281 ///
282 /// This builder method does not return errors. If `commit_prepare_action`
283 /// later returns an error during execution, the execution result becomes
284 /// [`super::ExecutionResult::Failed`] with
285 /// [`super::ExecutorError::PrepareCommitFailed`].
286 #[inline]
287 #[must_use = "assign or chain the returned builder"]
288 pub fn commit_prepare<Rn, E>(mut self, commit_prepare_action: Rn) -> Self
289 where
290 Rn: Runnable<E> + Send + 'static,
291 E: Display,
292 {
293 self.inner = self.inner.commit_prepare(commit_prepare_action);
294 self
295 }
296
297 /// Builds a reusable [`DoubleCheckedLockExecutor`].
298 ///
299 /// # Returns
300 ///
301 /// A reusable executor containing the configured lock, tester, logger, and
302 /// prepare lifecycle callbacks.
303 #[inline]
304 #[must_use = "use the returned executor"]
305 pub fn build(self) -> DoubleCheckedLockExecutor<L, T> {
306 self.inner.build()
307 }
308
309 /// Runs a callable task with one-shot executor creation.
310 ///
311 /// # Parameters
312 ///
313 /// * `task` - Zero-argument callable executed after both condition checks
314 /// pass.
315 ///
316 /// # Returns
317 ///
318 /// An [`ExecutionContext`] containing success, unmet-condition, or failure
319 /// information.
320 #[inline]
321 pub fn call<C, R, E>(self, task: C) -> ExecutionContext<R, E>
322 where
323 C: Callable<R, E>,
324 E: Display,
325 {
326 self.inner.build().call(task)
327 }
328
329 /// Runs a runnable task with one-shot executor creation.
330 ///
331 /// # Parameters
332 ///
333 /// * `task` - Zero-argument runnable executed after both condition checks
334 /// pass.
335 ///
336 /// # Returns
337 ///
338 /// An [`ExecutionContext`] containing success, unmet-condition, or failure
339 /// information.
340 #[inline]
341 pub fn execute<Rn, E>(self, task: Rn) -> ExecutionContext<(), E>
342 where
343 Rn: Runnable<E>,
344 E: Display,
345 {
346 self.inner.build().execute(task)
347 }
348
349 /// Runs a callable task with mutable protected data.
350 ///
351 /// # Parameters
352 ///
353 /// * `task` - Callable receiving `&mut T` after both condition checks pass.
354 ///
355 /// # Returns
356 ///
357 /// An [`ExecutionContext`] containing success, unmet-condition, or failure
358 /// information.
359 #[inline]
360 pub fn call_with<C, R, E>(self, task: C) -> ExecutionContext<R, E>
361 where
362 C: CallableWith<T, R, E>,
363 E: Display,
364 {
365 self.inner.build().call_with(task)
366 }
367
368 /// Runs a runnable task with mutable protected data.
369 ///
370 /// # Parameters
371 ///
372 /// * `task` - Runnable receiving `&mut T` after both condition checks pass.
373 ///
374 /// # Returns
375 ///
376 /// An [`ExecutionContext`] containing success, unmet-condition, or failure
377 /// information.
378 #[inline]
379 pub fn execute_with<Rn, E>(self, task: Rn) -> ExecutionContext<(), E>
380 where
381 Rn: RunnableWith<T, E>,
382 E: Display,
383 {
384 self.inner.build().execute_with(task)
385 }
386}