1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! Implementations for variously lengthed tuples.

use crate::compat::Packed;
use crate::de::{Decode, Decoder, PackDecoder};
use crate::en::{Encode, Encoder, SequenceEncoder};
use crate::mode::Mode;
use crate::Context;

macro_rules! count {
    (_) => { 1 };
    (_ _) => { 2 };
    (_ _ _) => { 3 };
    (_ _ _ _) => { 4 };
    (_ _ _ _ _) => { 5 };
    (_ _ _ _ _ _) => { 6 };
    (_ _ _ _ _ _ _) => { 7 };
    (_ _ _ _ _ _ _ _) => { 8 };
    (_ _ _ _ _ _ _ _ _) => { 9 };
    (_ _ _ _ _ _ _ _ _ _) => { 10 };
    (_ _ _ _ _ _ _ _ _ _ _) => { 11 };
    (_ _ _ _ _ _ _ _ _ _ _ _) => { 12 };
    (_ _ _ _ _ _ _ _ _ _ _ _ _) => { 13 };
    (_ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 14 };
    (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 15 };
    (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 16 };

    (( $($s:tt)* ) $_:ident $($tail:tt)*) => {
        count!(( $($s)* _ ) $($tail)*)
    };

    (( $($s:tt)* )) => {
        count!( $($s)* )
    };

    ($($ident:ident)*) => {
        count!(() $($ident)*)
    };
}

macro_rules! declare {
    () => {
    };

    (($ty0:ident, $ident0:ident) $(, ($ty:ident, $ident:ident))* $(,)?) => {
        impl<M, $ty0 $(, $ty)*> Encode<M> for ($ty0, $($ty),*) where M: Mode, $ty0: Encode<M>, $($ty: Encode<M>),* {
            #[inline]
            fn encode<C, E>(&self, cx: &mut C, encoder: E) -> Result<E::Ok, C::Error>
            where
                C: Context<Input = E::Error>,
                E: Encoder,
            {
                let mut pack = encoder.encode_tuple(cx, count!($ident0 $($ident)*))?;
                let ($ident0, $($ident),*) = self;
                let value = pack.next(cx)?;
                <$ty0>::encode($ident0, cx, value)?;
                $(
                    let value = pack.next(cx)?;
                    <$ty>::encode($ident, cx, value)?;
                )*
                pack.end(cx)
            }
        }

        impl<'de, M, $ty0, $($ty,)*> Decode<'de, M> for ($ty0, $($ty),*) where M: Mode, $ty0: Decode<'de, M>, $($ty: Decode<'de, M>),* {
            #[inline]
            fn decode<C, D>(cx: &mut C, decoder: D) -> Result<Self, C::Error>
            where
                C: Context<Input = D::Error>,
                D: Decoder<'de>
            {
                let mut unpack = decoder.decode_tuple(cx, count!($ident0 $($ident)*))?;
                let $ident0 = unpack.next(cx).and_then(|v| <$ty0>::decode(cx, v))?;
                $(let $ident = unpack.next(cx).and_then(|v| <$ty>::decode(cx, v))?;)*
                unpack.end(cx)?;
                Ok(($ident0, $($ident),*))
            }
        }

        impl<M, $ty0 $(,$ty)*> Encode<M> for Packed<($ty0, $($ty),*)> where M: Mode, $ty0: Encode<M>, $($ty: Encode<M>),* {
            #[inline]
            fn encode<C, E>(&self, cx: &mut C, encoder: E) -> Result<E::Ok, C::Error>
            where
                C: Context<Input = E::Error>,
                E: Encoder,
            {
                let Packed(($ident0, $($ident),*)) = self;
                let mut pack = encoder.encode_pack(cx)?;
                let value = pack.next(cx)?;
                <$ty0>::encode($ident0, cx, value)?;
                $(
                    let value = pack.next(cx)?;
                    <$ty>::encode($ident, cx, value)?;
                )*
                pack.end(cx)
            }
        }

        impl<'de, M, $ty0, $($ty,)*> Decode<'de, M> for Packed<($ty0, $($ty),*)> where M: Mode, $ty0: Decode<'de, M>, $($ty: Decode<'de, M>),* {
            #[inline]
            fn decode<C, D>(cx: &mut C, decoder: D) -> Result<Self, C::Error>
            where
                C: Context<Input = D::Error>,
                D: Decoder<'de>
            {
                let mut unpack = decoder.decode_pack(cx)?;
                let $ident0 = unpack.next(cx).and_then(|v| <$ty0>::decode(cx, v))?;
                $(let $ident = unpack.next(cx).and_then(|v| <$ty>::decode(cx, v))?;)*
                unpack.end(cx)?;
                Ok(Packed(($ident0, $($ident),*)))
            }
        }

        declare!($(($ty, $ident)),*);
    };
}

declare! {
    (T0, t0),
    (T1, t1),
    (T2, t2),
    (T3, t3),
    (T4, t4),
    (T5, t5),
    (T6, t6),
    (T7, t7),
    (T8, t8),
    (T9, t9),
    (T10, t10),
    (T11, t11),
    (T12, t12),
    (T13, t13),
    (T14, t14),
    (T15, t15),
}