qubit_cas/cas_success.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//! Successful CAS execution results.
11
12use std::sync::Arc;
13
14use crate::event::CasContext;
15
16/// Successful result returned by [`crate::CasExecutor`].
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub enum CasSuccess<T, R> {
19 /// The executor installed a new state by compare-and-swap.
20 Updated {
21 /// Previous state observed by the successful attempt.
22 previous: Arc<T>,
23 /// Current state after the successful update.
24 current: Arc<T>,
25 /// Business output returned by the operation.
26 output: R,
27 /// Retry context captured when the flow completed.
28 context: CasContext,
29 },
30
31 /// The executor finished successfully without writing a new state.
32 Finished {
33 /// Current state that remained installed.
34 current: Arc<T>,
35 /// Business output returned by the operation.
36 output: R,
37 /// Retry context captured when the flow completed.
38 context: CasContext,
39 },
40}
41
42impl<T, R> CasSuccess<T, R> {
43 /// Creates an updated success result.
44 ///
45 /// # Parameters
46 /// - `previous`: Previous state.
47 /// - `current`: Current state after the update.
48 /// - `output`: Business output.
49 /// - `context`: Retry context for the completed flow.
50 ///
51 /// # Returns
52 /// A [`CasSuccess::Updated`] value.
53 #[inline]
54 pub(crate) fn updated(
55 previous: Arc<T>,
56 current: Arc<T>,
57 output: R,
58 context: CasContext,
59 ) -> Self {
60 Self::Updated {
61 previous,
62 current,
63 output,
64 context,
65 }
66 }
67
68 /// Creates a finished success result.
69 ///
70 /// # Parameters
71 /// - `current`: Current state.
72 /// - `output`: Business output.
73 /// - `context`: Retry context for the completed flow.
74 ///
75 /// # Returns
76 /// A [`CasSuccess::Finished`] value.
77 #[inline]
78 pub(crate) fn finished(current: Arc<T>, output: R, context: CasContext) -> Self {
79 Self::Finished {
80 current,
81 output,
82 context,
83 }
84 }
85
86 /// Returns whether this success performed a write.
87 ///
88 /// # Returns
89 /// `true` for [`CasSuccess::Updated`], `false` for
90 /// [`CasSuccess::Finished`].
91 #[inline]
92 pub fn is_updated(&self) -> bool {
93 matches!(self, Self::Updated { .. })
94 }
95
96 /// Returns the previous state when a write occurred.
97 ///
98 /// # Returns
99 /// `Some(&Arc<T>)` for [`CasSuccess::Updated`], or `None` when no write
100 /// occurred.
101 #[inline]
102 pub fn previous(&self) -> Option<&Arc<T>> {
103 match self {
104 Self::Updated { previous, .. } => Some(previous),
105 Self::Finished { .. } => None,
106 }
107 }
108
109 /// Returns the current state after success.
110 ///
111 /// # Returns
112 /// Shared reference to the current state.
113 #[inline]
114 pub fn current(&self) -> &Arc<T> {
115 match self {
116 Self::Updated { current, .. } | Self::Finished { current, .. } => current,
117 }
118 }
119
120 /// Returns the business output.
121 ///
122 /// # Returns
123 /// Shared reference to the business output.
124 #[inline]
125 pub fn output(&self) -> &R {
126 match self {
127 Self::Updated { output, .. } | Self::Finished { output, .. } => output,
128 }
129 }
130
131 /// Consumes the success result and returns the business output.
132 ///
133 /// # Returns
134 /// The owned business output.
135 #[inline]
136 pub fn into_output(self) -> R {
137 match self {
138 Self::Updated { output, .. } | Self::Finished { output, .. } => output,
139 }
140 }
141
142 /// Returns the retry context captured at success.
143 ///
144 /// # Returns
145 /// Retry context for the completed flow.
146 #[inline]
147 pub fn context(&self) -> CasContext {
148 match self {
149 Self::Updated { context, .. } | Self::Finished { context, .. } => *context,
150 }
151 }
152
153 /// Returns the number of attempts that were executed.
154 ///
155 /// # Returns
156 /// One-based attempt count.
157 #[inline]
158 pub fn attempts(&self) -> u32 {
159 self.context().attempt()
160 }
161}