Skip to main content

fory_core/serializer/
tuple.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use 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            const READ_DATA_ALWAYS_ADVANCES: bool = false $(
437                || $C::IS_OPTIONAL
438                || $C::IS_SHARED_REF
439                || $C::READ_DATA_ALWAYS_ADVANCES
440            )+;
441
442            #[inline(always)]
443            fn write_data(
444                value: &Self::Target,
445                context: &mut WriteContext,
446            ) -> Result<(), Error> {
447                if !context.is_compatible() && !context.is_xlang() {
448                    $(write_tuple_element::<$T, $C>(&value.$index, context)?;)+
449                    return Ok(());
450                }
451                context.writer.write_var_u32(impl_tuple_codec!(@count $($T),+) as u32);
452                let mut header = 0u8;
453                $(
454                    if $C::IS_OPTIONAL {
455                        header |= HAS_NULL;
456                    }
457                    if $C::IS_SHARED_REF {
458                        header |= TRACKING_REF;
459                    }
460                )+
461                context.writer.write_u8(header);
462                let ref_mode = tuple_ref_mode(header);
463                $(
464                    $C::write(&value.$index, context, ref_mode, true)?;
465                )+
466                Ok(())
467            }
468
469            // Debug builds must not inline recursively nested tuple readers
470            // into one generated compatible-struct frame; complex schemas can
471            // otherwise exhaust the test thread's stack.
472            #[cfg_attr(debug_assertions, inline(never))]
473            #[cfg_attr(not(debug_assertions), inline(always))]
474            fn read_data(context: &mut ReadContext) -> Result<Self::Target, Error> {
475                read_tuple_body!(
476                    value,
477                    context,
478                    ();
479                    $(($T, $C, $S, $index)),+
480                )
481            }
482
483            #[inline(always)]
484            fn default_value(context: &mut ReadContext) -> Result<Self::Target, Error> {
485                Ok(($($C::default_value(context)?,)+))
486            }
487
488            #[inline(always)]
489            fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
490                write_collection_type_info(context, TypeId::LIST as u32)
491            }
492
493            #[inline(always)]
494            fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
495                read_collection_type_info(context, TypeId::LIST as u32)
496            }
497
498            #[inline(always)]
499            fn static_type_id() -> TypeId {
500                TypeId::LIST
501            }
502
503            #[inline(always)]
504            fn reserved_space() -> usize {
505                std::mem::size_of::<u32>() + SIZE_OF_REF_AND_TYPE
506            }
507
508        }
509
510        impl<
511                $($T, $C,)+
512                const NULLABLE: bool,
513                const TRACK_REF: bool,
514            > $codec<$($T, $C,)+ NULLABLE, TRACK_REF>
515        where
516            $($T: 'static, $C: Codec<$T>,)+
517        {
518            // This is the field-only counterpart to `Serializer::read_data`.
519            // It consumes the remote tuple field schema without leaking
520            // `FieldType` into value-level serializer composition.
521            #[cfg_attr(debug_assertions, inline(never))]
522            #[cfg_attr(not(debug_assertions), inline(always))]
523            fn read_tuple_with_type(
524                context: &mut ReadContext,
525                remote_data_type: &FieldType,
526            ) -> Result<($($T,)+), Error> {
527                read_tuple_body!(
528                    field,
529                    context,
530                    remote_data_type;
531                    $(($T, $C, $S, $index)),+
532                )
533            }
534        }
535
536        impl<
537                $($T, $C,)+
538                const NULLABLE: bool,
539                const TRACK_REF: bool,
540            > Codec<($($T,)+)>
541            for $codec<$($T, $C,)+ NULLABLE, TRACK_REF>
542        where
543            $($T: 'static, $C: Codec<$T>,)+
544        {
545            #[inline(always)]
546            fn field_type(type_resolver: &TypeResolver) -> Result<FieldType, Error> {
547                let _ = type_resolver;
548                // Tuple positions carry their own type metadata in compatible and
549                // xlang bodies. LIST metadata has one homogeneous generic slot, so
550                // declaring position codecs here would truncate the schema on wire.
551                Ok(FieldType::new_with_ref(
552                    TypeId::LIST as u32,
553                    NULLABLE,
554                    TRACK_REF,
555                    vec![FieldType::new(TypeId::UNKNOWN as u32, true, Vec::new())],
556                ))
557            }
558
559            #[inline(always)]
560            fn write_field(
561                value: &($($T,)+),
562                context: &mut WriteContext,
563            ) -> Result<(), Error> {
564                if NULLABLE || TRACK_REF {
565                    context.writer.write_i8(RefFlag::NotNullValue as i8);
566                }
567                <Self as Serializer>::write_data(value, context)
568            }
569
570            #[inline(always)]
571            fn read_field(context: &mut ReadContext) -> Result<($($T,)+), Error> {
572                if (NULLABLE || TRACK_REF)
573                    && context.reader.read_i8()? == RefFlag::Null as i8
574                {
575                    return <Self as Serializer>::default_value(context);
576                }
577                <Self as Serializer>::read_data(context)
578            }
579
580            #[inline(always)]
581            fn read_data_with_type(
582                context: &mut ReadContext,
583                remote_data_type: &FieldType,
584            ) -> Result<($($T,)+), Error> {
585                Self::read_tuple_with_type(context, remote_data_type)
586            }
587
588            #[inline(always)]
589            fn read_field_with_type(
590                context: &mut ReadContext,
591                remote_field_type: &FieldType,
592            ) -> Result<($($T,)+), Error> {
593                if field_ref_mode(remote_field_type) != RefMode::None
594                    && context.reader.read_i8()? == RefFlag::Null as i8
595                {
596                    return <Self as Serializer>::default_value(context);
597                }
598                Self::read_data_with_type(context, remote_field_type)
599            }
600
601            #[inline(always)]
602            fn write_with_mode(
603                value: &($($T,)+),
604                context: &mut WriteContext,
605                ref_mode: RefMode,
606                write_type_info: bool,
607                _has_generics: bool,
608            ) -> Result<(), Error> {
609                <Self as Serializer>::write(
610                    value,
611                    context,
612                    ref_mode,
613                    write_type_info,
614                )
615            }
616        }
617
618        #[doc = concat!(
619            "Statically serializes the recursively formed tuple of each child serializer's ",
620            "`Target` at roots or recursive carrier nodes. This zero-sized carrier is not ",
621            "registered independently."
622        )]
623        pub struct $provider<$($S,)+>(PhantomData<fn() -> ($($S,)+)>);
624
625        impl<$($S: Serializer,)+> Serializer for $provider<$($S,)+> {
626            type Target = ($($S::Target,)+);
627
628            const READ_DATA_ALWAYS_ADVANCES: bool = false $(
629                || $S::IS_OPTIONAL
630                || $S::IS_SHARED_REF
631                || $S::READ_DATA_ALWAYS_ADVANCES
632            )+;
633
634            #[inline(always)]
635            fn write_data(value: &Self::Target, context: &mut WriteContext) -> Result<(), Error> {
636                <$codec<
637                    $($S::Target, $S,)+
638                    false,
639                    false,
640                > as Serializer>::write_data(value, context)
641            }
642
643            #[inline(always)]
644            fn read_data(context: &mut ReadContext) -> Result<Self::Target, Error> {
645                <$codec<
646                    $($S::Target, $S,)+
647                    false,
648                    false,
649                > as Serializer>::read_data(context)
650            }
651
652            #[inline(always)]
653            fn default_value(context: &mut ReadContext) -> Result<Self::Target, Error> {
654                <$codec<
655                    $($S::Target, $S,)+
656                    false,
657                    false,
658                > as Serializer>::default_value(context)
659            }
660
661            #[inline(always)]
662            fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
663                write_collection_type_info(context, TypeId::LIST as u32)
664            }
665
666            #[inline(always)]
667            fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
668                read_collection_type_info(context, TypeId::LIST as u32)
669            }
670
671            #[inline(always)]
672            fn static_type_id() -> TypeId {
673                TypeId::LIST
674            }
675
676            #[inline(always)]
677            fn reserved_space() -> usize {
678                std::mem::size_of::<u32>() + SIZE_OF_REF_AND_TYPE
679            }
680
681        }
682
683        impl<$($T,)+> Serializer for ($($T,)+)
684        where
685            $($T: Serializer<Target = $T>,)+
686        {
687            type Target = Self;
688
689            const READ_DATA_ALWAYS_ADVANCES: bool = false $(
690                || $T::IS_OPTIONAL
691                || $T::IS_SHARED_REF
692                || $T::READ_DATA_ALWAYS_ADVANCES
693            )+;
694
695            #[inline(always)]
696            fn write_data(value: &Self, context: &mut WriteContext) -> Result<(), Error> {
697                <$provider<$($T,)+> as Serializer>::write_data(value, context)
698            }
699
700            #[inline(always)]
701            fn read_data(context: &mut ReadContext) -> Result<Self, Error> {
702                <$provider<$($T,)+> as Serializer>::read_data(context)
703            }
704
705            #[inline(always)]
706            fn default_value(context: &mut ReadContext) -> Result<Self, Error> {
707                <$provider<$($T,)+> as Serializer>::default_value(context)
708            }
709
710            #[inline(always)]
711            fn write(
712                value: &Self,
713                context: &mut WriteContext,
714                ref_mode: RefMode,
715                write_type_info: bool,
716            ) -> Result<(), Error> {
717                <$provider<$($T,)+> as Serializer>::write(
718                    value,
719                    context,
720                    ref_mode,
721                    write_type_info,
722                )
723            }
724
725            #[inline(always)]
726            fn read(
727                context: &mut ReadContext,
728                ref_mode: RefMode,
729                read_type_info: bool,
730            ) -> Result<Self, Error> {
731                <$provider<$($T,)+> as Serializer>::read(
732                    context,
733                    ref_mode,
734                    read_type_info,
735                )
736            }
737
738            #[inline(always)]
739            fn read_with_type_info(
740                context: &mut ReadContext,
741                ref_mode: RefMode,
742                type_info: &Rc<TypeInfo>,
743            ) -> Result<Self, Error> {
744                <$provider<$($T,)+> as Serializer>::read_with_type_info(
745                    context,
746                    ref_mode,
747                    type_info,
748                )
749            }
750
751            #[inline(always)]
752            fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
753                <$provider<$($T,)+> as Serializer>::write_type_info(context)
754            }
755
756            #[inline(always)]
757            fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
758                <$provider<$($T,)+> as Serializer>::read_type_info(context)
759            }
760
761            #[inline(always)]
762            fn static_type_id() -> TypeId {
763                TypeId::LIST
764            }
765
766            #[inline(always)]
767            fn reserved_space() -> usize {
768                std::mem::size_of::<u32>() + SIZE_OF_REF_AND_TYPE
769            }
770
771        }
772    };
773
774    (@count $head:ident $(, $tail:ident)*) => {
775        1usize $(+ impl_tuple_codec!(@one $tail))*
776    };
777    (@one $value:ident) => { 1usize };
778}
779
780impl_tuple_codec!(Tuple1Codec, Tuple1Serializer, (T0, C0, S0, 0));
781impl_tuple_codec!(
782    Tuple2Codec,
783    Tuple2Serializer,
784    (T0, C0, S0, 0),
785    (T1, C1, S1, 1)
786);
787impl_tuple_codec!(
788    Tuple3Codec,
789    Tuple3Serializer,
790    (T0, C0, S0, 0),
791    (T1, C1, S1, 1),
792    (T2, C2, S2, 2)
793);
794impl_tuple_codec!(
795    Tuple4Codec,
796    Tuple4Serializer,
797    (T0, C0, S0, 0),
798    (T1, C1, S1, 1),
799    (T2, C2, S2, 2),
800    (T3, C3, S3, 3)
801);
802impl_tuple_codec!(
803    Tuple5Codec,
804    Tuple5Serializer,
805    (T0, C0, S0, 0),
806    (T1, C1, S1, 1),
807    (T2, C2, S2, 2),
808    (T3, C3, S3, 3),
809    (T4, C4, S4, 4)
810);
811impl_tuple_codec!(
812    Tuple6Codec,
813    Tuple6Serializer,
814    (T0, C0, S0, 0),
815    (T1, C1, S1, 1),
816    (T2, C2, S2, 2),
817    (T3, C3, S3, 3),
818    (T4, C4, S4, 4),
819    (T5, C5, S5, 5)
820);
821impl_tuple_codec!(
822    Tuple7Codec,
823    Tuple7Serializer,
824    (T0, C0, S0, 0),
825    (T1, C1, S1, 1),
826    (T2, C2, S2, 2),
827    (T3, C3, S3, 3),
828    (T4, C4, S4, 4),
829    (T5, C5, S5, 5),
830    (T6, C6, S6, 6)
831);
832impl_tuple_codec!(
833    Tuple8Codec,
834    Tuple8Serializer,
835    (T0, C0, S0, 0),
836    (T1, C1, S1, 1),
837    (T2, C2, S2, 2),
838    (T3, C3, S3, 3),
839    (T4, C4, S4, 4),
840    (T5, C5, S5, 5),
841    (T6, C6, S6, 6),
842    (T7, C7, S7, 7)
843);
844impl_tuple_codec!(
845    Tuple9Codec,
846    Tuple9Serializer,
847    (T0, C0, S0, 0),
848    (T1, C1, S1, 1),
849    (T2, C2, S2, 2),
850    (T3, C3, S3, 3),
851    (T4, C4, S4, 4),
852    (T5, C5, S5, 5),
853    (T6, C6, S6, 6),
854    (T7, C7, S7, 7),
855    (T8, C8, S8, 8)
856);
857impl_tuple_codec!(
858    Tuple10Codec,
859    Tuple10Serializer,
860    (T0, C0, S0, 0),
861    (T1, C1, S1, 1),
862    (T2, C2, S2, 2),
863    (T3, C3, S3, 3),
864    (T4, C4, S4, 4),
865    (T5, C5, S5, 5),
866    (T6, C6, S6, 6),
867    (T7, C7, S7, 7),
868    (T8, C8, S8, 8),
869    (T9, C9, S9, 9)
870);
871impl_tuple_codec!(
872    Tuple11Codec,
873    Tuple11Serializer,
874    (T0, C0, S0, 0),
875    (T1, C1, S1, 1),
876    (T2, C2, S2, 2),
877    (T3, C3, S3, 3),
878    (T4, C4, S4, 4),
879    (T5, C5, S5, 5),
880    (T6, C6, S6, 6),
881    (T7, C7, S7, 7),
882    (T8, C8, S8, 8),
883    (T9, C9, S9, 9),
884    (T10, C10, S10, 10)
885);
886impl_tuple_codec!(
887    Tuple12Codec,
888    Tuple12Serializer,
889    (T0, C0, S0, 0),
890    (T1, C1, S1, 1),
891    (T2, C2, S2, 2),
892    (T3, C3, S3, 3),
893    (T4, C4, S4, 4),
894    (T5, C5, S5, 5),
895    (T6, C6, S6, 6),
896    (T7, C7, S7, 7),
897    (T8, C8, S8, 8),
898    (T9, C9, S9, 9),
899    (T10, C10, S10, 10),
900    (T11, C11, S11, 11)
901);
902impl_tuple_codec!(
903    Tuple13Codec,
904    Tuple13Serializer,
905    (T0, C0, S0, 0),
906    (T1, C1, S1, 1),
907    (T2, C2, S2, 2),
908    (T3, C3, S3, 3),
909    (T4, C4, S4, 4),
910    (T5, C5, S5, 5),
911    (T6, C6, S6, 6),
912    (T7, C7, S7, 7),
913    (T8, C8, S8, 8),
914    (T9, C9, S9, 9),
915    (T10, C10, S10, 10),
916    (T11, C11, S11, 11),
917    (T12, C12, S12, 12)
918);
919impl_tuple_codec!(
920    Tuple14Codec,
921    Tuple14Serializer,
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);
937impl_tuple_codec!(
938    Tuple15Codec,
939    Tuple15Serializer,
940    (T0, C0, S0, 0),
941    (T1, C1, S1, 1),
942    (T2, C2, S2, 2),
943    (T3, C3, S3, 3),
944    (T4, C4, S4, 4),
945    (T5, C5, S5, 5),
946    (T6, C6, S6, 6),
947    (T7, C7, S7, 7),
948    (T8, C8, S8, 8),
949    (T9, C9, S9, 9),
950    (T10, C10, S10, 10),
951    (T11, C11, S11, 11),
952    (T12, C12, S12, 12),
953    (T13, C13, S13, 13),
954    (T14, C14, S14, 14)
955);
956impl_tuple_codec!(
957    Tuple16Codec,
958    Tuple16Serializer,
959    (T0, C0, S0, 0),
960    (T1, C1, S1, 1),
961    (T2, C2, S2, 2),
962    (T3, C3, S3, 3),
963    (T4, C4, S4, 4),
964    (T5, C5, S5, 5),
965    (T6, C6, S6, 6),
966    (T7, C7, S7, 7),
967    (T8, C8, S8, 8),
968    (T9, C9, S9, 9),
969    (T10, C10, S10, 10),
970    (T11, C11, S11, 11),
971    (T12, C12, S12, 12),
972    (T13, C13, S13, 13),
973    (T14, C14, S14, 14),
974    (T15, C15, S15, 15)
975);
976impl_tuple_codec!(
977    Tuple17Codec,
978    Tuple17Serializer,
979    (T0, C0, S0, 0),
980    (T1, C1, S1, 1),
981    (T2, C2, S2, 2),
982    (T3, C3, S3, 3),
983    (T4, C4, S4, 4),
984    (T5, C5, S5, 5),
985    (T6, C6, S6, 6),
986    (T7, C7, S7, 7),
987    (T8, C8, S8, 8),
988    (T9, C9, S9, 9),
989    (T10, C10, S10, 10),
990    (T11, C11, S11, 11),
991    (T12, C12, S12, 12),
992    (T13, C13, S13, 13),
993    (T14, C14, S14, 14),
994    (T15, C15, S15, 15),
995    (T16, C16, S16, 16)
996);
997impl_tuple_codec!(
998    Tuple18Codec,
999    Tuple18Serializer,
1000    (T0, C0, S0, 0),
1001    (T1, C1, S1, 1),
1002    (T2, C2, S2, 2),
1003    (T3, C3, S3, 3),
1004    (T4, C4, S4, 4),
1005    (T5, C5, S5, 5),
1006    (T6, C6, S6, 6),
1007    (T7, C7, S7, 7),
1008    (T8, C8, S8, 8),
1009    (T9, C9, S9, 9),
1010    (T10, C10, S10, 10),
1011    (T11, C11, S11, 11),
1012    (T12, C12, S12, 12),
1013    (T13, C13, S13, 13),
1014    (T14, C14, S14, 14),
1015    (T15, C15, S15, 15),
1016    (T16, C16, S16, 16),
1017    (T17, C17, S17, 17)
1018);
1019impl_tuple_codec!(
1020    Tuple19Codec,
1021    Tuple19Serializer,
1022    (T0, C0, S0, 0),
1023    (T1, C1, S1, 1),
1024    (T2, C2, S2, 2),
1025    (T3, C3, S3, 3),
1026    (T4, C4, S4, 4),
1027    (T5, C5, S5, 5),
1028    (T6, C6, S6, 6),
1029    (T7, C7, S7, 7),
1030    (T8, C8, S8, 8),
1031    (T9, C9, S9, 9),
1032    (T10, C10, S10, 10),
1033    (T11, C11, S11, 11),
1034    (T12, C12, S12, 12),
1035    (T13, C13, S13, 13),
1036    (T14, C14, S14, 14),
1037    (T15, C15, S15, 15),
1038    (T16, C16, S16, 16),
1039    (T17, C17, S17, 17),
1040    (T18, C18, S18, 18)
1041);
1042impl_tuple_codec!(
1043    Tuple20Codec,
1044    Tuple20Serializer,
1045    (T0, C0, S0, 0),
1046    (T1, C1, S1, 1),
1047    (T2, C2, S2, 2),
1048    (T3, C3, S3, 3),
1049    (T4, C4, S4, 4),
1050    (T5, C5, S5, 5),
1051    (T6, C6, S6, 6),
1052    (T7, C7, S7, 7),
1053    (T8, C8, S8, 8),
1054    (T9, C9, S9, 9),
1055    (T10, C10, S10, 10),
1056    (T11, C11, S11, 11),
1057    (T12, C12, S12, 12),
1058    (T13, C13, S13, 13),
1059    (T14, C14, S14, 14),
1060    (T15, C15, S15, 15),
1061    (T16, C16, S16, 16),
1062    (T17, C17, S17, 17),
1063    (T18, C18, S18, 18),
1064    (T19, C19, S19, 19)
1065);
1066impl_tuple_codec!(
1067    Tuple21Codec,
1068    Tuple21Serializer,
1069    (T0, C0, S0, 0),
1070    (T1, C1, S1, 1),
1071    (T2, C2, S2, 2),
1072    (T3, C3, S3, 3),
1073    (T4, C4, S4, 4),
1074    (T5, C5, S5, 5),
1075    (T6, C6, S6, 6),
1076    (T7, C7, S7, 7),
1077    (T8, C8, S8, 8),
1078    (T9, C9, S9, 9),
1079    (T10, C10, S10, 10),
1080    (T11, C11, S11, 11),
1081    (T12, C12, S12, 12),
1082    (T13, C13, S13, 13),
1083    (T14, C14, S14, 14),
1084    (T15, C15, S15, 15),
1085    (T16, C16, S16, 16),
1086    (T17, C17, S17, 17),
1087    (T18, C18, S18, 18),
1088    (T19, C19, S19, 19),
1089    (T20, C20, S20, 20)
1090);
1091impl_tuple_codec!(
1092    Tuple22Codec,
1093    Tuple22Serializer,
1094    (T0, C0, S0, 0),
1095    (T1, C1, S1, 1),
1096    (T2, C2, S2, 2),
1097    (T3, C3, S3, 3),
1098    (T4, C4, S4, 4),
1099    (T5, C5, S5, 5),
1100    (T6, C6, S6, 6),
1101    (T7, C7, S7, 7),
1102    (T8, C8, S8, 8),
1103    (T9, C9, S9, 9),
1104    (T10, C10, S10, 10),
1105    (T11, C11, S11, 11),
1106    (T12, C12, S12, 12),
1107    (T13, C13, S13, 13),
1108    (T14, C14, S14, 14),
1109    (T15, C15, S15, 15),
1110    (T16, C16, S16, 16),
1111    (T17, C17, S17, 17),
1112    (T18, C18, S18, 18),
1113    (T19, C19, S19, 19),
1114    (T20, C20, S20, 20),
1115    (T21, C21, S21, 21)
1116);