1use crate::buf::ReverseBuf;
2use crate::encoding::value_traits::{
3 Collection, DistinguishedCollection, EmptyState, ForOverwrite,
4};
5use crate::encoding::{
6 decoding_modes, encode_varint, encoded_len_varint, encoding_uses_base_empty_state,
7 prepend_varint, unpacked, BorrowDecoder, Canonicity, Capped, DecodeContext, DecodeError,
8 Decoder, DistinguishedBorrowDecoder, DistinguishedDecoder, DistinguishedValueBorrowDecoder,
9 DistinguishedValueDecoder, Encoder, FieldEncoder, GeneralPacked, RestrictedDecodeContext,
10 TagMeasurer, TagRevWriter, TagWriter, ValueBorrowDecoder, ValueDecoder, ValueEncoder, WireType,
11 Wiretyped,
12};
13use crate::DecodeErrorKind::{InvalidValue, Truncated};
14use bytes::{Buf, BufMut};
15
16pub struct Packed<E = GeneralPacked>(E);
17
18encoding_uses_base_empty_state!(Packed<E>, with generics (E));
19
20impl<E, T: ?Sized> Wiretyped<Packed<E>, T> for () {
22 const WIRE_TYPE: WireType = WireType::LengthDelimited;
23}
24
25impl<C, T, E> ValueEncoder<Packed<E>, C> for ()
26where
27 C: Collection<Item = T>,
28 (): EmptyState<(), C> + ForOverwrite<E, T> + ValueEncoder<E, T>,
29{
30 #[inline]
31 fn encode_value<B: BufMut + ?Sized>(value: &C, buf: &mut B) {
32 encode_varint(
33 <() as ValueEncoder<E, _>>::many_values_encoded_len(value.iter()) as u64,
34 buf,
35 );
36 for val in value.iter() {
37 <() as ValueEncoder<E, _>>::encode_value(val, buf);
38 }
39 }
40
41 #[inline]
42 fn prepend_value<B: ReverseBuf + ?Sized>(value: &C, buf: &mut B) {
43 let end = buf.remaining();
44 for val in value.reversed() {
45 <() as ValueEncoder<E, _>>::prepend_value(val, buf);
46 }
47 prepend_varint((buf.remaining() - end) as u64, buf);
48 }
49
50 #[inline]
51 fn value_encoded_len(value: &C) -> usize {
52 let inner_len = <() as ValueEncoder<E, _>>::many_values_encoded_len(value.iter());
53 encoded_len_varint(inner_len as u64)
54 .checked_add(inner_len)
55 .unwrap()
56 }
57}
58
59impl<C, T, E> Encoder<Packed<E>, C> for ()
61where
62 C: Collection<Item = T>,
63 (): EmptyState<(), C> + ForOverwrite<E, T> + ValueEncoder<E, T> + ValueEncoder<Packed<E>, C>,
64{
65 #[inline]
66 fn encode<B: BufMut + ?Sized>(tag: u32, value: &C, buf: &mut B, tw: &mut TagWriter) {
67 if !<() as EmptyState<(), _>>::is_empty(value) {
68 Self::encode_field(tag, value, buf, tw);
69 }
70 }
71
72 #[inline]
73 fn prepend_encode<B: ReverseBuf + ?Sized>(
74 tag: u32,
75 value: &C,
76 buf: &mut B,
77 tw: &mut TagRevWriter,
78 ) {
79 if !<() as EmptyState<(), _>>::is_empty(value) {
80 Self::prepend_field(tag, value, buf, tw);
81 }
82 }
83
84 #[inline]
85 fn encoded_len(tag: u32, value: &C, tm: &mut impl TagMeasurer) -> usize {
86 if !<() as EmptyState<(), _>>::is_empty(value) {
87 Self::field_encoded_len(tag, value, tm)
88 } else {
89 0
90 }
91 }
92}
93
94impl<T, const N: usize, E> ValueEncoder<Packed<E>, [T; N]> for ()
95where
96 (): ValueEncoder<E, T>,
97{
98 #[inline]
99 fn encode_value<B: BufMut + ?Sized>(value: &[T; N], buf: &mut B) {
100 <() as ValueEncoder<Packed<E>, [T]>>::encode_value(value, buf)
101 }
102
103 #[inline]
104 fn prepend_value<B: ReverseBuf + ?Sized>(value: &[T; N], buf: &mut B) {
105 <() as ValueEncoder<Packed<E>, [T]>>::prepend_value(value, buf)
106 }
107
108 #[inline]
109 fn value_encoded_len(value: &[T; N]) -> usize {
110 <() as ValueEncoder<Packed<E>, [T]>>::value_encoded_len(value)
111 }
112}
113
114impl<T, const N: usize, E> Encoder<Packed<E>, [T; N]> for ()
115where
116 (): ValueEncoder<E, T> + EmptyState<E, [T; N]>,
117{
118 #[inline]
119 fn encode<B: BufMut + ?Sized>(tag: u32, value: &[T; N], buf: &mut B, tw: &mut TagWriter) {
120 if !<() as EmptyState<E, _>>::is_empty(value) {
121 <() as FieldEncoder<Packed<E>, [T]>>::encode_field(tag, value, buf, tw);
122 }
123 }
124
125 #[inline]
126 fn prepend_encode<B: ReverseBuf + ?Sized>(
127 tag: u32,
128 value: &[T; N],
129 buf: &mut B,
130 tw: &mut TagRevWriter,
131 ) {
132 if !<() as EmptyState<E, _>>::is_empty(value) {
133 <() as FieldEncoder<Packed<E>, [T]>>::prepend_field(tag, value, buf, tw);
134 }
135 }
136
137 #[inline]
138 fn encoded_len(tag: u32, value: &[T; N], tm: &mut impl TagMeasurer) -> usize {
139 if !<() as EmptyState<E, _>>::is_empty(value) {
140 <() as FieldEncoder<Packed<E>, [T]>>::field_encoded_len(tag, value, tm)
141 } else {
142 0
143 }
144 }
145}
146
147impl<T, E> ValueEncoder<Packed<E>, [T]> for ()
151where
152 (): ValueEncoder<E, T>,
153{
154 #[inline]
155 fn encode_value<B: BufMut + ?Sized>(value: &[T], buf: &mut B) {
156 encode_varint(
157 <() as ValueEncoder<E, _>>::many_values_encoded_len(value.iter()) as u64,
158 buf,
159 );
160 for val in value.iter() {
161 <() as ValueEncoder<E, _>>::encode_value(val, buf);
162 }
163 }
164
165 #[inline]
166 fn prepend_value<B: ReverseBuf + ?Sized>(value: &[T], buf: &mut B) {
167 let end = buf.remaining();
168 for val in value.iter().rev() {
169 <() as ValueEncoder<E, _>>::prepend_value(val, buf);
170 }
171 prepend_varint((buf.remaining() - end) as u64, buf);
172 }
173
174 #[inline]
175 fn value_encoded_len(value: &[T]) -> usize {
176 let inner_len = <() as ValueEncoder<E, _>>::many_values_encoded_len(value.iter());
177 encoded_len_varint(inner_len as u64)
178 .checked_add(inner_len)
179 .unwrap()
180 }
181}
182
183impl<T, E> Encoder<Packed<E>, [T]> for ()
184where
185 (): ValueEncoder<E, T>,
186{
187 #[inline]
188 fn encode<B: BufMut + ?Sized>(tag: u32, value: &[T], buf: &mut B, tw: &mut TagWriter) {
189 if !value.is_empty() {
190 <() as FieldEncoder<Packed<E>, [T]>>::encode_field(tag, value, buf, tw);
191 }
192 }
193
194 #[inline]
195 fn prepend_encode<B: ReverseBuf + ?Sized>(
196 tag: u32,
197 value: &[T],
198 buf: &mut B,
199 tw: &mut TagRevWriter,
200 ) {
201 if !value.is_empty() {
202 <() as FieldEncoder<Packed<E>, [T]>>::prepend_field(tag, value, buf, tw);
203 }
204 }
205
206 #[inline]
207 fn encoded_len(tag: u32, value: &[T], tm: &mut impl TagMeasurer) -> usize {
208 if !value.is_empty() {
209 <() as FieldEncoder<Packed<E>, [T]>>::field_encoded_len(tag, value, tm)
210 } else {
211 0
212 }
213 }
214}
215
216macro_rules! impl_decoders {
217 (
218 mode: $mode:ident,
219 relaxed: $relaxed:ident::$relaxed_method:ident,
220 relaxed_value: $relaxed_value:ident::$relaxed_value_method:ident,
221 relaxed_field: $relaxed_field:ident::$relaxed_field_method:ident,
222 distinguished: $distinguished:ident::$distinguished_method:ident,
223 distinguished_value: $distinguished_value:ident::$distinguished_value_method:ident,
224 distinguished_field: $distinguished_field:ident::$distinguished_field_method:ident,
225 buf_ty: $buf_ty:ty,
226 impl_buf_ty: $impl_buf_ty:ty,
227 $(buf_generic: ($($buf_generic:tt)*),)?
228 $(lifetime: $lifetime:lifetime,)?
229 ) => {
230 impl<$($lifetime,)? C, T, E> $relaxed_value <$($lifetime,)? Packed<E>, C> for ()
231 where
232 C: Collection<Item = T>,
233 (): EmptyState<(), C>
234 + ForOverwrite<E, T>
235 + $relaxed_value<$($lifetime,)? E, T>,
236 {
237 #[inline]
238 fn $relaxed_value_method $($($buf_generic)*)? (
239 value: &mut C,
240 mut buf: Capped<$buf_ty>,
241 ctx: DecodeContext,
242 ) -> Result<(), DecodeError> {
243 let mut capped = buf.take_length_delimited()?;
244 if matches!(
246 <() as Wiretyped<E, T>>::WIRE_TYPE.fixed_size(),
247 Some(fixed_size) if capped.remaining_before_cap() % fixed_size != 0
248 ) {
249 return Err(DecodeError::new(Truncated));
251 }
252 while capped.has_remaining()? {
253 let mut new_val = <() as ForOverwrite<E, T>>::for_overwrite();
254 <() as $relaxed_value<E, _>>::$relaxed_value_method(
255 &mut new_val,
256 capped.lend(),
257 ctx.clone(),
258 )?;
259 value.insert(new_val)?;
260 }
261 Ok(())
262 }
263 }
264
265 impl<$($lifetime,)? C, T, E> $distinguished_value<$($lifetime,)? Packed<E>, C> for ()
266 where
267 C: DistinguishedCollection<Item = T> + Eq,
268 T: Eq,
269 (): EmptyState<(), C>
270 + ForOverwrite<E, T>
271 + $distinguished_value<$($lifetime,)? E, T>,
272 {
273 const CHECKS_EMPTY: bool = false;
274
275 #[inline]
276 fn $distinguished_value_method <const ALLOW_EMPTY: bool>(
277 value: &mut C,
278 mut buf: Capped<$impl_buf_ty>,
279 ctx: RestrictedDecodeContext,
280 ) -> Result<Canonicity, DecodeError> {
281 let mut capped = buf.take_length_delimited()?;
282 if matches!(
284 <() as Wiretyped<E, T>>::WIRE_TYPE.fixed_size(),
285 Some(fixed_size) if capped.remaining_before_cap() % fixed_size != 0
286 ) {
287 return Err(DecodeError::new(Truncated));
289 }
290 let mut canon = Canonicity::Canonical;
291 while capped.has_remaining()? {
292 let mut new_val = <() as ForOverwrite<E, T>>::for_overwrite();
293 canon.update(
294 <() as $distinguished_value<E, _>>::$distinguished_value_method::<true>(
295 &mut new_val,
296 capped.lend(),
297 ctx.clone(),
298 )?,
299 );
300 canon.update(ctx.check(value.insert_distinguished(new_val)?)?);
301 }
302 Ok(canon)
303 }
304 }
305
306 impl<$($lifetime,)? C, T, E> $relaxed <$($lifetime,)? Packed<E>, C> for ()
307 where
308 C: Collection<Item = T>,
309 (): EmptyState<(), C>
310 + ForOverwrite<E, T>
311 + $relaxed_value <$($lifetime,)? E, T>
312 + $relaxed_value <$($lifetime,)? Packed<E>, C>,
313 {
314 #[inline]
315 fn $relaxed_method $($($buf_generic)*)? (
316 wire_type: WireType,
317 value: &mut C,
318 buf: Capped<$buf_ty>,
319 ctx: DecodeContext,
320 ) -> Result<(), DecodeError> {
321 if wire_type == WireType::LengthDelimited {
322 <() as $relaxed_value<Packed<E>, C>>::$relaxed_value_method(value, buf, ctx)
325 } else {
326 unpacked::$mode::decode::<C, E>(wire_type, value, buf, ctx)
328 }
329 }
330 }
331
332 impl<$($lifetime,)? C, T, E> $distinguished <$($lifetime,)? Packed<E>, C> for ()
333 where
334 C: DistinguishedCollection<Item = T>,
335 T: Eq,
336 (): EmptyState<(), C>
337 + ForOverwrite<E, T>
338 + $relaxed_value <$($lifetime,)? E, T>
339 + $distinguished_value <$($lifetime,)? Packed<E>, C>,
340 {
341 #[inline]
342 fn $distinguished_method $($($buf_generic)*)? (
343 wire_type: WireType,
344 value: &mut C,
345 buf: Capped<$buf_ty>,
346 ctx: RestrictedDecodeContext,
347 ) -> Result<Canonicity, DecodeError> {
348 if wire_type == WireType::LengthDelimited {
349 let canon = <() as $distinguished_value<Packed<E>, _>>::
352 $distinguished_value_method::<false>
353 (
354 value,
355 buf,
356 ctx.clone(),
357 )?;
358 if !<() as $distinguished_value<Packed<E>, C>>::CHECKS_EMPTY
359 && <() as EmptyState<(), C>>::is_empty(value)
360 {
361 ctx.check(Canonicity::NotCanonical)
362 } else {
363 Ok(canon)
364 }
365 } else {
366 _ = ctx.check(Canonicity::NotCanonical)?;
368 unpacked::$mode::decode::<C, E>(
369 wire_type,
370 value,
371 buf,
372 ctx.into_inner(),
373 )?;
374 Ok(Canonicity::NotCanonical)
375 }
376 }
377 }
378
379 impl<$($lifetime,)? T, const N: usize, E>
380 $relaxed_value <$($lifetime,)? Packed<E>, [T; N]> for ()
381 where
382 (): $relaxed_value <$($lifetime,)? E, T>,
383 {
384 #[inline]
385 fn $relaxed_value_method $($($buf_generic)*)? (
386 value: &mut [T; N],
387 mut buf: Capped<$buf_ty>,
388 ctx: DecodeContext,
389 ) -> Result<(), DecodeError> {
390 let mut capped = buf.take_length_delimited()?;
391 if matches!(
393 <() as Wiretyped<E, T>>::WIRE_TYPE.fixed_size(),
394 Some(fixed_size) if capped.remaining_before_cap() != fixed_size * N
395 ) {
396 return Err(DecodeError::new(InvalidValue));
398 }
399
400 for dest in value {
401 if <() as Wiretyped<E, T>>::WIRE_TYPE.fixed_size().is_none()
403 && !capped.has_remaining()?
404 {
405 return Err(DecodeError::new(InvalidValue));
407 }
408 <() as $relaxed_value<E, _>>::$relaxed_value_method(
409 dest, capped.lend(), ctx.clone())?;
410 }
411
412 if <() as Wiretyped<E, T>>::WIRE_TYPE.fixed_size().is_none()
414 && capped.has_remaining()?
415 {
416 Err(DecodeError::new(InvalidValue))
418 } else {
419 Ok(())
420 }
421 }
422 }
423
424 impl<$($lifetime,)? T, const N: usize, E>
425 $distinguished_value <$($lifetime,)? Packed<E>, [T; N]> for ()
426 where
427 (): $distinguished_value <$($lifetime,)? E, T>,
428 {
429 const CHECKS_EMPTY: bool = false;
430
431 #[inline]
432 fn $distinguished_value_method <const ALLOW_EMPTY: bool>(
433 value: &mut [T; N],
434 mut buf: Capped<$impl_buf_ty>,
435 ctx: RestrictedDecodeContext,
436 ) -> Result<Canonicity, DecodeError> {
437 let mut capped = buf.take_length_delimited()?;
438 if matches!(
440 <() as Wiretyped<E, T>>::WIRE_TYPE.fixed_size(),
441 Some(fixed_size) if capped.remaining_before_cap() != fixed_size * N
442 ) {
443 return Err(DecodeError::new(InvalidValue));
445 }
446
447 let mut canon = Canonicity::Canonical;
448 for dest in value.iter_mut() {
449 if <() as Wiretyped<E, T>>::WIRE_TYPE.fixed_size().is_none()
451 && !capped.has_remaining()?
452 {
453 return Err(DecodeError::new(InvalidValue));
455 }
456 canon.update(
457 <() as $distinguished_value<E, _>>::$distinguished_value_method::<true>(
459 dest,
460 capped.lend(),
461 ctx.clone(),
462 )?,
463 );
464 }
465
466 if <() as Wiretyped<E, T>>::WIRE_TYPE.fixed_size().is_none()
468 && capped.has_remaining()?
469 {
470 Err(DecodeError::new(InvalidValue))
472 } else {
473 Ok(canon)
474 }
475 }
476 }
477
478 impl<$($lifetime,)? T, const N: usize, E>
479 $relaxed <$($lifetime,)? Packed<E>, [T; N]> for ()
480 where
481 (): $relaxed_value <$($lifetime,)? E, T> + EmptyState<E, [T; N]>,
482 {
483 #[inline]
484 fn $relaxed_method $($($buf_generic)*)? (
485 wire_type: WireType,
486 value: &mut [T; N],
487 buf: Capped<$buf_ty>,
488 ctx: DecodeContext,
489 ) -> Result<(), DecodeError> {
490 if wire_type == WireType::LengthDelimited {
491 <() as $relaxed_value<Packed<E>, [T; N]>>::
494 $relaxed_value_method(value, buf, ctx)
495 } else {
496 unpacked::$mode::decode_array_unpacked_only::<T, N, E>(
498 wire_type,
499 value,
500 buf,
501 ctx,
502 )
503 }
504 }
505 }
506
507 impl<$($lifetime,)? T, const N: usize, E>
508 $distinguished <$($lifetime,)? Packed<E>, [T; N]> for ()
509 where
510 T: Eq,
511 (): $distinguished_value <$($lifetime,)? E, T>
512 + $relaxed_value <$($lifetime,)? E, T>
513 + EmptyState<E, [T; N]>,
514 {
515 #[inline]
516 fn $distinguished_method $($($buf_generic)*)? (
517 wire_type: WireType,
518 value: &mut [T; N],
519 buf: Capped<$buf_ty>,
520 ctx: RestrictedDecodeContext,
521 ) -> Result<Canonicity, DecodeError> {
522 if wire_type == WireType::LengthDelimited {
523 let canon = <() as $distinguished_value<Packed<E>, _>>::
527 $distinguished_value_method::<false>
528 (
529 value,
530 buf,
531 ctx.clone(),
532 )?;
533
534 if
535 <() as EmptyState<E, [T; N]>>::is_empty(value) {
537 ctx.check(Canonicity::NotCanonical)
538 } else {
539 Ok(canon)
540 }
541 } else {
542 _ = ctx.check(Canonicity::NotCanonical)?;
544 unpacked::$mode::decode_array_unpacked_only::<T, N, E>(
545 wire_type,
546 value,
547 buf,
548 ctx.into_inner(),
549 )?;
550 Ok(Canonicity::NotCanonical)
551 }
552 }
553 }
554 };
555}
556
557decoding_modes::__invoke!(impl_decoders, owned);
558decoding_modes::__invoke!(impl_decoders, borrowed);