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}