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