Skip to main content

qubit_dcl/double_checked/
execution_context.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # Execution Context
10//!
11//! Provides execution context after double-checked lock task execution.
12//!
13//! # Author
14//!
15//! Haixing Hu
16use crate::double_checked::execution_result::ExecutionResult;
17
18/// Execution context (state after task execution)
19///
20/// This type provides result retrieval functionality after task execution.
21///
22/// Prepare lifecycle callbacks are configured on
23/// [`super::DoubleCheckedLockExecutor`] and are already applied before an
24/// `ExecutionContext` is returned. Task closures are responsible for their own
25/// rollback, cleanup, and commit logic.
26///
27/// # Type Parameters
28///
29/// * `T` - The type of the task return value
30/// * `E` - The type of the task error
31///
32/// # Author
33///
34/// Haixing Hu
35pub struct ExecutionContext<T, E>
36where
37    E: std::fmt::Display,
38{
39    /// Result produced by the double-checked execution.
40    result: ExecutionResult<T, E>,
41}
42
43impl<T, E> ExecutionContext<T, E>
44where
45    E: std::fmt::Display,
46{
47    /// Creates a new execution context.
48    ///
49    /// # Arguments
50    ///
51    /// * `result` - The execution result
52    ///
53    /// # Returns
54    ///
55    /// A context wrapping the supplied result.
56    #[inline]
57    pub(super) fn new(result: ExecutionResult<T, E>) -> Self {
58        Self { result }
59    }
60
61    /// Gets the execution result (consumes the context)
62    ///
63    /// Prepare commit or rollback callbacks have already been executed by the
64    /// builder before this context was created. This method does not trigger
65    /// additional side effects.
66    ///
67    /// # Returns
68    ///
69    /// The owned [`ExecutionResult`] stored in this context.
70    #[inline]
71    pub fn get_result(self) -> ExecutionResult<T, E> {
72        self.result
73    }
74
75    /// Checks the execution result (does not consume the context)
76    ///
77    /// # Returns
78    ///
79    /// A shared reference to the stored [`ExecutionResult`].
80    #[inline]
81    pub fn peek_result(&self) -> &ExecutionResult<T, E> {
82        &self.result
83    }
84
85    /// Checks if execution was successful
86    ///
87    /// # Returns
88    ///
89    /// `true` if the stored result is [`ExecutionResult::Success`].
90    #[inline]
91    pub fn is_success(&self) -> bool {
92        self.result.is_success()
93    }
94}
95
96// Convenience methods for cases without return values
97impl<E> ExecutionContext<(), E>
98where
99    E: std::fmt::Display,
100{
101    /// Completes execution (for operations without return values)
102    ///
103    /// Returns whether the execution was successful
104    ///
105    /// # Returns
106    ///
107    /// `true` if the stored result is [`ExecutionResult::Success`] containing
108    /// `()`.
109    #[inline]
110    pub fn finish(self) -> bool {
111        let result = self.get_result();
112        result.is_success()
113    }
114}