1use super::*;
8
9#[cfg(feature = "alloc")]
10use alloc::boxed::Box;
11#[cfg(feature = "alloc")]
12use alloc::vec::Vec;
13use primitives::RawBytes;
14
15#[cfg(not(feature = "alloc"))]
16pub type Header<O, B> = InlineHeader<O, B>;
19
20#[cfg(feature = "alloc")]
21pub type Header<O, B> = BoxedHeader<O, B>;
23
24pub type HeaderOf<T, B> = Header<T, <T as HasView<B>>::ViewType>;
27
28#[derive(Clone, Debug, Eq, Hash, PartialEq)]
33pub enum InlineHeader<O, B> {
34 Repr(O),
36 Raw(B),
38}
39
40#[cfg(feature = "alloc")]
47#[derive(Clone, Debug, Eq, Hash, PartialEq)]
48pub enum BoxedHeader<O, B> {
49 #[cfg(feature = "alloc")]
51 Repr(Box<O>),
52 Raw(B),
54}
55
56#[cfg(feature = "alloc")]
57impl<O, B> From<InlineHeader<O, B>> for BoxedHeader<O, B> {
58 fn from(value: InlineHeader<O, B>) -> Self {
59 match value {
60 InlineHeader::Repr(o) => Self::Repr(o.into()),
61 InlineHeader::Raw(b) => Self::Raw(b),
62 }
63 }
64}
65
66#[cfg(feature = "alloc")]
67impl<O, B> From<BoxedHeader<O, B>> for InlineHeader<O, B> {
68 fn from(value: BoxedHeader<O, B>) -> Self {
69 match value {
70 BoxedHeader::Repr(o) => Self::Repr(*o),
71 BoxedHeader::Raw(b) => Self::Raw(b),
72 }
73 }
74}
75
76#[cfg(feature = "alloc")]
80impl<O, B> BoxedHeader<O, B> {
81 pub fn repr(&self) -> Option<&O> {
84 match self {
85 Self::Repr(o) => Some(o),
86 _ => None,
87 }
88 }
89
90 pub fn repr_mut(&mut self) -> Option<&mut O> {
93 match self {
94 Self::Repr(o) => Some(o),
95 _ => None,
96 }
97 }
98
99 pub fn raw(&self) -> Option<&B> {
102 match self {
103 Self::Raw(b) => Some(b),
104 _ => None,
105 }
106 }
107
108 pub fn raw_mut(&mut self) -> Option<&mut B> {
111 match self {
112 Self::Raw(b) => Some(b),
113 _ => None,
114 }
115 }
116}
117
118#[cfg(feature = "alloc")]
119impl<
120 O: NextLayer + Clone,
121 B: NextLayer<Denom = O::Denom, Hint = O::Hint> + ToOwnedPacket<Target = O>,
122 > ToOwnedPacket for BoxedHeader<O, B>
123{
124 type Target = O;
125
126 fn to_owned(&self, hint: Option<Self::Hint>) -> ParseResult<Self::Target> {
127 match self {
128 Header::Repr(o) => Ok(*o.clone()),
129 Header::Raw(v) => v.to_owned(hint),
130 }
131 }
132}
133
134#[cfg(feature = "alloc")]
135impl<B: ByteSlice, T> From<&BoxedHeader<Vec<T>, RawBytes<B>>> for Vec<T>
136where
137 T: FromBytes + IntoBytes + KnownLayout + Immutable + Clone,
138{
139 fn from(value: &Header<Vec<T>, RawBytes<B>>) -> Self {
140 match value {
141 Header::Repr(v) => v.deref().clone(),
142 Header::Raw(v) => {
143 <[T]>::ref_from_bytes(v.as_ref()).unwrap().to_vec()
144 }
145 }
146 }
147}
148
149#[cfg(feature = "alloc")]
150impl<O: HasView<V, ViewType = B>, B, V> HasView<V> for BoxedHeader<O, B> {
151 type ViewType = B;
152}
153
154#[cfg(feature = "alloc")]
155impl<O, B> HasRepr for BoxedHeader<O, B> {
156 type ReprType = O;
157}
158
159#[cfg(feature = "alloc")]
160impl<O, B> HeaderLen for BoxedHeader<O, B>
161where
162 O: HeaderLen,
163 B: HeaderLen,
164{
165 const MINIMUM_LENGTH: usize = O::MINIMUM_LENGTH;
166
167 #[inline]
168 fn packet_length(&self) -> usize {
169 match self {
170 Self::Repr(o) => o.packet_length(),
171 Self::Raw(b) => b.packet_length(),
172 }
173 }
174}
175
176#[cfg(feature = "alloc")]
180impl<
181 V: SplitByteSlice,
182 B: HeaderParse<V> + HasRepr + NextLayer + Into<Self>,
183 > HeaderParse<V> for BoxedHeader<B::ReprType, B>
184where
185 B: NextLayer,
186 B::ReprType: NextLayer<Denom = B::Denom, Hint = B::Hint>,
187{
188 #[inline]
189 fn parse_choice(
190 from: V,
191 hint: Option<Self::Hint>,
192 ) -> ParseResult<Success<Self, V>> {
193 <B as HeaderParse<V>>::parse_choice(from, hint)
194 .map(|(val, hint, remainder)| (val.into(), hint, remainder))
195 }
196}
197
198#[cfg(feature = "alloc")]
199impl<O: NextLayer, B> NextLayer for BoxedHeader<O, B>
200where
201 B: NextLayer<Denom = O::Denom, Hint = O::Hint>,
202{
203 type Denom = O::Denom;
204 type Hint = O::Hint;
205
206 #[inline]
207 fn next_layer_choice(
208 &self,
209 hint: Option<Self::Hint>,
210 ) -> Option<Self::Denom> {
211 match self {
212 Self::Repr(v) => v.next_layer_choice(hint),
213 Self::Raw(v) => v.next_layer_choice(hint),
214 }
215 }
216}
217
218#[cfg(feature = "alloc")]
219unsafe impl<O: EmitDoesNotRelyOnBufContents, B: EmitDoesNotRelyOnBufContents>
220 EmitDoesNotRelyOnBufContents for BoxedHeader<O, B>
221{
222}
223
224#[cfg(feature = "alloc")]
225impl<O: Emit, B: Emit> Emit for BoxedHeader<O, B> {
226 #[inline]
227 fn emit_raw<V: ByteSliceMut>(&self, buf: V) -> usize {
228 match self {
229 Self::Repr(o) => o.emit_raw(buf),
230 Self::Raw(b) => b.emit_raw(buf),
231 }
232 }
233
234 #[inline]
235 fn needs_emit(&self) -> bool {
236 match self {
237 Self::Repr(_) => true,
238 Self::Raw(b) => b.needs_emit(),
239 }
240 }
241}
242
243impl<O, B> InlineHeader<O, B> {
247 pub fn repr(&self) -> Option<&O> {
250 match self {
251 Self::Repr(o) => Some(o),
252 _ => None,
253 }
254 }
255
256 pub fn repr_mut(&mut self) -> Option<&mut O> {
259 match self {
260 Self::Repr(o) => Some(o),
261 _ => None,
262 }
263 }
264
265 pub fn raw(&self) -> Option<&B> {
268 match self {
269 Self::Raw(b) => Some(b),
270 _ => None,
271 }
272 }
273
274 pub fn raw_mut(&mut self) -> Option<&mut B> {
277 match self {
278 Self::Raw(b) => Some(b),
279 _ => None,
280 }
281 }
282}
283
284impl<
285 O: NextLayer + Clone,
286 B: NextLayer<Denom = O::Denom, Hint = O::Hint> + ToOwnedPacket<Target = O>,
287 > ToOwnedPacket for InlineHeader<O, B>
288{
289 type Target = O;
290
291 fn to_owned(&self, hint: Option<Self::Hint>) -> ParseResult<Self::Target> {
292 match self {
293 Self::Repr(o) => Ok(o.clone()),
294 Self::Raw(v) => v.to_owned(hint),
295 }
296 }
297}
298
299impl<O: HasView<V, ViewType = B>, B, V> HasView<V> for InlineHeader<O, B> {
300 type ViewType = B;
301}
302
303impl<O, B> HasRepr for InlineHeader<O, B> {
304 type ReprType = O;
305}
306
307impl<O, B> HeaderLen for InlineHeader<O, B>
308where
309 O: HeaderLen,
310 B: HeaderLen,
311{
312 const MINIMUM_LENGTH: usize = O::MINIMUM_LENGTH;
313
314 #[inline]
315 fn packet_length(&self) -> usize {
316 match self {
317 Self::Repr(o) => o.packet_length(),
318 Self::Raw(b) => b.packet_length(),
319 }
320 }
321}
322
323impl<
327 V: SplitByteSlice,
328 B: HeaderParse<V> + HasRepr + NextLayer + Into<Self>,
329 > HeaderParse<V> for InlineHeader<B::ReprType, B>
330where
331 B: NextLayer,
332 B::ReprType: NextLayer<Denom = B::Denom, Hint = B::Hint>,
333{
334 #[inline]
335 fn parse_choice(
336 from: V,
337 hint: Option<Self::Hint>,
338 ) -> ParseResult<Success<Self, V>> {
339 <B as HeaderParse<V>>::parse_choice(from, hint)
340 .map(|(val, hint, remainder)| (val.into(), hint, remainder))
341 }
342}
343
344impl<O: NextLayer, B> NextLayer for InlineHeader<O, B>
345where
346 B: NextLayer<Denom = O::Denom, Hint = O::Hint>,
347{
348 type Denom = O::Denom;
349 type Hint = O::Hint;
350
351 #[inline]
352 fn next_layer_choice(
353 &self,
354 hint: Option<Self::Hint>,
355 ) -> Option<Self::Denom> {
356 match self {
357 Self::Repr(v) => v.next_layer_choice(hint),
358 Self::Raw(v) => v.next_layer_choice(hint),
359 }
360 }
361}
362
363unsafe impl<O: EmitDoesNotRelyOnBufContents, B: EmitDoesNotRelyOnBufContents>
364 EmitDoesNotRelyOnBufContents for InlineHeader<O, B>
365{
366}
367
368impl<O: Emit, B: Emit> Emit for InlineHeader<O, B> {
369 #[inline]
370 fn emit_raw<V: ByteSliceMut>(&self, buf: V) -> usize {
371 match self {
372 Self::Repr(o) => o.emit_raw(buf),
373 Self::Raw(b) => b.emit_raw(buf),
374 }
375 }
376
377 #[inline]
378 fn needs_emit(&self) -> bool {
379 match self {
380 Self::Repr(_) => true,
381 Self::Raw(b) => b.needs_emit(),
382 }
383 }
384}