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 qubit_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(mut self, level: log::Level, message_prefix: impl Into<String>) -> Self {
81 self.inner = self.inner.log_prepare_failure(level, message_prefix);
82 self
83 }
84
85 /// Disables logging when the prepare action fails.
86 ///
87 /// # Returns
88 ///
89 /// This builder with prepare failure logging disabled.
90 #[inline]
91 #[must_use = "assign or chain the returned builder"]
92 pub fn disable_prepare_failure_logging(mut self) -> Self {
93 self.inner = self.inner.disable_prepare_failure_logging();
94 self
95 }
96
97 /// Configures logging when the prepare commit action fails.
98 ///
99 /// # Parameters
100 ///
101 /// * `level` - Log level used for prepare-commit failure messages.
102 /// * `message_prefix` - Prefix placed before the prepare-commit failure
103 /// text.
104 ///
105 /// # Returns
106 ///
107 /// This builder with prepare-commit failure logging configured.
108 #[inline]
109 #[must_use = "assign or chain the returned builder"]
110 pub fn log_prepare_commit_failure(mut self, level: log::Level, message_prefix: impl Into<String>) -> Self {
111 self.inner = self.inner.log_prepare_commit_failure(level, message_prefix);
112 self
113 }
114
115 /// Disables logging when the prepare commit action fails.
116 ///
117 /// # Returns
118 ///
119 /// This builder with prepare-commit failure logging disabled.
120 #[inline]
121 #[must_use = "assign or chain the returned builder"]
122 pub fn disable_prepare_commit_failure_logging(mut self) -> Self {
123 self.inner = self.inner.disable_prepare_commit_failure_logging();
124 self
125 }
126
127 /// Configures logging when the prepare rollback action fails.
128 ///
129 /// # Parameters
130 ///
131 /// * `level` - Log level used for prepare-rollback failure messages.
132 /// * `message_prefix` - Prefix placed before the prepare-rollback failure
133 /// text.
134 ///
135 /// # Returns
136 ///
137 /// This builder with prepare-rollback failure logging configured.
138 #[inline]
139 #[must_use = "assign or chain the returned builder"]
140 pub fn log_prepare_rollback_failure(mut self, level: log::Level, message_prefix: impl Into<String>) -> Self {
141 self.inner = self.inner.log_prepare_rollback_failure(level, message_prefix);
142 self
143 }
144
145 /// Disables logging when the prepare rollback action fails.
146 ///
147 /// # Returns
148 ///
149 /// This builder with prepare-rollback failure logging disabled.
150 #[inline]
151 #[must_use = "assign or chain the returned builder"]
152 pub fn disable_prepare_rollback_failure_logging(mut self) -> Self {
153 self.inner = self.inner.disable_prepare_rollback_failure_logging();
154 self
155 }
156
157 /// Enables panic capture for tester, prepare callbacks, and task execution.
158 ///
159 /// # Returns
160 ///
161 /// This builder with panic capture enabled.
162 #[inline]
163 #[must_use = "assign or chain the returned builder"]
164 pub fn catch_panics(mut self) -> Self {
165 self.inner = self.inner.catch_panics();
166 self
167 }
168
169 /// Derives a builder with panic capture enabled or disabled for tester,
170 /// prepare callbacks, and task execution.
171 ///
172 /// # Parameters
173 ///
174 /// * `catch_panics` - `true` to capture panics as execution errors, or
175 /// `false` to let panics unwind.
176 ///
177 /// # Returns
178 ///
179 /// A reconfigured builder with the updated panic-capture setting.
180 #[inline]
181 #[must_use = "assign or chain the returned builder"]
182 pub fn with_panic_capture(mut self, catch_panics: bool) -> Self {
183 self.inner = self.inner.with_panic_capture(catch_panics);
184 self
185 }
186
187 /// Disables panic capture for tester, prepare callbacks, and task execution.
188 ///
189 /// # Returns
190 ///
191 /// This builder with panic capture disabled.
192 #[inline]
193 #[must_use = "assign or chain the returned builder"]
194 pub fn disable_catch_panics(mut self) -> Self {
195 self.inner = self.inner.disable_catch_panics();
196 self
197 }
198
199 /// Sets the prepare action.
200 ///
201 /// # Parameters
202 ///
203 /// * `prepare_action` - Fallible action to run after the first condition
204 /// check and before locking.
205 ///
206 /// # Returns
207 ///
208 /// This builder with prepare configured.
209 ///
210 /// # Errors
211 ///
212 /// This builder method does not return errors. If `prepare_action` later
213 /// returns an error during execution, the execution result becomes
214 /// [`super::ExecutionResult::Failed`] with
215 /// [`super::ExecutorError::PrepareFailed`].
216 #[inline]
217 #[must_use = "assign or chain the returned builder"]
218 pub fn prepare<Rn, E>(mut self, prepare_action: Rn) -> Self
219 where
220 Rn: Runnable<E> + Send + 'static,
221 E: Display,
222 {
223 self.inner = self.inner.prepare(prepare_action);
224 self
225 }
226
227 /// Sets the rollback action for prepare.
228 ///
229 /// # Parameters
230 ///
231 /// * `rollback_prepare_action` - Fallible action to run when prepare
232 /// completed but the second condition check or task fails.
233 ///
234 /// # Returns
235 ///
236 /// This builder with prepare rollback configured.
237 ///
238 /// # Errors
239 ///
240 /// This builder method does not return errors. If
241 /// `rollback_prepare_action` later returns an error during execution, the
242 /// execution result becomes [`super::ExecutionResult::Failed`] with
243 /// [`super::ExecutorError::PrepareRollbackFailed`].
244 #[inline]
245 #[must_use = "assign or chain the returned builder"]
246 pub fn rollback_prepare<Rn, E>(mut self, rollback_prepare_action: Rn) -> Self
247 where
248 Rn: Runnable<E> + Send + 'static,
249 E: Display,
250 {
251 self.inner = self.inner.rollback_prepare(rollback_prepare_action);
252 self
253 }
254
255 /// Sets the commit action for prepare.
256 ///
257 /// # Parameters
258 ///
259 /// * `commit_prepare_action` - Fallible action to run when prepare
260 /// completed and the task succeeds.
261 ///
262 /// # Returns
263 ///
264 /// This builder with prepare commit configured.
265 ///
266 /// # Errors
267 ///
268 /// This builder method does not return errors. If `commit_prepare_action`
269 /// later returns an error during execution, the execution result becomes
270 /// [`super::ExecutionResult::Failed`] with
271 /// [`super::ExecutorError::PrepareCommitFailed`].
272 #[inline]
273 #[must_use = "assign or chain the returned builder"]
274 pub fn commit_prepare<Rn, E>(mut self, commit_prepare_action: Rn) -> Self
275 where
276 Rn: Runnable<E> + Send + 'static,
277 E: Display,
278 {
279 self.inner = self.inner.commit_prepare(commit_prepare_action);
280 self
281 }
282
283 /// Builds a reusable [`DoubleCheckedLockExecutor`].
284 ///
285 /// # Returns
286 ///
287 /// A reusable executor containing the configured lock, tester, logger, and
288 /// prepare lifecycle callbacks.
289 #[inline]
290 #[must_use = "use the returned executor"]
291 pub fn build(self) -> DoubleCheckedLockExecutor<L, T> {
292 self.inner.build()
293 }
294
295 /// Runs a callable task with one-shot executor creation.
296 ///
297 /// # Parameters
298 ///
299 /// * `task` - Zero-argument callable executed after both condition checks
300 /// pass.
301 ///
302 /// # Returns
303 ///
304 /// An [`ExecutionContext`] containing success, unmet-condition, or failure
305 /// information.
306 #[inline]
307 pub fn call<C, R, E>(self, task: C) -> ExecutionContext<R, E>
308 where
309 C: Callable<R, E>,
310 E: Display,
311 {
312 self.inner.build().call(task)
313 }
314
315 /// Runs a runnable task with one-shot executor creation.
316 ///
317 /// # Parameters
318 ///
319 /// * `task` - Zero-argument runnable executed after both condition checks
320 /// pass.
321 ///
322 /// # Returns
323 ///
324 /// An [`ExecutionContext`] containing success, unmet-condition, or failure
325 /// information.
326 #[inline]
327 pub fn execute<Rn, E>(self, task: Rn) -> ExecutionContext<(), E>
328 where
329 Rn: Runnable<E>,
330 E: Display,
331 {
332 self.inner.build().execute(task)
333 }
334
335 /// Runs a callable task with mutable protected data.
336 ///
337 /// # Parameters
338 ///
339 /// * `task` - Callable receiving `&mut T` after both condition checks pass.
340 ///
341 /// # Returns
342 ///
343 /// An [`ExecutionContext`] containing success, unmet-condition, or failure
344 /// information.
345 #[inline]
346 pub fn call_with<C, R, E>(self, task: C) -> ExecutionContext<R, E>
347 where
348 C: CallableWith<T, R, E>,
349 E: Display,
350 {
351 self.inner.build().call_with(task)
352 }
353
354 /// Runs a runnable task with mutable protected data.
355 ///
356 /// # Parameters
357 ///
358 /// * `task` - Runnable receiving `&mut T` after both condition checks pass.
359 ///
360 /// # Returns
361 ///
362 /// An [`ExecutionContext`] containing success, unmet-condition, or failure
363 /// information.
364 #[inline]
365 pub fn execute_with<Rn, E>(self, task: Rn) -> ExecutionContext<(), E>
366 where
367 Rn: RunnableWith<T, E>,
368 E: Display,
369 {
370 self.inner.build().execute_with(task)
371 }
372}