qubit_codec/value/decode_lifecycle_progress.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//! Progress from a scratch-backed single-value decode lifecycle.
9
10/// Main decoded value and lifecycle output lengths written to caller storage.
11///
12/// # Type Parameters
13///
14/// - `V`: Logical value type produced by the codec.
15///
16/// # Examples
17///
18/// ```
19/// use core::convert::Infallible;
20/// use core::num::NonZeroUsize;
21///
22/// use qubit_codec::Codec;
23/// use qubit_codec::CodecValueDecoder;
24/// use qubit_codec::DecodeFailure;
25/// use qubit_codec::DecodeLifecycleProgress;
26///
27/// struct ByteCodec;
28/// impl Codec for ByteCodec {
29/// type Value = u8;
30/// type Unit = u8;
31/// type DecodeError = Infallible;
32/// type EncodeError = Infallible;
33/// const MIN_UNITS_PER_VALUE: usize = 1;
34/// const MAX_ENCODE_UNITS_PER_VALUE: usize = 1;
35/// const MAX_DECODE_UNITS_PER_VALUE: usize = 1;
36///
37/// unsafe fn decode(&mut self, input: &[u8], index: usize)
38/// -> Result<(u8, NonZeroUsize), DecodeFailure<Infallible>>
39/// {
40/// Ok((input[index], NonZeroUsize::MIN))
41/// }
42///
43/// unsafe fn encode(&mut self, value: &u8, output: &mut [u8], index: usize)
44/// -> Result<usize, Infallible>
45/// {
46/// output[index] = *value;
47/// Ok(1)
48/// }
49/// }
50///
51/// let mut decoder = CodecValueDecoder::new(ByteCodec);
52/// let progress: DecodeLifecycleProgress<u8> = decoder
53/// .decode_lifecycle_with_scratch(&[42], &mut [], &mut [])
54/// .unwrap();
55/// assert_eq!(*progress.value(), 42);
56/// assert_eq!(progress.reset_written(), 0);
57/// assert_eq!(progress.finish_written(), 0);
58/// ```
59#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
60#[must_use]
61pub struct DecodeLifecycleProgress<V> {
62 /// Main value decoded from the supplied input.
63 value: V,
64 /// Number of reset values written to caller storage.
65 reset_written: usize,
66 /// Number of finish values written to caller storage.
67 finish_written: usize,
68}
69
70impl<V> DecodeLifecycleProgress<V> {
71 /// Creates progress for a completed decode lifecycle.
72 ///
73 /// # Parameters
74 ///
75 /// - `value`: Main value decoded from the supplied input.
76 /// - `reset_written`: Number of reset values written to caller storage.
77 /// - `finish_written`: Number of finish values written to caller storage.
78 ///
79 /// # Returns
80 ///
81 /// Returns completed lifecycle progress.
82 #[inline]
83 pub(crate) const fn new(value: V, reset_written: usize, finish_written: usize) -> Self {
84 Self {
85 value,
86 reset_written,
87 finish_written,
88 }
89 }
90
91 /// Returns the main value decoded from the supplied input.
92 ///
93 /// # Returns
94 ///
95 /// Returns a shared reference to the main decoded value.
96 #[inline]
97 #[must_use]
98 pub const fn value(&self) -> &V {
99 &self.value
100 }
101
102 /// Returns the number of reset values written to caller storage.
103 ///
104 /// # Returns
105 ///
106 /// Returns the initialized reset output length.
107 #[inline]
108 #[must_use]
109 pub const fn reset_written(&self) -> usize {
110 self.reset_written
111 }
112
113 /// Returns the number of finish values written to caller storage.
114 ///
115 /// # Returns
116 ///
117 /// Returns the initialized finish output length.
118 #[inline]
119 #[must_use]
120 pub const fn finish_written(&self) -> usize {
121 self.finish_written
122 }
123
124 /// Consumes this progress and returns its components.
125 ///
126 /// # Returns
127 ///
128 /// Returns the main value, reset output length, and finish output length.
129 #[inline]
130 #[must_use]
131 pub fn into_parts(self) -> (V, usize, usize) {
132 (self.value, self.reset_written, self.finish_written)
133 }
134}