Skip to main content

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