qubit_codec/transcode/engine/decode_context.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//! Decode context passed to buffered decoder policy hooks.
9
10/// Context for one codec decode attempt inside a buffered decoder engine.
11///
12/// # Examples
13///
14/// ```
15/// use qubit_codec::engine::DecodeContext;
16///
17/// let context = DecodeContext::new(0, 0, 0, 0, 2);
18/// assert_eq!(context.available(), 2);
19/// ```
20#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
21pub struct DecodeContext {
22 /// Absolute source index where this `transcode` call starts.
23 input_start: usize,
24 /// Absolute source index where the attempted value starts.
25 input_index: usize,
26 /// Absolute output index where this `transcode` call starts.
27 output_start: usize,
28 /// Absolute output index where the next decoded value would be written.
29 output_index: usize,
30 /// Units visible to the codec from `input_index`.
31 available: usize,
32}
33
34impl DecodeContext {
35 /// Creates a decode context.
36 ///
37 /// # Parameters
38 ///
39 /// - `input_start`: Absolute source index where this `transcode` call
40 /// starts.
41 /// - `input_index`: Absolute source index where the attempted value starts.
42 /// - `output_start`: Absolute output index where this `transcode` call
43 /// starts.
44 /// - `output_index`: Absolute output index where the next value would be
45 /// written.
46 /// - `available`: Units visible to the codec from `input_index`.
47 ///
48 /// # Returns
49 ///
50 /// Returns a decode context.
51 ///
52 /// # Panics
53 ///
54 /// Panics when `input_index < input_start` or
55 /// `output_index < output_start`.
56 #[inline(always)]
57 #[must_use]
58 pub const fn new(
59 input_start: usize,
60 input_index: usize,
61 output_start: usize,
62 output_index: usize,
63 available: usize,
64 ) -> Self {
65 assert!(
66 input_start <= input_index,
67 "decode context input index must not precede input start",
68 );
69 assert!(
70 output_start <= output_index,
71 "decode context output index must not precede output start",
72 );
73 Self {
74 input_start,
75 input_index,
76 output_start,
77 output_index,
78 available,
79 }
80 }
81
82 /// Returns the absolute source index where this `transcode` call starts.
83 ///
84 /// # Returns
85 ///
86 /// Returns the input start index.
87 #[inline(always)]
88 #[must_use]
89 pub const fn input_start(self) -> usize {
90 self.input_start
91 }
92
93 /// Returns the absolute source index where the attempted value starts.
94 ///
95 /// # Returns
96 ///
97 /// Returns the current input index.
98 #[inline(always)]
99 #[must_use]
100 pub const fn input_index(self) -> usize {
101 self.input_index
102 }
103
104 /// Returns the absolute output index where this `transcode` call starts.
105 ///
106 /// # Returns
107 ///
108 /// Returns the output start index.
109 #[inline(always)]
110 #[must_use]
111 pub const fn output_start(self) -> usize {
112 self.output_start
113 }
114
115 /// Returns the absolute output index where the next decoded value would be
116 /// written.
117 ///
118 /// # Returns
119 ///
120 /// Returns the current output index.
121 #[inline(always)]
122 #[must_use]
123 pub const fn output_index(self) -> usize {
124 self.output_index
125 }
126
127 /// Returns units visible to the codec from [`Self::input_index`].
128 ///
129 /// # Returns
130 ///
131 /// Returns the available input-unit count.
132 #[inline(always)]
133 #[must_use]
134 pub const fn available(self) -> usize {
135 self.available
136 }
137
138 /// Returns input units consumed since this `transcode` call started.
139 ///
140 /// # Returns
141 ///
142 /// Returns `input_index - input_start`.
143 #[inline(always)]
144 #[must_use]
145 pub const fn input_used(self) -> usize {
146 self.input_index - self.input_start
147 }
148
149 /// Returns output values written since this `transcode` call started.
150 ///
151 /// # Returns
152 ///
153 /// Returns `output_index - output_start`.
154 #[inline(always)]
155 #[must_use]
156 pub const fn output_written(self) -> usize {
157 self.output_index - self.output_start
158 }
159}