musli_core/impls/
tuples.rs

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
135
136
137
138
139
140
141
142
//! Implementations for variously lengthed tuples.

use crate::de::{Decode, DecodePacked, Decoder, SequenceDecoder};
use crate::en::{Encode, EncodePacked, Encoder, SequenceEncoder};
use crate::hint::SequenceHint;

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
            $ty0: Encode<M>,
            $($ty: Encode<M>),*
        {
            #[inline]
            fn encode<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
            where
                E: Encoder<Mode = M>,
            {
                static HINT: SequenceHint = SequenceHint::with_size(count!($ident0 $($ident)*));

                encoder.encode_sequence_fn(&HINT, |tuple| {
                    let ($ident0, $($ident),*) = self;
                    tuple.encode_next()?.encode($ident0)?;
                    $(tuple.encode_next()?.encode($ident)?;)*
                    Ok(())
                })
            }
        }

        impl<'de, M, $ty0, $($ty,)*> Decode<'de, M> for ($ty0, $($ty),*)
        where
            $ty0: Decode<'de, M>,
            $($ty: Decode<'de, M>),*
        {
            #[inline]
            fn decode<D>(_: &D::Cx, decoder: D) -> Result<Self, D::Error>
            where
                D: Decoder<'de, Mode = M>,
            {
                static HINT: SequenceHint = SequenceHint::with_size(count!($ident0 $($ident)*));

                decoder.decode_sequence_hint(&HINT, |tuple| {
                    let $ident0 = tuple.next()?;
                    $(let $ident = tuple.next()?;)*
                    Ok(($ident0, $($ident),*))
                })
            }
        }

        impl<M, $ty0 $(,$ty)*> EncodePacked<M> for ($ty0, $($ty),*)
        where
            $ty0: Encode<M>,
            $($ty: Encode<M>),*
        {
            #[inline]
            fn encode_packed<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
            where
                E: Encoder<Mode = M>,
            {
                let ($ident0, $($ident),*) = self;
                encoder.encode_pack_fn(|pack| {
                    pack.encode_next()?.encode($ident0)?;
                    $(pack.encode_next()?.encode($ident)?;)*
                    Ok(())
                })
            }
        }

        impl<'de, M, $ty0, $($ty,)*> DecodePacked<'de, M> for ($ty0, $($ty),*)
        where
            $ty0: Decode<'de, M>,
            $($ty: Decode<'de, M>),*
        {
            #[inline]
            fn decode_packed<D>(_: &D::Cx, decoder: D) -> Result<Self, D::Error>
            where
                D: Decoder<'de, Mode = M>,
            {
                decoder.decode_pack(|pack| {
                    let $ident0 = pack.next()?;
                    $(let $ident = pack.next()?;)*
                    Ok(($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),
}