Skip to main content

qubit_codec/value/
decode_lifecycle_output.rs

1// =============================================================================
2//    Copyright (c) 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Owned output from a complete single-value decode lifecycle.
9
10/// Values produced by decode reset, the main decode, and decode finish.
11///
12/// This result keeps lifecycle output in phase order without allowing finish
13/// output to overwrite reset output.
14///
15/// # Type Parameters
16///
17/// - `V`: Logical value type produced by the codec.
18///
19/// # Examples
20///
21/// A stateless identity codec produces one lifecycle whose reset and finish
22/// phases stay empty:
23///
24/// ```
25/// use core::convert::Infallible;
26/// use core::num::NonZeroUsize;
27///
28/// use qubit_codec::Codec;
29/// use qubit_codec::CodecValueDecoder;
30/// use qubit_codec::DecodeFailure;
31/// use qubit_codec::DecodeLifecycleOutput;
32///
33/// struct Identity;
34///
35/// impl Codec for Identity {
36///     type Value = u8;
37///     type Unit = u8;
38///     type DecodeError = Infallible;
39///     type EncodeError = Infallible;
40///     const MIN_UNITS_PER_VALUE: usize = 1;
41///     const MAX_DECODE_UNITS_PER_VALUE: usize = 1;
42///     const MAX_ENCODE_UNITS_PER_VALUE: usize = 1;
43///
44///     unsafe fn decode(&mut self, input: &[u8], index: usize)
45///         -> Result<(u8, NonZeroUsize), DecodeFailure<Infallible>>
46///     {
47///         Ok((input[index], NonZeroUsize::MIN))
48///     }
49///
50///     unsafe fn encode(&mut self, value: &u8, output: &mut [u8], index: usize)
51///         -> Result<usize, Infallible>
52///     {
53///         output[index] = *value;
54///         Ok(1)
55///     }
56/// }
57///
58/// let output: DecodeLifecycleOutput<u8> =
59///     CodecValueDecoder::new(Identity).decode_lifecycle(&[7]).unwrap();
60/// assert_eq!(*output.value(), 7);
61/// assert!(output.reset().is_empty());
62/// assert!(output.finish().is_empty());
63///
64/// let (reset, value, finish) = output.into_parts();
65/// assert_eq!(value, 7);
66/// assert!(reset.is_empty() && finish.is_empty());
67/// ```
68#[derive(Clone, Debug, Eq, Hash, PartialEq)]
69#[must_use]
70pub struct DecodeLifecycleOutput<V> {
71    /// Values emitted while resetting decode state.
72    reset: Vec<V>,
73    /// Main value decoded from the supplied input.
74    value: V,
75    /// Values emitted while finishing decode state.
76    finish: Vec<V>,
77}
78
79impl<V> DecodeLifecycleOutput<V> {
80    /// Creates owned output from the three decode lifecycle phases.
81    ///
82    /// # Parameters
83    ///
84    /// - `reset`: Values emitted while resetting decode state.
85    /// - `value`: Main value decoded from the supplied input.
86    /// - `finish`: Values emitted while finishing decode state.
87    ///
88    /// # Returns
89    ///
90    /// Returns output preserving all three lifecycle phases.
91    #[inline]
92    pub(crate) fn new(reset: Vec<V>, value: V, finish: Vec<V>) -> Self {
93        Self { reset, value, finish }
94    }
95
96    /// Returns values emitted while resetting decode state.
97    ///
98    /// # Returns
99    ///
100    /// Returns the reset output in emission order.
101    #[inline]
102    #[must_use]
103    pub fn reset(&self) -> &[V] {
104        &self.reset
105    }
106
107    /// Returns the main value decoded from the supplied input.
108    ///
109    /// # Returns
110    ///
111    /// Returns a shared reference to the main decoded value.
112    #[inline]
113    #[must_use]
114    pub const fn value(&self) -> &V {
115        &self.value
116    }
117
118    /// Returns values emitted while finishing decode state.
119    ///
120    /// # Returns
121    ///
122    /// Returns the finish output in emission order.
123    #[inline]
124    #[must_use]
125    pub fn finish(&self) -> &[V] {
126        &self.finish
127    }
128
129    /// Consumes this result and returns all lifecycle phases.
130    ///
131    /// # Returns
132    ///
133    /// Returns reset values, the main decoded value, and finish values.
134    #[inline]
135    #[must_use]
136    pub fn into_parts(self) -> (Vec<V>, V, Vec<V>) {
137        (self.reset, self.value, self.finish)
138    }
139}