Skip to main content

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}