Skip to main content

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::{Callable, CallableWith, Runnable, RunnableWith};
15
16use super::{
17    DoubleCheckedLockExecutor, ExecutionContext, executor_ready_builder::ExecutorReadyBuilder,
18};
19use crate::lock::Lock;
20
21/// Convenience builder state with tester attached.
22#[derive(Clone)]
23pub struct DoubleCheckedLockReadyBuilder<L, T> {
24    /// Reusable-executor builder delegated to by the convenience API.
25    pub(in crate::double_checked) inner: ExecutorReadyBuilder<L, T>,
26}
27
28impl<L, T> DoubleCheckedLockReadyBuilder<L, T>
29where
30    L: Lock<T>,
31{
32    /// Configures logging when the double-checked condition is not met.
33    #[inline]
34    pub fn log_unmet_condition(mut self, level: log::Level, message: impl Into<String>) -> Self {
35        self.inner = self.inner.log_unmet_condition(level, message);
36        self
37    }
38
39    /// Disables logging when the double-checked condition is not met.
40    #[inline]
41    pub fn disable_unmet_condition_logging(mut self) -> Self {
42        self.inner = self.inner.disable_unmet_condition_logging();
43        self
44    }
45
46    /// Configures logging when the prepare action fails.
47    #[inline]
48    pub fn log_prepare_failure(
49        mut self,
50        level: log::Level,
51        message_prefix: impl Into<String>,
52    ) -> Self {
53        self.inner = self.inner.log_prepare_failure(level, message_prefix);
54        self
55    }
56
57    /// Disables logging when the prepare action fails.
58    #[inline]
59    pub fn disable_prepare_failure_logging(mut self) -> Self {
60        self.inner = self.inner.disable_prepare_failure_logging();
61        self
62    }
63
64    /// Configures logging when the prepare commit action fails.
65    #[inline]
66    pub fn log_prepare_commit_failure(
67        mut self,
68        level: log::Level,
69        message_prefix: impl Into<String>,
70    ) -> Self {
71        self.inner = self.inner.log_prepare_commit_failure(level, message_prefix);
72        self
73    }
74
75    /// Disables logging when the prepare commit action fails.
76    #[inline]
77    pub fn disable_prepare_commit_failure_logging(mut self) -> Self {
78        self.inner = self.inner.disable_prepare_commit_failure_logging();
79        self
80    }
81
82    /// Configures logging when the prepare rollback action fails.
83    #[inline]
84    pub fn log_prepare_rollback_failure(
85        mut self,
86        level: log::Level,
87        message_prefix: impl Into<String>,
88    ) -> Self {
89        self.inner = self
90            .inner
91            .log_prepare_rollback_failure(level, message_prefix);
92        self
93    }
94
95    /// Disables logging when the prepare rollback action fails.
96    #[inline]
97    pub fn disable_prepare_rollback_failure_logging(mut self) -> Self {
98        self.inner = self.inner.disable_prepare_rollback_failure_logging();
99        self
100    }
101
102    /// Enables panic capture for tester, prepare callbacks, and task execution.
103    #[inline]
104    pub fn catch_panics(mut self) -> Self {
105        self.inner = self.inner.catch_panics();
106        self
107    }
108
109    /// Sets whether panic capture for tester, prepare callbacks, and task
110    /// execution is enabled.
111    #[inline]
112    pub fn set_catch_panics(mut self, catch_panics: bool) -> Self {
113        self.inner = self.inner.set_catch_panics(catch_panics);
114        self
115    }
116
117    /// Disables panic capture for tester, prepare callbacks, and task execution.
118    #[inline]
119    pub fn disable_catch_panics(mut self) -> Self {
120        self.inner = self.inner.disable_catch_panics();
121        self
122    }
123
124    /// Sets the prepare action.
125    #[inline]
126    pub fn prepare<Rn, E>(mut self, prepare_action: Rn) -> Self
127    where
128        Rn: Runnable<E> + Send + 'static,
129        E: Display,
130    {
131        self.inner = self.inner.prepare(prepare_action);
132        self
133    }
134
135    /// Sets the rollback action for prepare.
136    #[inline]
137    pub fn rollback_prepare<Rn, E>(mut self, rollback_prepare_action: Rn) -> Self
138    where
139        Rn: Runnable<E> + Send + 'static,
140        E: Display,
141    {
142        self.inner = self.inner.rollback_prepare(rollback_prepare_action);
143        self
144    }
145
146    /// Sets the commit action for prepare.
147    #[inline]
148    pub fn commit_prepare<Rn, E>(mut self, commit_prepare_action: Rn) -> Self
149    where
150        Rn: Runnable<E> + Send + 'static,
151        E: Display,
152    {
153        self.inner = self.inner.commit_prepare(commit_prepare_action);
154        self
155    }
156
157    /// Builds a reusable [`DoubleCheckedLockExecutor`].
158    #[inline]
159    pub fn build(self) -> DoubleCheckedLockExecutor<L, T> {
160        self.inner.build()
161    }
162
163    /// Runs a callable task with one-shot executor creation.
164    #[inline]
165    pub fn call<C, R, E>(self, task: C) -> ExecutionContext<R, E>
166    where
167        C: Callable<R, E>,
168        E: Display,
169    {
170        self.inner.build().call(task)
171    }
172
173    /// Runs a runnable task with one-shot executor creation.
174    #[inline]
175    pub fn execute<Rn, E>(self, task: Rn) -> ExecutionContext<(), E>
176    where
177        Rn: Runnable<E>,
178        E: Display,
179    {
180        self.inner.build().execute(task)
181    }
182
183    /// Runs a callable task with mutable protected data.
184    #[inline]
185    pub fn call_with<C, R, E>(self, task: C) -> ExecutionContext<R, E>
186    where
187        C: CallableWith<T, R, E>,
188        E: Display,
189    {
190        self.inner.build().call_with(task)
191    }
192
193    /// Runs a runnable task with mutable protected data.
194    #[inline]
195    pub fn execute_with<Rn, E>(self, task: Rn) -> ExecutionContext<(), E>
196    where
197        Rn: RunnableWith<T, E>,
198        E: Display,
199    {
200        self.inner.build().execute_with(task)
201    }
202}