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            #[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            // Debug builds must not inline recursively nested tuple readers
464            // into one generated compatible-struct frame; complex schemas can
465            // otherwise exhaust the test thread's stack.
466            #[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            // This is the field-only counterpart to `Serializer::read_data`.
513            // It consumes the remote tuple field schema without leaking
514            // `FieldType` into value-level serializer composition.
515            #[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                // Tuple positions carry their own type metadata in compatible and
543                // xlang bodies. LIST metadata has one homogeneous generic slot, so
544                // declaring position codecs here would truncate the schema on wire.
545                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);