1use crate::http3::codepoints::Http3FrameType;
4use crate::http3::ids::Http3PushId;
5use crate::quic::varint::{QuicVarInt, QuicVarIntLen};
6
7use super::envelope::Http3Frame;
8use super::payload::{
9 Http3FramePayloadBuildError, Http3FramePayloadField, Http3FramePayloadParseError, add_payload,
10 encode_varint, envelope, parse_exact_varint, parse_payload_varint, validate_type,
11};
12
13#[derive(Clone, Copy, Debug, Eq, PartialEq)]
15pub struct Http3CancelPush<'a> {
16 frame: Http3Frame<'a>,
17 push_id: QuicVarInt<'a>,
18}
19
20impl<'a> Http3CancelPush<'a> {
21 pub(in crate::http3) fn from_validated(
23 frame: Http3Frame<'a>,
24 push_id: Http3PushId,
25 push_id_length: QuicVarIntLen,
26 ) -> Self {
27 let push_id = QuicVarInt::from_validated(
28 &frame.payload()[..push_id_length.byte_len()],
29 push_id.value(),
30 push_id_length,
31 );
32 Self { frame, push_id }
33 }
34
35 pub fn parse(
37 bytes: &'a [u8],
38 maximum_payload: usize,
39 ) -> Result<Self, Http3FramePayloadParseError> {
40 Self::from_frame(
41 Http3Frame::parse(bytes, maximum_payload)
42 .map_err(Http3FramePayloadParseError::Frame)?,
43 )
44 }
45
46 pub fn from_frame(frame: Http3Frame<'a>) -> Result<Self, Http3FramePayloadParseError> {
48 validate_type(frame, Http3FrameType::CANCEL_PUSH)?;
49 let push_id = parse_exact_varint(frame.payload(), Http3FramePayloadField::PushId)?;
50 Ok(Self { frame, push_id })
51 }
52
53 pub const fn frame(&self) -> Http3Frame<'a> {
55 self.frame
56 }
57
58 pub const fn as_bytes(&self) -> &'a [u8] {
60 self.frame.as_bytes()
61 }
62
63 pub const fn push_id(&self) -> Http3PushId {
65 Http3PushId::new(self.push_id.value())
66 }
67
68 pub const fn push_id_varint(&self) -> QuicVarInt<'a> {
70 self.push_id
71 }
72}
73
74#[derive(Clone, Copy, Debug, Eq, PartialEq)]
76pub struct Http3PushPromise<'a> {
77 frame: Http3Frame<'a>,
78 push_id: QuicVarInt<'a>,
79}
80
81impl<'a> Http3PushPromise<'a> {
82 pub(in crate::http3) fn from_validated(
84 frame: Http3Frame<'a>,
85 push_id: Http3PushId,
86 push_id_length: QuicVarIntLen,
87 ) -> Self {
88 let push_id = QuicVarInt::from_validated(
89 &frame.payload()[..push_id_length.byte_len()],
90 push_id.value(),
91 push_id_length,
92 );
93 Self { frame, push_id }
94 }
95
96 pub fn parse(
98 bytes: &'a [u8],
99 maximum_payload: usize,
100 ) -> Result<Self, Http3FramePayloadParseError> {
101 Self::from_frame(
102 Http3Frame::parse(bytes, maximum_payload)
103 .map_err(Http3FramePayloadParseError::Frame)?,
104 )
105 }
106
107 pub fn from_frame(frame: Http3Frame<'a>) -> Result<Self, Http3FramePayloadParseError> {
109 validate_type(frame, Http3FrameType::PUSH_PROMISE)?;
110 let push_id = parse_payload_varint(frame.payload(), Http3FramePayloadField::PushId, 0)?;
111 Ok(Self { frame, push_id })
112 }
113
114 pub const fn frame(&self) -> Http3Frame<'a> {
116 self.frame
117 }
118
119 pub const fn as_bytes(&self) -> &'a [u8] {
121 self.frame.as_bytes()
122 }
123
124 pub const fn push_id(&self) -> Http3PushId {
126 Http3PushId::new(self.push_id.value())
127 }
128
129 pub const fn push_id_varint(&self) -> QuicVarInt<'a> {
131 self.push_id
132 }
133
134 pub fn encoded_field_section(&self) -> &'a [u8] {
136 &self.frame.payload()[self.push_id.byte_len()..]
137 }
138}
139
140#[derive(Clone, Copy, Debug, Eq, PartialEq)]
142pub struct Http3MaxPushId<'a> {
143 frame: Http3Frame<'a>,
144 push_id: QuicVarInt<'a>,
145}
146
147impl<'a> Http3MaxPushId<'a> {
148 pub(in crate::http3) fn from_validated(
150 frame: Http3Frame<'a>,
151 push_id: Http3PushId,
152 push_id_length: QuicVarIntLen,
153 ) -> Self {
154 let push_id = QuicVarInt::from_validated(
155 &frame.payload()[..push_id_length.byte_len()],
156 push_id.value(),
157 push_id_length,
158 );
159 Self { frame, push_id }
160 }
161
162 pub fn parse(
164 bytes: &'a [u8],
165 maximum_payload: usize,
166 ) -> Result<Self, Http3FramePayloadParseError> {
167 Self::from_frame(
168 Http3Frame::parse(bytes, maximum_payload)
169 .map_err(Http3FramePayloadParseError::Frame)?,
170 )
171 }
172
173 pub fn from_frame(frame: Http3Frame<'a>) -> Result<Self, Http3FramePayloadParseError> {
175 validate_type(frame, Http3FrameType::MAX_PUSH_ID)?;
176 let push_id = parse_exact_varint(frame.payload(), Http3FramePayloadField::PushId)?;
177 Ok(Self { frame, push_id })
178 }
179
180 pub const fn frame(&self) -> Http3Frame<'a> {
182 self.frame
183 }
184
185 pub const fn as_bytes(&self) -> &'a [u8] {
187 self.frame.as_bytes()
188 }
189
190 pub const fn push_id(&self) -> Http3PushId {
192 Http3PushId::new(self.push_id.value())
193 }
194
195 pub const fn push_id_varint(&self) -> QuicVarInt<'a> {
197 self.push_id
198 }
199}
200
201pub struct Http3CancelPushBuilder<'output> {
203 destination: &'output mut [u8],
204 push_id: Http3PushId,
205}
206
207impl<'output> Http3CancelPushBuilder<'output> {
208 pub fn new(destination: &'output mut [u8], push_id: Http3PushId) -> Self {
210 Self {
211 destination,
212 push_id,
213 }
214 }
215
216 pub fn build(self) -> Result<Http3CancelPush<'output>, Http3FramePayloadBuildError> {
218 let push_id = encode_varint(self.push_id.value()).map_err(|error| {
219 Http3FramePayloadBuildError::PayloadVarInt {
220 field: Http3FramePayloadField::PushId,
221 error,
222 }
223 })?;
224 let plan = envelope(
225 Http3FrameType::CANCEL_PUSH,
226 push_id.byte_len(),
227 self.destination,
228 )?;
229 let header_length = plan.header_length();
230 let required = plan.required();
231 let bytes = &mut self.destination[..required];
232 plan.write_header(bytes);
233 bytes[header_length..].copy_from_slice(push_id.bytes());
234 let frame = plan.finish(bytes);
235 Ok(Http3CancelPush::from_validated(
236 frame,
237 self.push_id,
238 push_id.len,
239 ))
240 }
241}
242
243pub struct Http3PushPromiseBuilder<'output, 'section> {
245 destination: &'output mut [u8],
246 push_id: Http3PushId,
247 encoded_field_section: &'section [u8],
248}
249
250impl<'output, 'section> Http3PushPromiseBuilder<'output, 'section> {
251 pub fn new(
253 destination: &'output mut [u8],
254 push_id: Http3PushId,
255 encoded_field_section: &'section [u8],
256 ) -> Self {
257 Self {
258 destination,
259 push_id,
260 encoded_field_section,
261 }
262 }
263
264 pub fn build(self) -> Result<Http3PushPromise<'output>, Http3FramePayloadBuildError> {
266 let push_id = encode_varint(self.push_id.value()).map_err(|error| {
267 Http3FramePayloadBuildError::PayloadVarInt {
268 field: Http3FramePayloadField::PushId,
269 error,
270 }
271 })?;
272 let payload_length = add_payload(push_id.byte_len(), self.encoded_field_section.len())
273 .ok_or(Http3FramePayloadBuildError::PayloadLengthOverflow {
274 current: push_id.byte_len(),
275 addition: self.encoded_field_section.len(),
276 })?;
277 let plan = envelope(
278 Http3FrameType::PUSH_PROMISE,
279 payload_length,
280 self.destination,
281 )?;
282 let header_length = plan.header_length();
283 let required = plan.required();
284 let bytes = &mut self.destination[..required];
285 plan.write_header(bytes);
286 let payload = &mut bytes[header_length..];
287 let push_id_length = push_id.byte_len();
288 payload[..push_id_length].copy_from_slice(push_id.bytes());
289 payload[push_id_length..].copy_from_slice(self.encoded_field_section);
290 let frame = plan.finish(bytes);
291 Ok(Http3PushPromise::from_validated(
292 frame,
293 self.push_id,
294 push_id.len,
295 ))
296 }
297}
298
299pub struct Http3MaxPushIdBuilder<'output> {
301 destination: &'output mut [u8],
302 push_id: Http3PushId,
303}
304
305impl<'output> Http3MaxPushIdBuilder<'output> {
306 pub fn new(destination: &'output mut [u8], push_id: Http3PushId) -> Self {
308 Self {
309 destination,
310 push_id,
311 }
312 }
313
314 pub fn build(self) -> Result<Http3MaxPushId<'output>, Http3FramePayloadBuildError> {
316 let push_id = encode_varint(self.push_id.value()).map_err(|error| {
317 Http3FramePayloadBuildError::PayloadVarInt {
318 field: Http3FramePayloadField::PushId,
319 error,
320 }
321 })?;
322 let plan = envelope(
323 Http3FrameType::MAX_PUSH_ID,
324 push_id.byte_len(),
325 self.destination,
326 )?;
327 let header_length = plan.header_length();
328 let required = plan.required();
329 let bytes = &mut self.destination[..required];
330 plan.write_header(bytes);
331 bytes[header_length..].copy_from_slice(push_id.bytes());
332 let frame = plan.finish(bytes);
333 Ok(Http3MaxPushId::from_validated(
334 frame,
335 self.push_id,
336 push_id.len,
337 ))
338 }
339}