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