Skip to main content

qubit_codec/transcode/
encode_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//! Encode context for one buffered encode attempt.
9
10/// Context for one encode attempt inside a buffered encoder engine.
11///
12/// The context carries the current input value and output cursor. The hook
13/// decides whether the value can be consumed with the visible output capacity
14/// and reports that decision through [`crate::EncodeOutcome`].
15///
16/// # Type Parameters
17///
18/// - `Value`: Logical input value type.
19/// - `Unit`: Encoded output unit type.
20#[derive(Debug)]
21pub struct EncodeContext<'a, Value, Unit> {
22    input_value: &'a Value,
23    input_index: usize,
24    output: &'a mut [Unit],
25    output_index: usize,
26}
27
28impl<'a, Value, Unit> EncodeContext<'a, Value, Unit> {
29    /// Creates an encode context.
30    ///
31    /// # Parameters
32    ///
33    /// - `input_value`: Borrowed input value being encoded.
34    /// - `input_index`: Absolute input index of `input_value`.
35    /// - `output`: Complete output unit slice visible to the encoder.
36    /// - `output_index`: Start position in `output` where writing begins.
37    ///
38    /// # Returns
39    ///
40    /// Returns an encode context.
41    #[inline(always)]
42    #[must_use]
43    pub fn new(
44        input_value: &'a Value,
45        input_index: usize,
46        output: &'a mut [Unit],
47        output_index: usize,
48    ) -> Self {
49        Self {
50            input_value,
51            input_index,
52            output,
53            output_index,
54        }
55    }
56
57    /// Returns the input value being encoded.
58    ///
59    /// # Returns
60    ///
61    /// Returns a shared reference to the current input value.
62    #[inline(always)]
63    #[must_use]
64    pub fn input_value(&self) -> &Value {
65        self.input_value
66    }
67
68    /// Returns the absolute input index of the current value.
69    ///
70    /// # Returns
71    ///
72    /// Returns the absolute input index.
73    #[inline(always)]
74    #[must_use]
75    pub fn input_index(&self) -> usize {
76        self.input_index
77    }
78
79    /// Returns the complete output unit slice visible to the encoder.
80    ///
81    /// # Returns
82    ///
83    /// Returns the output slice.
84    #[inline(always)]
85    #[must_use]
86    pub fn output(&mut self) -> &mut [Unit] {
87        self.output
88    }
89
90    /// Returns the start position in the output slice where writing begins.
91    ///
92    /// # Returns
93    ///
94    /// Returns the absolute output index.
95    #[inline(always)]
96    #[must_use]
97    pub fn output_index(&self) -> usize {
98        self.output_index
99    }
100
101    /// Returns writable output units from the current output index.
102    ///
103    /// # Returns
104    ///
105    /// Returns output capacity visible to this encode attempt.
106    #[inline(always)]
107    #[must_use]
108    pub fn available_output(&self) -> usize {
109        self.output.len().saturating_sub(self.output_index)
110    }
111
112    /// Consumes the context and returns all parts.
113    ///
114    /// Use this when you need simultaneous access to the input value reference
115    /// and the mutable output slice, since Rust's borrow checker disallows
116    /// taking `&self` and `&mut self` in the same expression.
117    ///
118    /// # Returns
119    ///
120    /// Returns `(input_value, input_index, output, output_index)`.
121    #[inline(always)]
122    #[must_use]
123    pub fn into_parts(self) -> (&'a Value, usize, &'a mut [Unit], usize) {
124        (
125            self.input_value,
126            self.input_index,
127            self.output,
128            self.output_index,
129        )
130    }
131}