musli_core/impls/
tuples.rs

1//! Implementations for variously lengthed tuples.
2
3use crate::Allocator;
4use crate::de::{Decode, DecodePacked, Decoder, SequenceDecoder};
5use crate::en::{Encode, EncodePacked, Encoder, SequenceEncoder};
6
7macro_rules! count {
8    (_) => { 1 };
9    (_ _) => { 2 };
10    (_ _ _) => { 3 };
11    (_ _ _ _) => { 4 };
12    (_ _ _ _ _) => { 5 };
13    (_ _ _ _ _ _) => { 6 };
14    (_ _ _ _ _ _ _) => { 7 };
15    (_ _ _ _ _ _ _ _) => { 8 };
16    (_ _ _ _ _ _ _ _ _) => { 9 };
17    (_ _ _ _ _ _ _ _ _ _) => { 10 };
18    (_ _ _ _ _ _ _ _ _ _ _) => { 11 };
19    (_ _ _ _ _ _ _ _ _ _ _ _) => { 12 };
20    (_ _ _ _ _ _ _ _ _ _ _ _ _) => { 13 };
21    (_ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 14 };
22    (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 15 };
23    (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 16 };
24
25    (( $($s:tt)* ) $_:ident $($tail:tt)*) => {
26        count!(( $($s)* _ ) $($tail)*)
27    };
28
29    (( $($s:tt)* )) => {
30        count!( $($s)* )
31    };
32
33    ($($ident:ident)*) => {
34        count!(() $($ident)*)
35    };
36}
37
38macro_rules! declare {
39    () => {
40    };
41
42    (($ty0:ident, $ident0:ident) $(, ($ty:ident, $ident:ident))* $(,)?) => {
43        impl<M, $ty0 $(, $ty)*> Encode<M> for ($ty0, $($ty),*)
44        where
45            $ty0: Encode<M>,
46            $($ty: Encode<M>),*
47        {
48            // It is harder to check that a tuple is packed, because we have to
49            // ensure it doesn't contain any padding.
50            const IS_BITWISE_ENCODE: bool = false;
51
52            #[inline]
53            fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
54            where
55                E: Encoder<Mode = M>,
56            {
57                encoder.encode_sequence_fn(count!($ident0 $($ident)*), |tuple| {
58                    let ($ident0, $($ident),*) = self;
59                    tuple.encode_next()?.encode($ident0)?;
60                    $(tuple.encode_next()?.encode($ident)?;)*
61                    Ok(())
62                })
63            }
64
65            type Encode = Self;
66
67            #[inline]
68            fn as_encode(&self) -> &Self::Encode {
69                self
70            }
71        }
72
73        impl<'de, M, A, $ty0, $($ty,)*> Decode<'de, M, A> for ($ty0, $($ty),*)
74        where
75            A: Allocator,
76            $ty0: Decode<'de, M, A>,
77            $($ty: Decode<'de, M, A>),*
78        {
79            // It is harder to check that a tuple is packed, because we have to
80            // ensure it doesn't contain any padding.
81            const IS_BITWISE_DECODE: bool = false;
82
83            #[inline]
84            fn decode<D>(decoder: D) -> Result<Self, D::Error>
85            where
86                D: Decoder<'de, Mode = M, Allocator = A>,
87            {
88                decoder.decode_sequence_hint(count!($ident0 $($ident)*), |tuple| {
89                    let $ident0 = tuple.next()?;
90                    $(let $ident = tuple.next()?;)*
91                    Ok(($ident0, $($ident),*))
92                })
93            }
94        }
95
96        impl<M, $ty0 $(,$ty)*> EncodePacked<M> for ($ty0, $($ty),*)
97        where
98            $ty0: Encode<M>,
99            $($ty: Encode<M>),*
100        {
101            #[inline]
102            fn encode_packed<E>(&self, encoder: E) -> Result<(), E::Error>
103            where
104                E: Encoder<Mode = M>,
105            {
106                let ($ident0, $($ident),*) = self;
107                encoder.encode_pack_fn(|pack| {
108                    pack.encode_next()?.encode($ident0)?;
109                    $(pack.encode_next()?.encode($ident)?;)*
110                    Ok(())
111                })
112            }
113        }
114
115        impl<'de, M, A, $ty0, $($ty,)*> DecodePacked<'de, M, A> for ($ty0, $($ty),*)
116        where
117            A: Allocator,
118            $ty0: Decode<'de, M, A>,
119            $($ty: Decode<'de, M, A>),*
120        {
121            #[inline]
122            fn decode_packed<D>(decoder: D) -> Result<Self, D::Error>
123            where
124                D: Decoder<'de, Mode = M, Allocator = A>,
125            {
126                decoder.decode_pack(|pack| {
127                    let $ident0 = pack.next()?;
128                    $(let $ident = pack.next()?;)*
129                    Ok(($ident0, $($ident),*))
130                })
131            }
132        }
133
134        declare!($(($ty, $ident)),*);
135    };
136}
137
138declare! {
139    (T0, t0),
140    (T1, t1),
141    (T2, t2),
142    (T3, t3),
143    (T4, t4),
144    (T5, t5),
145    (T6, t6),
146    (T7, t7),
147    (T8, t8),
148    (T9, t9),
149    (T10, t10),
150    (T11, t11),
151    (T12, t12),
152    (T13, t13),
153    (T14, t14),
154    (T15, t15),
155}