Skip to main content

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}