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}