net_wire/qpack/stream/
decoder.rs1use core::fmt;
4
5use crate::qpack::integer::{QpackInteger, QpackIntegerParseError};
6
7mod builder;
8
9pub use builder::{
10 QpackDecoderInstructionBuildError, QpackInsertCountIncrementBuilder,
11 QpackSectionAcknowledgmentBuilder, QpackStreamCancellationBuilder,
12};
13
14#[derive(Clone, Copy, Debug, Eq, PartialEq)]
16pub enum QpackDecoderInstruction<'a> {
17 SectionAcknowledgment(QpackSectionAcknowledgment<'a>),
19 StreamCancellation(QpackStreamCancellation<'a>),
21 InsertCountIncrement(QpackInsertCountIncrement<'a>),
23}
24
25impl<'a> QpackDecoderInstruction<'a> {
26 pub fn parse(bytes: &'a [u8]) -> Result<Self, QpackDecoderInstructionParseError> {
28 let first = *bytes
29 .first()
30 .ok_or(QpackDecoderInstructionParseError::DispatchIncomplete)?;
31 if first & 0x80 != 0 {
32 let stream_id = QpackInteger::parse(bytes, 7)
33 .map_err(QpackDecoderInstructionParseError::SectionAcknowledgment)?;
34 return Ok(Self::SectionAcknowledgment(QpackSectionAcknowledgment {
35 bytes: stream_id.as_bytes(),
36 stream_id,
37 }));
38 }
39 if first & 0xc0 == 0x40 {
40 let stream_id = QpackInteger::parse(bytes, 6)
41 .map_err(QpackDecoderInstructionParseError::StreamCancellation)?;
42 return Ok(Self::StreamCancellation(QpackStreamCancellation {
43 bytes: stream_id.as_bytes(),
44 stream_id,
45 }));
46 }
47 let increment = QpackInteger::parse(bytes, 6)
48 .map_err(QpackDecoderInstructionParseError::InsertCountIncrement)?;
49 Ok(Self::InsertCountIncrement(QpackInsertCountIncrement {
50 bytes: increment.as_bytes(),
51 increment,
52 }))
53 }
54
55 pub const fn as_bytes(self) -> &'a [u8] {
57 match self {
58 Self::SectionAcknowledgment(instruction) => instruction.as_bytes(),
59 Self::StreamCancellation(instruction) => instruction.as_bytes(),
60 Self::InsertCountIncrement(instruction) => instruction.as_bytes(),
61 }
62 }
63}
64
65#[derive(Clone, Copy, Debug, Eq, PartialEq)]
67pub struct QpackSectionAcknowledgment<'a> {
68 bytes: &'a [u8],
69 stream_id: QpackInteger<'a>,
70}
71
72impl<'a> QpackSectionAcknowledgment<'a> {
73 pub const fn as_bytes(self) -> &'a [u8] {
75 self.bytes
76 }
77
78 pub const fn stream_id(self) -> QpackInteger<'a> {
80 self.stream_id
81 }
82}
83
84#[derive(Clone, Copy, Debug, Eq, PartialEq)]
86pub struct QpackStreamCancellation<'a> {
87 bytes: &'a [u8],
88 stream_id: QpackInteger<'a>,
89}
90
91impl<'a> QpackStreamCancellation<'a> {
92 pub const fn as_bytes(self) -> &'a [u8] {
94 self.bytes
95 }
96
97 pub const fn stream_id(self) -> QpackInteger<'a> {
99 self.stream_id
100 }
101}
102
103#[derive(Clone, Copy, Debug, Eq, PartialEq)]
105pub struct QpackInsertCountIncrement<'a> {
106 bytes: &'a [u8],
107 increment: QpackInteger<'a>,
108}
109
110impl<'a> QpackInsertCountIncrement<'a> {
111 pub const fn as_bytes(self) -> &'a [u8] {
113 self.bytes
114 }
115
116 pub const fn increment(self) -> QpackInteger<'a> {
118 self.increment
119 }
120}
121
122#[derive(Clone, Copy, Debug, Eq, PartialEq)]
124pub enum QpackDecoderInstructionParseError {
125 DispatchIncomplete,
127 SectionAcknowledgment(#[doc = "The nested stream-ID failure."] QpackIntegerParseError),
129 StreamCancellation(#[doc = "The nested stream-ID failure."] QpackIntegerParseError),
131 InsertCountIncrement(#[doc = "The nested increment failure."] QpackIntegerParseError),
133}
134
135impl fmt::Display for QpackDecoderInstructionParseError {
136 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
137 match self {
138 Self::DispatchIncomplete => {
139 f.write_str("QPACK decoder instruction input is incomplete")
140 }
141 Self::SectionAcknowledgment(error) => {
142 write!(f, "QPACK Section Acknowledgment is invalid: {error}")
143 }
144 Self::StreamCancellation(error) => {
145 write!(f, "QPACK Stream Cancellation is invalid: {error}")
146 }
147 Self::InsertCountIncrement(error) => {
148 write!(f, "QPACK Insert Count Increment is invalid: {error}")
149 }
150 }
151 }
152}
153
154#[derive(Clone, Copy, Debug, Eq, PartialEq)]
156pub struct QpackDecoderInstructions<'a> {
157 bytes: &'a [u8],
158}
159
160impl<'a> QpackDecoderInstructions<'a> {
161 pub fn parse(bytes: &'a [u8]) -> Result<Self, QpackDecoderInstructionsParseError> {
163 let mut offset = 0usize;
164 while offset < bytes.len() {
165 let instruction = QpackDecoderInstruction::parse(&bytes[offset..])
166 .map_err(|error| QpackDecoderInstructionsParseError { offset, error })?;
167 offset += instruction.as_bytes().len();
168 }
169 Ok(Self { bytes })
170 }
171
172 pub const fn as_bytes(self) -> &'a [u8] {
174 self.bytes
175 }
176
177 pub const fn iter(self) -> QpackDecoderInstructionIter<'a> {
179 QpackDecoderInstructionIter {
180 remaining: self.bytes,
181 offset: 0,
182 failed: false,
183 }
184 }
185}
186
187#[derive(Clone, Copy, Debug, Eq, PartialEq)]
189pub struct QpackDecoderInstructionsParseError {
190 pub offset: usize,
192 pub error: QpackDecoderInstructionParseError,
194}
195
196impl fmt::Display for QpackDecoderInstructionsParseError {
197 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
198 write!(
199 f,
200 "QPACK decoder instruction sequence is invalid at byte {}: {}",
201 self.offset, self.error
202 )
203 }
204}
205
206#[derive(Clone, Copy, Debug)]
208pub struct QpackDecoderInstructionIter<'a> {
209 remaining: &'a [u8],
210 offset: usize,
211 failed: bool,
212}
213
214impl<'a> Iterator for QpackDecoderInstructionIter<'a> {
215 type Item = Result<QpackDecoderInstruction<'a>, QpackDecoderInstructionsParseError>;
216
217 fn next(&mut self) -> Option<Self::Item> {
218 if self.failed || self.remaining.is_empty() {
219 return None;
220 }
221 match QpackDecoderInstruction::parse(self.remaining) {
222 Ok(instruction) => {
223 let consumed = instruction.as_bytes().len();
224 self.remaining = &self.remaining[consumed..];
225 self.offset += consumed;
226 Some(Ok(instruction))
227 }
228 Err(error) => {
229 self.failed = true;
230 Some(Err(QpackDecoderInstructionsParseError {
231 offset: self.offset,
232 error,
233 }))
234 }
235 }
236 }
237}
238
239impl core::iter::FusedIterator for QpackDecoderInstructionIter<'_> {}