1use crate::buf::ReverseBuf;
2use crate::encoding::value_traits::{
3 Collection, DistinguishedCollection, EmptyState, ForOverwrite,
4};
5use crate::encoding::{
6 check_wire_type, decoding_modes, encoding_uses_base_empty_state, peek_repeated_field,
7 BorrowDecoder, Capped, DecodeContext, Decoder, DistinguishedBorrowDecoder,
8 DistinguishedDecoder, DistinguishedValueBorrowDecoder, DistinguishedValueDecoder, Encoder,
9 FieldEncoder, GeneralPacked, Packed, RestrictedDecodeContext, TagMeasurer, TagRevWriter,
10 TagWriter, ValueBorrowDecoder, ValueDecoder, ValueEncoder, WireType, Wiretyped,
11};
12use crate::DecodeErrorKind::InvalidValue;
13use crate::{Canonicity, DecodeError};
14use bytes::BufMut;
15
16pub struct Unpacked<E = GeneralPacked>(E);
17
18encoding_uses_base_empty_state!(Unpacked<E>, with generics (E));
19
20macro_rules! define_decoders {
21 (
22 mode: $mode:ident,
23 relaxed: $relaxed:ident::$relaxed_method:ident,
24 relaxed_value: $relaxed_value:ident::$relaxed_value_method:ident,
25 relaxed_field: $relaxed_field:ident::$relaxed_field_method:ident,
26 distinguished: $distinguished:ident::$distinguished_method:ident,
27 distinguished_value: $distinguished_value:ident::$distinguished_value_method:ident,
28 distinguished_field: $distinguished_field:ident::$distinguished_field_method:ident,
29 buf_ty: $buf_ty:ty,
30 impl_buf_ty: $impl_buf_ty:ty,
31 $(buf_generic: ($($buf_generic:tt)*),)?
32 $(lifetime: $lifetime:lifetime,)?
33 ) => {
34 #[inline]
37 pub(crate) fn decode<$($lifetime,)? T, E>(
38 wire_type: WireType,
39 collection: &mut T,
40 mut buf: Capped<$impl_buf_ty>,
41 ctx: DecodeContext,
42 ) -> Result<(), DecodeError>
43 where
44 T: Collection,
45 (): EmptyState<(), T>
46 + ForOverwrite<E, T::Item>
47 + $relaxed_value <$($lifetime,)? E, T::Item>,
48 {
49 check_wire_type(<() as Wiretyped<E, T::Item>>::WIRE_TYPE, wire_type)?;
50 loop {
51 let mut new_item = <() as ForOverwrite<E, T::Item>>::for_overwrite();
53 <() as $relaxed_value<E, _>>::$relaxed_value_method(&mut new_item, buf.lend(), ctx.clone())?;
54 collection.insert(new_item)?;
55
56 if let Some(next_wire_type) = peek_repeated_field(&mut buf) {
57 check_wire_type(<() as Wiretyped<E, T::Item>>::WIRE_TYPE, next_wire_type)?;
58 } else {
59 break;
60 }
61 }
62 Ok(())
63 }
64
65 #[inline]
68 pub(super) fn decode_array_either_repr<$($lifetime,)? T, const N: usize, E>(
69 wire_type: WireType,
70 arr: &mut [T; N],
71 buf: Capped<$impl_buf_ty>,
72 ctx: DecodeContext,
73 ) -> Result<(), DecodeError>
74 where
75 (): $relaxed_value <$($lifetime,)? E, T>,
76 {
77 if wire_type == WireType::LengthDelimited
78 && <() as Wiretyped<E, T>>::WIRE_TYPE != WireType::LengthDelimited
79 {
80 <() as $relaxed_value<Packed<E>, _>>::$relaxed_value_method(arr, buf, ctx)
83 } else {
84 decode_array_unpacked_only(wire_type, arr, buf, ctx)
86 }
87 }
88
89 #[inline]
92 pub(crate) fn decode_array_unpacked_only<$($lifetime,)? T, const N: usize, E>(
93 wire_type: WireType,
94 arr: &mut [T; N],
95 mut buf: Capped<$impl_buf_ty>,
96 ctx: DecodeContext,
97 ) -> Result<(), DecodeError>
98 where
99 (): $relaxed_value <$($lifetime,)? E, T>,
100 {
101 check_wire_type(<() as Wiretyped<E, T>>::WIRE_TYPE, wire_type)?;
102 for (i, dest) in arr.iter_mut().enumerate() {
103 if i > 0 {
106 if let Some(next_wire_type) = peek_repeated_field(&mut buf) {
107 check_wire_type(<() as Wiretyped<E, T>>::WIRE_TYPE, next_wire_type)?;
108 } else {
109 return Err(DecodeError::new(InvalidValue));
111 }
112 }
113 <() as $relaxed_value<E, _>>::$relaxed_value_method(dest, buf.lend(), ctx.clone())?;
115 }
116 if peek_repeated_field(&mut buf).is_some() {
117 Err(DecodeError::new(InvalidValue))
119 } else {
120 Ok(())
121 }
122 }
123
124 #[inline]
127 pub(crate) fn decode_distinguished<$($lifetime,)? T, E>(
128 wire_type: WireType,
129 collection: &mut T,
130 mut buf: Capped<$impl_buf_ty>,
131 ctx: RestrictedDecodeContext,
132 ) -> Result<Canonicity, DecodeError>
133 where
134 T: DistinguishedCollection,
135 T::Item: Eq,
136 (): EmptyState<(), T>
137 + ForOverwrite<E, T::Item>
138 + $distinguished_value <$($lifetime,)? E, T::Item>,
139 {
140 check_wire_type(<() as Wiretyped<E, T::Item>>::WIRE_TYPE, wire_type)?;
141 let mut canon = Canonicity::Canonical;
142 loop {
143 let mut new_item = <() as ForOverwrite<E, T::Item>>::for_overwrite();
145 canon.update(
147 <() as $distinguished_value<E, _>>::$distinguished_value_method::<true>(
148 &mut new_item,
149 buf.lend(),
150 ctx.clone(),
151 )?,
152 );
153 canon.update(ctx.check(collection.insert_distinguished(new_item)?)?);
154
155 if let Some(next_wire_type) = peek_repeated_field(&mut buf) {
156 check_wire_type(<() as Wiretyped<E, T::Item>>::WIRE_TYPE, next_wire_type)?;
157 } else {
158 break;
159 }
160 }
161 Ok(canon)
162 }
163
164 #[inline]
167 pub(super) fn decode_distinguished_array_either_repr<$($lifetime,)? T, const N: usize, E>(
168 wire_type: WireType,
169 arr: &mut [T; N],
170 buf: Capped<$impl_buf_ty>,
171 ctx: RestrictedDecodeContext,
172 ) -> Result<Canonicity, DecodeError>
173 where
174 T: Eq,
175 (): $relaxed_value <$($lifetime,)? E, T>
176 + $distinguished_value <$($lifetime,)? E, T>,
177 {
178 if wire_type == WireType::LengthDelimited
179 && <() as Wiretyped<E, T>>::WIRE_TYPE != WireType::LengthDelimited
180 {
181 _ = ctx.check(Canonicity::NotCanonical)?;
185 <() as $relaxed_value<Packed<E>, _>>::$relaxed_value_method(
186 arr, buf, ctx.into_inner(),
187 )?;
188 Ok(Canonicity::NotCanonical)
189 } else {
190 decode_distinguished_array_unpacked_only(wire_type, arr, buf, ctx)
192 }
193 }
194
195 #[inline]
198 fn decode_distinguished_array_unpacked_only<$($lifetime,)? T, const N: usize, E>(
199 wire_type: WireType,
200 arr: &mut [T; N],
201 mut buf: Capped<$impl_buf_ty>,
202 ctx: RestrictedDecodeContext,
203 ) -> Result<Canonicity, DecodeError>
204 where
205 T: Eq,
206 (): $distinguished_value <$($lifetime,)? E, T>,
207 {
208 check_wire_type(<() as Wiretyped<E, T>>::WIRE_TYPE, wire_type)?;
209 let mut canon = Canonicity::Canonical;
210 for (i, dest) in arr.iter_mut().enumerate() {
211 if i > 0 {
214 if let Some(next_wire_type) = peek_repeated_field(&mut buf) {
215 check_wire_type(<() as Wiretyped<E, T>>::WIRE_TYPE, next_wire_type)?;
216 } else {
217 return Err(DecodeError::new(InvalidValue));
219 }
220 }
221 canon.update(
223 <() as $distinguished_value<E, _>>::$distinguished_value_method::<true>(
224 dest,
225 buf.lend(),
226 ctx.clone(),
227 )?,
228 );
229 }
230 if peek_repeated_field(&mut buf).is_some() {
231 Err(DecodeError::new(InvalidValue))
233 } else {
234 Ok(canon)
235 }
236 }
237 };
238}
239
240pub(crate) mod owned {
241 use super::*;
242 decoding_modes::__invoke!(define_decoders, owned);
243}
244
245pub(crate) mod borrowed {
246 use super::*;
247 decoding_modes::__invoke!(define_decoders, borrowed);
248}
249
250impl<C, T, E> Encoder<Unpacked<E>, C> for ()
253where
254 C: Collection<Item = T>,
255 (): EmptyState<(), C> + ForOverwrite<E, T> + ValueEncoder<E, T>,
256{
257 #[inline]
258 fn encode<B: BufMut + ?Sized>(tag: u32, value: &C, buf: &mut B, tw: &mut TagWriter) {
259 for val in value.iter() {
260 <() as FieldEncoder<E, T>>::encode_field(tag, val, buf, tw);
261 }
262 }
263
264 #[inline]
265 fn prepend_encode<B: ReverseBuf + ?Sized>(
266 tag: u32,
267 value: &C,
268 buf: &mut B,
269 tw: &mut TagRevWriter,
270 ) {
271 for val in value.reversed() {
272 <() as FieldEncoder<E, T>>::prepend_field(tag, val, buf, tw);
273 }
274 }
275
276 #[inline]
277 fn encoded_len(tag: u32, value: &C, tm: &mut impl TagMeasurer) -> usize {
278 if value.len() > 0 {
279 tm.key_len(tag)
281 + <() as ValueEncoder<E, _>>::many_values_encoded_len(value.iter())
282 + value.len()
283 - 1
284 } else {
285 0
286 }
287 }
288}
289
290impl<T, const N: usize, E> Encoder<Unpacked<E>, [T; N]> for ()
293where
294 (): ValueEncoder<E, T> + EmptyState<E, [T; N]>,
295{
296 #[inline]
297 fn encode<B: BufMut + ?Sized>(tag: u32, value: &[T; N], buf: &mut B, tw: &mut TagWriter) {
298 if !<() as EmptyState<E, _>>::is_empty(value) {
299 <() as Encoder<Unpacked<E>, [T]>>::encode(tag, value, buf, tw);
300 }
301 }
302
303 #[inline]
304 fn prepend_encode<B: ReverseBuf + ?Sized>(
305 tag: u32,
306 value: &[T; N],
307 buf: &mut B,
308 tw: &mut TagRevWriter,
309 ) {
310 if !<() as EmptyState<E, _>>::is_empty(value) {
311 <() as Encoder<Unpacked<E>, [T]>>::prepend_encode(tag, value, buf, tw);
312 }
313 }
314
315 #[inline]
316 fn encoded_len(tag: u32, value: &[T; N], tm: &mut impl TagMeasurer) -> usize {
317 if !<() as EmptyState<E, _>>::is_empty(value) {
318 <() as Encoder<Unpacked<E>, [T]>>::encoded_len(tag, value, tm)
319 } else {
320 0
321 }
322 }
323}
324
325impl<T, E> Encoder<Unpacked<E>, [T]> for ()
329where
330 (): ValueEncoder<E, T>,
331{
332 #[inline]
333 fn encode<B: BufMut + ?Sized>(tag: u32, value: &[T], buf: &mut B, tw: &mut TagWriter) {
334 for val in value.iter() {
335 <() as FieldEncoder<E, T>>::encode_field(tag, val, buf, tw);
336 }
337 }
338
339 #[inline]
340 fn prepend_encode<B: ReverseBuf + ?Sized>(
341 tag: u32,
342 value: &[T],
343 buf: &mut B,
344 tw: &mut TagRevWriter,
345 ) {
346 for val in value.iter().rev() {
347 <() as FieldEncoder<E, T>>::prepend_field(tag, val, buf, tw);
348 }
349 }
350
351 #[inline]
352 fn encoded_len(tag: u32, value: &[T], tm: &mut impl TagMeasurer) -> usize {
353 if !value.is_empty() {
354 tm.key_len(tag)
356 + <() as ValueEncoder<E, T>>::many_values_encoded_len(value.iter())
357 + value.len()
358 - 1
359 } else {
360 0
361 }
362 }
363}
364
365impl<T, const N: usize, E> Encoder<Unpacked<E>, Option<[T; N]>> for ()
367where
368 (): ValueEncoder<E, T> + ForOverwrite<E, [T; N]>,
369{
370 #[inline]
371 fn encode<B: BufMut + ?Sized>(
372 tag: u32,
373 value: &Option<[T; N]>,
374 buf: &mut B,
375 tw: &mut TagWriter,
376 ) {
377 if let Some(values) = value.as_ref() {
378 for val in values {
379 <() as FieldEncoder<E, T>>::encode_field(tag, val, buf, tw);
380 }
381 }
382 }
383
384 #[inline]
385 fn prepend_encode<B: ReverseBuf + ?Sized>(
386 tag: u32,
387 value: &Option<[T; N]>,
388 buf: &mut B,
389 tw: &mut TagRevWriter,
390 ) {
391 if let Some(values) = value.as_ref() {
392 for val in values.iter().rev() {
393 <() as FieldEncoder<E, T>>::prepend_field(tag, val, buf, tw);
394 }
395 }
396 }
397
398 #[inline]
399 fn encoded_len(tag: u32, value: &Option<[T; N]>, tm: &mut impl TagMeasurer) -> usize {
400 if let Some(values) = value.as_ref() {
401 tm.key_len(tag) + <() as ValueEncoder<E, T>>::many_values_encoded_len(values.iter()) + N
403 - 1
404 } else {
405 0
406 }
407 }
408}
409
410macro_rules! impl_decoders {
411 (
412 mode: $mode:ident,
413 relaxed: $relaxed:ident::$relaxed_method:ident,
414 relaxed_value: $relaxed_value:ident::$relaxed_value_method:ident,
415 relaxed_field: $relaxed_field:ident::$relaxed_field_method:ident,
416 distinguished: $distinguished:ident::$distinguished_method:ident,
417 distinguished_value: $distinguished_value:ident::$distinguished_value_method:ident,
418 distinguished_field: $distinguished_field:ident::$distinguished_field_method:ident,
419 buf_ty: $buf_ty:ty,
420 impl_buf_ty: $impl_buf_ty:ty,
421 $(buf_generic: ($($buf_generic:tt)*),)?
422 $(lifetime: $lifetime:lifetime,)?
423 ) => {
424 impl<$($lifetime,)? C, T, E> $relaxed <$($lifetime,)? Unpacked<E>, C> for ()
425 where
426 C: Collection<Item = T>,
427 (): EmptyState<(), C> + ForOverwrite<E, T> + $relaxed_value <$($lifetime,)? E, T>,
428 {
429 #[inline]
430 fn $relaxed_method $($($buf_generic)*)? (
431 wire_type: WireType,
432 value: &mut C,
433 buf: Capped<$buf_ty>,
434 ctx: DecodeContext,
435 ) -> Result<(), DecodeError> {
436 if wire_type == WireType::LengthDelimited
437 && <() as Wiretyped<E, C::Item>>::WIRE_TYPE != WireType::LengthDelimited
438 {
439 <() as $relaxed_value<Packed<E>, _>>::$relaxed_value_method(value, buf, ctx)
442 } else {
443 $mode::decode::<C, E>(wire_type, value, buf, ctx)
445 }
446 }
447 }
448
449 impl<$($lifetime,)? C, T, E> $distinguished <$($lifetime,)? Unpacked<E>, C> for ()
451 where
452 C: DistinguishedCollection<Item = T>,
453 T: Eq,
454 (): EmptyState<(), C>
455 + ForOverwrite<E, T>
456 + $distinguished_value <$($lifetime,)? E, T>
457 + $relaxed_value <$($lifetime,)? Packed<E>, C>
458 + $relaxed <$($lifetime,)? Unpacked<E>, C>,
459 {
460 #[inline]
461 fn $distinguished_method $($($buf_generic)*)? (
462 wire_type: WireType,
463 value: &mut C,
464 buf: Capped<$buf_ty>,
465 ctx: RestrictedDecodeContext,
466 ) -> Result<Canonicity, DecodeError> {
467 if wire_type == WireType::LengthDelimited
468 && <() as Wiretyped<E, T>>::WIRE_TYPE != WireType::LengthDelimited
469 {
470 _ = ctx.check(Canonicity::NotCanonical)?;
474 <() as $relaxed_value<Packed<E>, _>>::$relaxed_value_method(
475 value,
476 buf,
477 ctx.into_inner(),
478 )?;
479 Ok(Canonicity::NotCanonical)
480 } else {
481 $mode::decode_distinguished::<C, E>(wire_type, value, buf, ctx)
483 }
484 }
485 }
486
487 impl<$($lifetime,)? T, const N: usize, E>
488 $relaxed <$($lifetime,)? Unpacked<E>, [T; N]> for ()
489 where
490 (): $relaxed_value <$($lifetime,)? E, T> + EmptyState<E, [T; N]>,
491 {
492 #[inline]
493 fn $relaxed_method $($($buf_generic)*)? (
494 wire_type: WireType,
495 value: &mut [T; N],
496 buf: Capped<$buf_ty>,
497 ctx: DecodeContext,
498 ) -> Result<(), DecodeError> {
499 $mode::decode_array_either_repr(wire_type, value, buf, ctx)
500 }
501 }
502
503 impl<$($lifetime,)? T, const N: usize, E>
505 $distinguished <$($lifetime,)? Unpacked<E>, [T; N]> for ()
506 where
507 T: Eq,
508 (): EmptyState<E, [T; N]>
509 + $distinguished_value <$($lifetime,)? E, T>
510 + $relaxed_value <$($lifetime,)? E, T>,
511 {
512 #[inline]
513 fn $distinguished_method $($($buf_generic)*)? (
514 wire_type: WireType,
515 value: &mut [T; N],
516 buf: Capped<$buf_ty>,
517 ctx: RestrictedDecodeContext,
518 ) -> Result<Canonicity, DecodeError> {
519 let canon = $mode::decode_distinguished_array_either_repr(
520 wire_type,
521 value,
522 buf,
523 ctx.clone(),
524 )?;
525 if <() as EmptyState::<E, _>>::is_empty(value) {
526 ctx.check(Canonicity::NotCanonical)
527 } else {
528 Ok(canon)
529 }
530 }
531 }
532
533 impl<$($lifetime,)? T, const N: usize, E>
534 $relaxed <$($lifetime,)? Unpacked<E>, Option<[T; N]>> for ()
535 where
536 (): $relaxed_value <$($lifetime,)? E, T> + ForOverwrite<E, [T; N]>,
537 {
538 #[inline]
539 fn $relaxed_method $($($buf_generic)*)? (
540 wire_type: WireType,
541 value: &mut Option<[T; N]>,
542 buf: Capped<$buf_ty>,
543 ctx: DecodeContext,
544 ) -> Result<(), DecodeError> {
545 $mode::decode_array_either_repr(
546 wire_type,
547 value.get_or_insert_with(<() as ForOverwrite::<E, _>>::for_overwrite),
548 buf,
549 ctx,
550 )
551 }
552 }
553
554 impl<$($lifetime,)? T, const N: usize, E>
557 $distinguished <$($lifetime,)? Unpacked<E>, Option<[T; N]>> for ()
558 where
559 T: Eq,
560 (): ForOverwrite<E, [T; N]>
561 + $distinguished_value<$($lifetime,)? E, T>
562 + $relaxed_value<$($lifetime,)? E, T>,
563 {
564 #[inline]
565 fn $distinguished_method $($($buf_generic)*)? (
566 wire_type: WireType,
567 value: &mut Option<[T; N]>,
568 buf: Capped<$buf_ty>,
569 ctx: RestrictedDecodeContext,
570 ) -> Result<Canonicity, DecodeError> {
571 $mode::decode_distinguished_array_either_repr(
572 wire_type,
573 value.get_or_insert_with(<() as ForOverwrite::<E, _>>::for_overwrite),
574 buf,
575 ctx,
576 )
577 }
578 }
579 };
580}
581
582decoding_modes::__invoke!(impl_decoders, owned);
583decoding_modes::__invoke!(impl_decoders, borrowed);
584
585#[cfg(test)]
586mod test {
587 use alloc::string::String;
588 use alloc::vec::Vec;
589
590 use proptest::proptest;
591
592 use crate::encoding::test::{distinguished, relaxed};
593 use crate::encoding::{Fixed, Unpacked, WireType};
594
595 proptest! {
596 #[test]
597 fn varint(value: Vec<u64>, tag: u32) {
598 relaxed::check_type_unpacked::<Vec<u64>, Unpacked>(
599 value.clone(),
600 tag,
601 WireType::Varint,
602 )?;
603 distinguished::check_type_unpacked::<Vec<u64>, Unpacked>(value, tag, WireType::Varint)?;
604 }
605
606 #[test]
607 fn length_delimited(value: Vec<String>, tag: u32) {
608 relaxed::check_type_unpacked::<Vec<String>, Unpacked>(
609 value.clone(),
610 tag,
611 WireType::LengthDelimited,
612 )?;
613 distinguished::check_type_unpacked::<Vec<String>, Unpacked>(
614 value,
615 tag,
616 WireType::LengthDelimited,
617 )?;
618 }
619
620 #[test]
621 fn fixed32(value: Vec<u32>, tag: u32) {
622 relaxed::check_type_unpacked::<Vec<u32>, Unpacked<Fixed>>(
623 value.clone(),
624 tag,
625 WireType::ThirtyTwoBit,
626 )?;
627 distinguished::check_type_unpacked::<Vec<u32>, Unpacked<Fixed>>(
628 value,
629 tag,
630 WireType::ThirtyTwoBit,
631 )?;
632 }
633
634 #[test]
635 fn fixed64(value: Vec<u64>, tag: u32) {
636 relaxed::check_type_unpacked::<Vec<u64>, Unpacked<Fixed>>(
637 value.clone(),
638 tag,
639 WireType::SixtyFourBit,
640 )?;
641 distinguished::check_type_unpacked::<Vec<u64>, Unpacked<Fixed>>(
642 value,
643 tag,
644 WireType::SixtyFourBit,
645 )?;
646 }
647
648 #[test]
649 fn varint_array(value: [u64; 2], tag: u32) {
650 relaxed::check_type_unpacked::<[u64; 2], Unpacked>(
651 value,
652 tag,
653 WireType::Varint,
654 )?;
655 distinguished::check_type_unpacked::<[u64; 2], Unpacked>(value, tag, WireType::Varint)?;
656 }
657
658 #[test]
659 fn length_delimited_array(value: [String; 2], tag: u32) {
660 relaxed::check_type_unpacked::<[String; 2], Unpacked>(
661 value.clone(),
662 tag,
663 WireType::LengthDelimited,
664 )?;
665 distinguished::check_type_unpacked::<[String; 2], Unpacked>(
666 value,
667 tag,
668 WireType::LengthDelimited,
669 )?;
670 }
671
672 #[test]
673 fn fixed32_array(value: [u32; 2], tag: u32) {
674 relaxed::check_type_unpacked::<[u32; 2], Unpacked<Fixed>>(
675 value,
676 tag,
677 WireType::ThirtyTwoBit,
678 )?;
679 distinguished::check_type_unpacked::<[u32; 2], Unpacked<Fixed>>(
680 value,
681 tag,
682 WireType::ThirtyTwoBit,
683 )?;
684 }
685
686 #[test]
687 fn fixed64_array(value: [u64; 2], tag: u32) {
688 relaxed::check_type_unpacked::<[u64; 2], Unpacked<Fixed>>(
689 value,
690 tag,
691 WireType::SixtyFourBit,
692 )?;
693 distinguished::check_type_unpacked::<[u64; 2], Unpacked<Fixed>>(
694 value,
695 tag,
696 WireType::SixtyFourBit,
697 )?;
698 }
699 }
700}