1use super::codec::{compatible_field_pair, field_ref_mode, generic_field_type, Codec};
19use super::collection::{
20 read_collection_type_info, write_collection_type_info, DECL_ELEMENT_TYPE, HAS_NULL,
21 IS_SAME_TYPE, TRACKING_REF,
22};
23use super::skip::{skip_any_value, skip_known_value};
24use crate::context::{ReadContext, WriteContext};
25use crate::error::Error;
26use crate::meta::FieldType;
27use crate::resolver::{RefFlag, RefMode, TypeInfo, TypeResolver};
28use crate::serializer::Serializer;
29use crate::type_id::{TypeId, SIZE_OF_REF_AND_TYPE};
30use std::marker::PhantomData;
31use std::rc::Rc;
32
33impl Serializer for () {
34 type Target = Self;
35
36 #[inline(always)]
37 fn write_data(_: &Self, _: &mut WriteContext) -> Result<(), Error> {
38 Ok(())
39 }
40
41 #[inline(always)]
42 fn read_data(_: &mut ReadContext) -> Result<Self, Error> {
43 Ok(())
44 }
45
46 #[inline(always)]
47 fn default_value(_: &mut ReadContext) -> Result<Self, Error> {
48 Ok(())
49 }
50
51 #[inline(always)]
52 fn static_type_id() -> TypeId {
53 TypeId::NONE
54 }
55
56 #[inline(always)]
57 fn reserved_space() -> usize {
58 0
59 }
60
61 #[inline(always)]
62 fn read_arc_any(
63 _: &mut ReadContext,
64 ) -> Result<std::sync::Arc<dyn std::any::Any + Send + Sync>, Error> {
65 Ok(std::sync::Arc::new(()))
66 }
67}
68
69#[inline(always)]
70fn write_tuple_element<T: 'static, S: Serializer<Target = T>>(
71 value: &T,
72 context: &mut WriteContext,
73) -> Result<(), Error> {
74 if S::IS_OPTIONAL || S::IS_SHARED_REF || S::static_type_id() == TypeId::UNKNOWN {
75 S::write(
76 value,
77 context,
78 if S::IS_SHARED_REF {
79 RefMode::Tracking
80 } else {
81 RefMode::NullOnly
82 },
83 false,
84 )
85 } else {
86 S::write_data(value, context)
87 }
88}
89
90#[inline(always)]
91fn read_tuple_element<T: 'static, S: Serializer<Target = T>>(
92 context: &mut ReadContext,
93) -> Result<T, Error> {
94 if S::IS_OPTIONAL || S::IS_SHARED_REF || S::static_type_id() == TypeId::UNKNOWN {
95 S::read(
96 context,
97 if S::IS_SHARED_REF {
98 RefMode::Tracking
99 } else {
100 RefMode::NullOnly
101 },
102 false,
103 )
104 } else {
105 S::read_data(context)
106 }
107}
108
109#[inline(always)]
110fn tuple_ref_mode(header: u8) -> RefMode {
111 if (header & TRACKING_REF) != 0 {
112 RefMode::Tracking
113 } else if (header & HAS_NULL) != 0 {
114 RefMode::NullOnly
115 } else {
116 RefMode::None
117 }
118}
119
120#[inline(always)]
121fn read_tuple_value<T: 'static, C: Codec<T>>(
122 context: &mut ReadContext,
123 ref_mode: RefMode,
124 same_type: bool,
125 declared_type: Option<&FieldType>,
126 type_info: Option<&Rc<TypeInfo>>,
127 type_info_field: Option<&FieldType>,
128) -> Result<T, Error> {
129 if !same_type {
130 return C::read(context, ref_mode, true);
131 }
132 if let Some(field_type) = declared_type {
133 let local_field_type = C::field_type(context.get_type_resolver())?;
134 return C::read_compatible(context, &local_field_type, field_type)?
135 .ok_or_else(tuple_type_mismatch);
136 }
137 if let (Some(type_info), Some(type_info_field)) = (type_info, type_info_field) {
138 let local_field_type = C::field_type(context.get_type_resolver())?;
139 if !compatible_field_pair(&local_field_type, type_info_field) {
140 return Err(tuple_type_mismatch());
141 }
142 return C::read_with_type_info(context, ref_mode, type_info);
143 }
144 Err(missing_tuple_metadata())
145}
146
147#[cold]
148#[inline(never)]
149fn tuple_type_mismatch() -> Error {
150 Error::type_error("same-type tuple element is incompatible with local position")
151}
152
153#[cold]
154#[inline(never)]
155fn missing_tuple_metadata() -> Error {
156 Error::invalid_data("same-type tuple metadata is missing")
157}
158
159#[cold]
160#[inline(never)]
161fn tuple_ref_mismatch() -> Error {
162 Error::invalid_data("tuple header conflicts with declared element metadata")
163}
164
165#[cold]
166#[inline(never)]
167fn skip_tuple_values(
168 context: &mut ReadContext,
169 count: u32,
170 ref_mode: RefMode,
171 same_type: bool,
172 declared_type: Option<&FieldType>,
173 type_info: Option<&Rc<TypeInfo>>,
174) -> Result<(), Error> {
175 if !same_type {
176 for _ in 0..count {
177 skip_any_value(context, ref_mode != RefMode::None)?;
178 }
179 return Ok(());
180 }
181 if let Some(field_type) = declared_type {
182 for _ in 0..count {
183 skip_known_value(context, Some(field_type), ref_mode, None)?;
184 }
185 return Ok(());
186 }
187 let type_info = type_info.ok_or_else(missing_tuple_metadata)?;
188 for _ in 0..count {
189 skip_known_value(context, None, ref_mode, Some(type_info))?;
190 }
191 Ok(())
192}
193
194#[cold]
195#[inline(never)]
196fn skip_declared_tuple_values<T, S>(
197 context: &mut ReadContext,
198 count: u32,
199 ref_mode: RefMode,
200) -> Result<(), Error>
201where
202 T: 'static,
203 S: Serializer<Target = T>,
204{
205 for _ in 0..count {
206 let _ = S::read(context, ref_mode, false)?;
207 }
208 Ok(())
209}
210
211macro_rules! tuple_declared_type {
212 (value, $context:expr, $remote:expr, $same_type:expr, $declared:expr, $ref_mode:expr) => {
213 ()
214 };
215 (field, $context:expr, $remote:expr, $same_type:expr, $declared:expr, $ref_mode:expr) => {{
216 if $same_type && $declared {
217 let field_type = generic_field_type($remote, 0, "tuple")?;
218 if field_ref_mode(field_type) != $ref_mode {
219 return Err(tuple_ref_mismatch());
220 }
221 Some(field_type)
222 } else {
223 None
224 }
225 }};
226}
227
228macro_rules! tuple_type_info_field {
229 (value, $type_info:expr, $ref_mode:expr) => {
230 ()
231 };
232 (field, $type_info:expr, $ref_mode:expr) => {
233 $type_info.as_ref().map(|type_info| {
234 FieldType::new_with_user_type_id(
235 type_info.get_type_id() as u32,
236 type_info.get_user_type_id(),
237 $ref_mode.is_nullable(),
238 $ref_mode.tracks_refs(),
239 Vec::new(),
240 )
241 })
242 };
243}
244
245macro_rules! tuple_read_node {
246 (
247 value,
248 $T:ty,
249 $C:ty,
250 $context:expr,
251 $ref_mode:expr,
252 $same_type:expr,
253 $declared:expr,
254 $declared_type:expr,
255 $type_info:expr,
256 $type_info_field:expr
257 ) => {
258 if !$same_type {
259 <$C as Serializer>::read($context, $ref_mode, true)
260 } else if $declared {
261 <$C as Serializer>::read($context, $ref_mode, false)
262 } else {
263 <$C as Serializer>::read_with_type_info(
264 $context,
265 $ref_mode,
266 $type_info.as_ref().ok_or_else(missing_tuple_metadata)?,
267 )
268 }
269 };
270 (
271 field,
272 $T:ty,
273 $C:ty,
274 $context:expr,
275 $ref_mode:expr,
276 $same_type:expr,
277 $declared:expr,
278 $declared_type:expr,
279 $type_info:expr,
280 $type_info_field:expr
281 ) => {
282 read_tuple_value::<$T, $C>(
283 $context,
284 $ref_mode,
285 $same_type,
286 $declared_type,
287 $type_info.as_ref(),
288 $type_info_field.as_ref(),
289 )
290 };
291}
292
293macro_rules! tuple_skip_nodes {
294 (
295 value,
296 $context:expr,
297 $count:expr,
298 $ref_mode:expr,
299 $same_type:expr,
300 $declared:expr,
301 $declared_type:expr,
302 $type_info:expr;
303 ($T:ident, $C:ident, $S:ident, $index:tt)
304 $(, ($rest_t:ident, $rest_c:ident, $rest_s:ident, $rest_index:tt))*
305 ) => {
306 if $same_type && $declared {
307 skip_declared_tuple_values::<$T, $C>($context, $count, $ref_mode)
308 } else {
309 skip_tuple_values(
310 $context,
311 $count,
312 $ref_mode,
313 $same_type,
314 None,
315 $type_info.as_ref(),
316 )
317 }
318 };
319 (
320 field,
321 $context:expr,
322 $count:expr,
323 $ref_mode:expr,
324 $same_type:expr,
325 $declared:expr,
326 $declared_type:expr,
327 $type_info:expr;
328 $(($T:ident, $C:ident, $S:ident, $index:tt)),+
329 ) => {
330 skip_tuple_values(
331 $context,
332 $count,
333 $ref_mode,
334 $same_type,
335 $declared_type,
336 $type_info.as_ref(),
337 )
338 };
339}
340
341macro_rules! read_tuple_body {
342 (
343 $layer:ident,
344 $context:expr,
345 $remote:expr;
346 $(($T:ident, $C:ident, $S:ident, $index:tt)),+
347 ) => {{
348 let context = &mut *$context;
349 if !context.is_compatible() && !context.is_xlang() {
350 return Ok(($(read_tuple_element::<$T, $C>(context)?,)+));
351 }
352 let len = context.reader.read_var_u32()?;
353 context.reader.check_bound(len as usize)?;
354 if len == 0 {
355 return Ok(($($C::default_value(context)?,)+));
356 }
357 let header = context.reader.read_u8()?;
358 let same_type = (header & IS_SAME_TYPE) != 0;
359 let ref_mode = tuple_ref_mode(header);
360 let declared = (header & DECL_ELEMENT_TYPE) != 0;
361 let declared_type = tuple_declared_type!(
362 $layer,
363 context,
364 $remote,
365 same_type,
366 declared,
367 ref_mode
368 );
369 let type_info = if same_type && !declared {
370 Some(context.read_any_type_info()?)
371 } else {
372 None
373 };
374 let type_info_field =
375 tuple_type_info_field!($layer, type_info, ref_mode);
376 let _ = &declared_type;
377 let _ = &type_info_field;
378 let mut index = 0u32;
379 let value = ($({
380 let value = if index < len {
381 index += 1;
382 tuple_read_node!(
383 $layer,
384 $T,
385 $C,
386 context,
387 ref_mode,
388 same_type,
389 declared,
390 declared_type,
391 type_info,
392 type_info_field
393 )?
394 } else {
395 $C::default_value(context)?
396 };
397 value
398 },)+);
399 tuple_skip_nodes!(
400 $layer,
401 context,
402 len - index,
403 ref_mode,
404 same_type,
405 declared,
406 declared_type,
407 type_info;
408 $(($T, $C, $S, $index)),+
409 )?;
410 Ok(value)
411 }};
412}
413
414macro_rules! impl_tuple_codec {
415 (
416 $codec:ident,
417 $provider:ident,
418 $(($T:ident, $C:ident, $S:ident, $index:tt)),+ $(,)?
419 ) => {
420 pub struct $codec<
421 $($T, $C,)+
422 const NULLABLE: bool,
423 const TRACK_REF: bool,
424 >(PhantomData<fn() -> ($($T, $C,)+)>);
425
426 impl<
427 $($T, $C,)+
428 const NULLABLE: bool,
429 const TRACK_REF: bool,
430 > Serializer for $codec<$($T, $C,)+ NULLABLE, TRACK_REF>
431 where
432 $($T: 'static, $C: Serializer<Target = $T>,)+
433 {
434 type Target = ($($T,)+);
435
436 #[inline(always)]
437 fn write_data(
438 value: &Self::Target,
439 context: &mut WriteContext,
440 ) -> Result<(), Error> {
441 if !context.is_compatible() && !context.is_xlang() {
442 $(write_tuple_element::<$T, $C>(&value.$index, context)?;)+
443 return Ok(());
444 }
445 context.writer.write_var_u32(impl_tuple_codec!(@count $($T),+) as u32);
446 let mut header = 0u8;
447 $(
448 if $C::IS_OPTIONAL {
449 header |= HAS_NULL;
450 }
451 if $C::IS_SHARED_REF {
452 header |= TRACKING_REF;
453 }
454 )+
455 context.writer.write_u8(header);
456 let ref_mode = tuple_ref_mode(header);
457 $(
458 $C::write(&value.$index, context, ref_mode, true)?;
459 )+
460 Ok(())
461 }
462
463 #[cfg_attr(debug_assertions, inline(never))]
467 #[cfg_attr(not(debug_assertions), inline(always))]
468 fn read_data(context: &mut ReadContext) -> Result<Self::Target, Error> {
469 read_tuple_body!(
470 value,
471 context,
472 ();
473 $(($T, $C, $S, $index)),+
474 )
475 }
476
477 #[inline(always)]
478 fn default_value(context: &mut ReadContext) -> Result<Self::Target, Error> {
479 Ok(($($C::default_value(context)?,)+))
480 }
481
482 #[inline(always)]
483 fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
484 write_collection_type_info(context, TypeId::LIST as u32)
485 }
486
487 #[inline(always)]
488 fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
489 read_collection_type_info(context, TypeId::LIST as u32)
490 }
491
492 #[inline(always)]
493 fn static_type_id() -> TypeId {
494 TypeId::LIST
495 }
496
497 #[inline(always)]
498 fn reserved_space() -> usize {
499 std::mem::size_of::<u32>() + SIZE_OF_REF_AND_TYPE
500 }
501
502 }
503
504 impl<
505 $($T, $C,)+
506 const NULLABLE: bool,
507 const TRACK_REF: bool,
508 > $codec<$($T, $C,)+ NULLABLE, TRACK_REF>
509 where
510 $($T: 'static, $C: Codec<$T>,)+
511 {
512 #[cfg_attr(debug_assertions, inline(never))]
516 #[cfg_attr(not(debug_assertions), inline(always))]
517 fn read_tuple_with_type(
518 context: &mut ReadContext,
519 remote_data_type: &FieldType,
520 ) -> Result<($($T,)+), Error> {
521 read_tuple_body!(
522 field,
523 context,
524 remote_data_type;
525 $(($T, $C, $S, $index)),+
526 )
527 }
528 }
529
530 impl<
531 $($T, $C,)+
532 const NULLABLE: bool,
533 const TRACK_REF: bool,
534 > Codec<($($T,)+)>
535 for $codec<$($T, $C,)+ NULLABLE, TRACK_REF>
536 where
537 $($T: 'static, $C: Codec<$T>,)+
538 {
539 #[inline(always)]
540 fn field_type(type_resolver: &TypeResolver) -> Result<FieldType, Error> {
541 let _ = type_resolver;
542 Ok(FieldType::new_with_ref(
546 TypeId::LIST as u32,
547 NULLABLE,
548 TRACK_REF,
549 vec![FieldType::new(TypeId::UNKNOWN as u32, true, Vec::new())],
550 ))
551 }
552
553 #[inline(always)]
554 fn write_field(
555 value: &($($T,)+),
556 context: &mut WriteContext,
557 ) -> Result<(), Error> {
558 if NULLABLE || TRACK_REF {
559 context.writer.write_i8(RefFlag::NotNullValue as i8);
560 }
561 <Self as Serializer>::write_data(value, context)
562 }
563
564 #[inline(always)]
565 fn read_field(context: &mut ReadContext) -> Result<($($T,)+), Error> {
566 if (NULLABLE || TRACK_REF)
567 && context.reader.read_i8()? == RefFlag::Null as i8
568 {
569 return <Self as Serializer>::default_value(context);
570 }
571 <Self as Serializer>::read_data(context)
572 }
573
574 #[inline(always)]
575 fn read_data_with_type(
576 context: &mut ReadContext,
577 remote_data_type: &FieldType,
578 ) -> Result<($($T,)+), Error> {
579 Self::read_tuple_with_type(context, remote_data_type)
580 }
581
582 #[inline(always)]
583 fn read_field_with_type(
584 context: &mut ReadContext,
585 remote_field_type: &FieldType,
586 ) -> Result<($($T,)+), Error> {
587 if field_ref_mode(remote_field_type) != RefMode::None
588 && context.reader.read_i8()? == RefFlag::Null as i8
589 {
590 return <Self as Serializer>::default_value(context);
591 }
592 Self::read_data_with_type(context, remote_field_type)
593 }
594
595 #[inline(always)]
596 fn write_with_mode(
597 value: &($($T,)+),
598 context: &mut WriteContext,
599 ref_mode: RefMode,
600 write_type_info: bool,
601 _has_generics: bool,
602 ) -> Result<(), Error> {
603 <Self as Serializer>::write(
604 value,
605 context,
606 ref_mode,
607 write_type_info,
608 )
609 }
610 }
611
612 #[doc = concat!(
613 "Statically serializes the recursively formed tuple of each child serializer's ",
614 "`Target` at roots or recursive carrier nodes. This zero-sized carrier is not ",
615 "registered independently."
616 )]
617 pub struct $provider<$($S,)+>(PhantomData<fn() -> ($($S,)+)>);
618
619 impl<$($S: Serializer,)+> Serializer for $provider<$($S,)+> {
620 type Target = ($($S::Target,)+);
621
622 #[inline(always)]
623 fn write_data(value: &Self::Target, context: &mut WriteContext) -> Result<(), Error> {
624 <$codec<
625 $($S::Target, $S,)+
626 false,
627 false,
628 > as Serializer>::write_data(value, context)
629 }
630
631 #[inline(always)]
632 fn read_data(context: &mut ReadContext) -> Result<Self::Target, Error> {
633 <$codec<
634 $($S::Target, $S,)+
635 false,
636 false,
637 > as Serializer>::read_data(context)
638 }
639
640 #[inline(always)]
641 fn default_value(context: &mut ReadContext) -> Result<Self::Target, Error> {
642 <$codec<
643 $($S::Target, $S,)+
644 false,
645 false,
646 > as Serializer>::default_value(context)
647 }
648
649 #[inline(always)]
650 fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
651 write_collection_type_info(context, TypeId::LIST as u32)
652 }
653
654 #[inline(always)]
655 fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
656 read_collection_type_info(context, TypeId::LIST as u32)
657 }
658
659 #[inline(always)]
660 fn static_type_id() -> TypeId {
661 TypeId::LIST
662 }
663
664 #[inline(always)]
665 fn reserved_space() -> usize {
666 std::mem::size_of::<u32>() + SIZE_OF_REF_AND_TYPE
667 }
668
669 }
670
671 impl<$($T,)+> Serializer for ($($T,)+)
672 where
673 $($T: Serializer<Target = $T>,)+
674 {
675 type Target = Self;
676
677 #[inline(always)]
678 fn write_data(value: &Self, context: &mut WriteContext) -> Result<(), Error> {
679 <$provider<$($T,)+> as Serializer>::write_data(value, context)
680 }
681
682 #[inline(always)]
683 fn read_data(context: &mut ReadContext) -> Result<Self, Error> {
684 <$provider<$($T,)+> as Serializer>::read_data(context)
685 }
686
687 #[inline(always)]
688 fn default_value(context: &mut ReadContext) -> Result<Self, Error> {
689 <$provider<$($T,)+> as Serializer>::default_value(context)
690 }
691
692 #[inline(always)]
693 fn write(
694 value: &Self,
695 context: &mut WriteContext,
696 ref_mode: RefMode,
697 write_type_info: bool,
698 ) -> Result<(), Error> {
699 <$provider<$($T,)+> as Serializer>::write(
700 value,
701 context,
702 ref_mode,
703 write_type_info,
704 )
705 }
706
707 #[inline(always)]
708 fn read(
709 context: &mut ReadContext,
710 ref_mode: RefMode,
711 read_type_info: bool,
712 ) -> Result<Self, Error> {
713 <$provider<$($T,)+> as Serializer>::read(
714 context,
715 ref_mode,
716 read_type_info,
717 )
718 }
719
720 #[inline(always)]
721 fn read_with_type_info(
722 context: &mut ReadContext,
723 ref_mode: RefMode,
724 type_info: &Rc<TypeInfo>,
725 ) -> Result<Self, Error> {
726 <$provider<$($T,)+> as Serializer>::read_with_type_info(
727 context,
728 ref_mode,
729 type_info,
730 )
731 }
732
733 #[inline(always)]
734 fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
735 <$provider<$($T,)+> as Serializer>::write_type_info(context)
736 }
737
738 #[inline(always)]
739 fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
740 <$provider<$($T,)+> as Serializer>::read_type_info(context)
741 }
742
743 #[inline(always)]
744 fn static_type_id() -> TypeId {
745 TypeId::LIST
746 }
747
748 #[inline(always)]
749 fn reserved_space() -> usize {
750 std::mem::size_of::<u32>() + SIZE_OF_REF_AND_TYPE
751 }
752
753 }
754 };
755
756 (@count $head:ident $(, $tail:ident)*) => {
757 1usize $(+ impl_tuple_codec!(@one $tail))*
758 };
759 (@one $value:ident) => { 1usize };
760}
761
762impl_tuple_codec!(Tuple1Codec, Tuple1Serializer, (T0, C0, S0, 0));
763impl_tuple_codec!(
764 Tuple2Codec,
765 Tuple2Serializer,
766 (T0, C0, S0, 0),
767 (T1, C1, S1, 1)
768);
769impl_tuple_codec!(
770 Tuple3Codec,
771 Tuple3Serializer,
772 (T0, C0, S0, 0),
773 (T1, C1, S1, 1),
774 (T2, C2, S2, 2)
775);
776impl_tuple_codec!(
777 Tuple4Codec,
778 Tuple4Serializer,
779 (T0, C0, S0, 0),
780 (T1, C1, S1, 1),
781 (T2, C2, S2, 2),
782 (T3, C3, S3, 3)
783);
784impl_tuple_codec!(
785 Tuple5Codec,
786 Tuple5Serializer,
787 (T0, C0, S0, 0),
788 (T1, C1, S1, 1),
789 (T2, C2, S2, 2),
790 (T3, C3, S3, 3),
791 (T4, C4, S4, 4)
792);
793impl_tuple_codec!(
794 Tuple6Codec,
795 Tuple6Serializer,
796 (T0, C0, S0, 0),
797 (T1, C1, S1, 1),
798 (T2, C2, S2, 2),
799 (T3, C3, S3, 3),
800 (T4, C4, S4, 4),
801 (T5, C5, S5, 5)
802);
803impl_tuple_codec!(
804 Tuple7Codec,
805 Tuple7Serializer,
806 (T0, C0, S0, 0),
807 (T1, C1, S1, 1),
808 (T2, C2, S2, 2),
809 (T3, C3, S3, 3),
810 (T4, C4, S4, 4),
811 (T5, C5, S5, 5),
812 (T6, C6, S6, 6)
813);
814impl_tuple_codec!(
815 Tuple8Codec,
816 Tuple8Serializer,
817 (T0, C0, S0, 0),
818 (T1, C1, S1, 1),
819 (T2, C2, S2, 2),
820 (T3, C3, S3, 3),
821 (T4, C4, S4, 4),
822 (T5, C5, S5, 5),
823 (T6, C6, S6, 6),
824 (T7, C7, S7, 7)
825);
826impl_tuple_codec!(
827 Tuple9Codec,
828 Tuple9Serializer,
829 (T0, C0, S0, 0),
830 (T1, C1, S1, 1),
831 (T2, C2, S2, 2),
832 (T3, C3, S3, 3),
833 (T4, C4, S4, 4),
834 (T5, C5, S5, 5),
835 (T6, C6, S6, 6),
836 (T7, C7, S7, 7),
837 (T8, C8, S8, 8)
838);
839impl_tuple_codec!(
840 Tuple10Codec,
841 Tuple10Serializer,
842 (T0, C0, S0, 0),
843 (T1, C1, S1, 1),
844 (T2, C2, S2, 2),
845 (T3, C3, S3, 3),
846 (T4, C4, S4, 4),
847 (T5, C5, S5, 5),
848 (T6, C6, S6, 6),
849 (T7, C7, S7, 7),
850 (T8, C8, S8, 8),
851 (T9, C9, S9, 9)
852);
853impl_tuple_codec!(
854 Tuple11Codec,
855 Tuple11Serializer,
856 (T0, C0, S0, 0),
857 (T1, C1, S1, 1),
858 (T2, C2, S2, 2),
859 (T3, C3, S3, 3),
860 (T4, C4, S4, 4),
861 (T5, C5, S5, 5),
862 (T6, C6, S6, 6),
863 (T7, C7, S7, 7),
864 (T8, C8, S8, 8),
865 (T9, C9, S9, 9),
866 (T10, C10, S10, 10)
867);
868impl_tuple_codec!(
869 Tuple12Codec,
870 Tuple12Serializer,
871 (T0, C0, S0, 0),
872 (T1, C1, S1, 1),
873 (T2, C2, S2, 2),
874 (T3, C3, S3, 3),
875 (T4, C4, S4, 4),
876 (T5, C5, S5, 5),
877 (T6, C6, S6, 6),
878 (T7, C7, S7, 7),
879 (T8, C8, S8, 8),
880 (T9, C9, S9, 9),
881 (T10, C10, S10, 10),
882 (T11, C11, S11, 11)
883);
884impl_tuple_codec!(
885 Tuple13Codec,
886 Tuple13Serializer,
887 (T0, C0, S0, 0),
888 (T1, C1, S1, 1),
889 (T2, C2, S2, 2),
890 (T3, C3, S3, 3),
891 (T4, C4, S4, 4),
892 (T5, C5, S5, 5),
893 (T6, C6, S6, 6),
894 (T7, C7, S7, 7),
895 (T8, C8, S8, 8),
896 (T9, C9, S9, 9),
897 (T10, C10, S10, 10),
898 (T11, C11, S11, 11),
899 (T12, C12, S12, 12)
900);
901impl_tuple_codec!(
902 Tuple14Codec,
903 Tuple14Serializer,
904 (T0, C0, S0, 0),
905 (T1, C1, S1, 1),
906 (T2, C2, S2, 2),
907 (T3, C3, S3, 3),
908 (T4, C4, S4, 4),
909 (T5, C5, S5, 5),
910 (T6, C6, S6, 6),
911 (T7, C7, S7, 7),
912 (T8, C8, S8, 8),
913 (T9, C9, S9, 9),
914 (T10, C10, S10, 10),
915 (T11, C11, S11, 11),
916 (T12, C12, S12, 12),
917 (T13, C13, S13, 13)
918);
919impl_tuple_codec!(
920 Tuple15Codec,
921 Tuple15Serializer,
922 (T0, C0, S0, 0),
923 (T1, C1, S1, 1),
924 (T2, C2, S2, 2),
925 (T3, C3, S3, 3),
926 (T4, C4, S4, 4),
927 (T5, C5, S5, 5),
928 (T6, C6, S6, 6),
929 (T7, C7, S7, 7),
930 (T8, C8, S8, 8),
931 (T9, C9, S9, 9),
932 (T10, C10, S10, 10),
933 (T11, C11, S11, 11),
934 (T12, C12, S12, 12),
935 (T13, C13, S13, 13),
936 (T14, C14, S14, 14)
937);
938impl_tuple_codec!(
939 Tuple16Codec,
940 Tuple16Serializer,
941 (T0, C0, S0, 0),
942 (T1, C1, S1, 1),
943 (T2, C2, S2, 2),
944 (T3, C3, S3, 3),
945 (T4, C4, S4, 4),
946 (T5, C5, S5, 5),
947 (T6, C6, S6, 6),
948 (T7, C7, S7, 7),
949 (T8, C8, S8, 8),
950 (T9, C9, S9, 9),
951 (T10, C10, S10, 10),
952 (T11, C11, S11, 11),
953 (T12, C12, S12, 12),
954 (T13, C13, S13, 13),
955 (T14, C14, S14, 14),
956 (T15, C15, S15, 15)
957);
958impl_tuple_codec!(
959 Tuple17Codec,
960 Tuple17Serializer,
961 (T0, C0, S0, 0),
962 (T1, C1, S1, 1),
963 (T2, C2, S2, 2),
964 (T3, C3, S3, 3),
965 (T4, C4, S4, 4),
966 (T5, C5, S5, 5),
967 (T6, C6, S6, 6),
968 (T7, C7, S7, 7),
969 (T8, C8, S8, 8),
970 (T9, C9, S9, 9),
971 (T10, C10, S10, 10),
972 (T11, C11, S11, 11),
973 (T12, C12, S12, 12),
974 (T13, C13, S13, 13),
975 (T14, C14, S14, 14),
976 (T15, C15, S15, 15),
977 (T16, C16, S16, 16)
978);
979impl_tuple_codec!(
980 Tuple18Codec,
981 Tuple18Serializer,
982 (T0, C0, S0, 0),
983 (T1, C1, S1, 1),
984 (T2, C2, S2, 2),
985 (T3, C3, S3, 3),
986 (T4, C4, S4, 4),
987 (T5, C5, S5, 5),
988 (T6, C6, S6, 6),
989 (T7, C7, S7, 7),
990 (T8, C8, S8, 8),
991 (T9, C9, S9, 9),
992 (T10, C10, S10, 10),
993 (T11, C11, S11, 11),
994 (T12, C12, S12, 12),
995 (T13, C13, S13, 13),
996 (T14, C14, S14, 14),
997 (T15, C15, S15, 15),
998 (T16, C16, S16, 16),
999 (T17, C17, S17, 17)
1000);
1001impl_tuple_codec!(
1002 Tuple19Codec,
1003 Tuple19Serializer,
1004 (T0, C0, S0, 0),
1005 (T1, C1, S1, 1),
1006 (T2, C2, S2, 2),
1007 (T3, C3, S3, 3),
1008 (T4, C4, S4, 4),
1009 (T5, C5, S5, 5),
1010 (T6, C6, S6, 6),
1011 (T7, C7, S7, 7),
1012 (T8, C8, S8, 8),
1013 (T9, C9, S9, 9),
1014 (T10, C10, S10, 10),
1015 (T11, C11, S11, 11),
1016 (T12, C12, S12, 12),
1017 (T13, C13, S13, 13),
1018 (T14, C14, S14, 14),
1019 (T15, C15, S15, 15),
1020 (T16, C16, S16, 16),
1021 (T17, C17, S17, 17),
1022 (T18, C18, S18, 18)
1023);
1024impl_tuple_codec!(
1025 Tuple20Codec,
1026 Tuple20Serializer,
1027 (T0, C0, S0, 0),
1028 (T1, C1, S1, 1),
1029 (T2, C2, S2, 2),
1030 (T3, C3, S3, 3),
1031 (T4, C4, S4, 4),
1032 (T5, C5, S5, 5),
1033 (T6, C6, S6, 6),
1034 (T7, C7, S7, 7),
1035 (T8, C8, S8, 8),
1036 (T9, C9, S9, 9),
1037 (T10, C10, S10, 10),
1038 (T11, C11, S11, 11),
1039 (T12, C12, S12, 12),
1040 (T13, C13, S13, 13),
1041 (T14, C14, S14, 14),
1042 (T15, C15, S15, 15),
1043 (T16, C16, S16, 16),
1044 (T17, C17, S17, 17),
1045 (T18, C18, S18, 18),
1046 (T19, C19, S19, 19)
1047);
1048impl_tuple_codec!(
1049 Tuple21Codec,
1050 Tuple21Serializer,
1051 (T0, C0, S0, 0),
1052 (T1, C1, S1, 1),
1053 (T2, C2, S2, 2),
1054 (T3, C3, S3, 3),
1055 (T4, C4, S4, 4),
1056 (T5, C5, S5, 5),
1057 (T6, C6, S6, 6),
1058 (T7, C7, S7, 7),
1059 (T8, C8, S8, 8),
1060 (T9, C9, S9, 9),
1061 (T10, C10, S10, 10),
1062 (T11, C11, S11, 11),
1063 (T12, C12, S12, 12),
1064 (T13, C13, S13, 13),
1065 (T14, C14, S14, 14),
1066 (T15, C15, S15, 15),
1067 (T16, C16, S16, 16),
1068 (T17, C17, S17, 17),
1069 (T18, C18, S18, 18),
1070 (T19, C19, S19, 19),
1071 (T20, C20, S20, 20)
1072);
1073impl_tuple_codec!(
1074 Tuple22Codec,
1075 Tuple22Serializer,
1076 (T0, C0, S0, 0),
1077 (T1, C1, S1, 1),
1078 (T2, C2, S2, 2),
1079 (T3, C3, S3, 3),
1080 (T4, C4, S4, 4),
1081 (T5, C5, S5, 5),
1082 (T6, C6, S6, 6),
1083 (T7, C7, S7, 7),
1084 (T8, C8, S8, 8),
1085 (T9, C9, S9, 9),
1086 (T10, C10, S10, 10),
1087 (T11, C11, S11, 11),
1088 (T12, C12, S12, 12),
1089 (T13, C13, S13, 13),
1090 (T14, C14, S14, 14),
1091 (T15, C15, S15, 15),
1092 (T16, C16, S16, 16),
1093 (T17, C17, S17, 17),
1094 (T18, C18, S18, 18),
1095 (T19, C19, S19, 19),
1096 (T20, C20, S20, 20),
1097 (T21, C21, S21, 21)
1098);