Skip to main content

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