solid_core/
tuples.rs

1use crate::{
2    decode::Decode,
3    encode::Encode,
4    into_type::IntoType,
5};
6use std::borrow::Cow;
7
8macro_rules! impl_encode_and_into_types_for_tuples {
9	  ($(($index:tt => $ident:ident) ),+) => {
10        #[allow(unused)]
11        impl<$($ident: Encode, )+> Encode for ($($ident, )+) {
12            fn encode(&self) -> Vec<u8> {
13                let len = self.required_len();
14
15                let mut buf: Vec<u8> = vec![0; len as usize];
16
17                let mut count = 0usize;
18
19                $(
20                    count += if $ident::is_dynamic() { 1 } else { 1 };
21                )+
22
23                let mut offset: usize = count * 32;
24
25                let mut index = 0;
26
27                $(
28                    let bytes = self.$index.encode();
29
30                    if $ident::is_dynamic() {
31                        buf[index * 32 + 24..(index + 1) * 32]
32                            .copy_from_slice(&(offset as u64).to_be_bytes());
33                        buf[offset..offset + bytes.len()]
34                            .copy_from_slice(&bytes);
35                        offset += bytes.len()
36                    } else {
37                        buf[index * 32..(index + 1) * 32]
38                            .copy_from_slice(&bytes);
39                    }
40
41                    index += 1;
42                )+
43
44                buf
45            }
46
47            fn required_len(&self) -> u64 {
48                let mut len = 0u64;
49
50                $(
51                    len += self.$index.required_len();
52                    len += if $ident::is_dynamic() {
53                        32
54                    } else {
55                        0
56                    };
57                )+
58
59                len
60            }
61
62            fn is_dynamic() -> bool {
63                true
64            }
65        }
66
67        impl<$($ident: IntoType, )+> IntoType for ($($ident,) +) {
68            fn into_type() -> Cow<'static, str> {
69                let mut ty = Vec::new();
70                $(
71                    ty.push($ident::into_type());
72                )+
73
74                Cow::Owned(format!("({})", ty.join(",")))
75            }
76        }
77
78        #[allow(unused)]
79        impl<'a, $($ident: Encode + Decode<'a>, )+> Decode<'a> for ($($ident,) +)
80        {
81            fn decode(buf: &'a [u8]) -> Self {
82                let mut index = 0;
83
84
85                (
86                    $(
87                        {
88                            let value = if $ident::is_dynamic() {
89                                $ident::decode(&buf[index * 32..(index + 1) * 32])
90                            } else {
91                                let offset = u64::decode(&buf[index * 32..(index + 1) * 32]);
92                                $ident::decode(&buf[offset as usize..])
93                            };
94                            index += 1;
95                            value
96                        },
97                    )+
98                )
99            }
100        }
101	  };
102}
103
104impl_encode_and_into_types_for_tuples!(
105    (0 => T0),
106    (1 => T1)
107);
108impl_encode_and_into_types_for_tuples!(
109    (0 => T0),
110    (1 => T1),
111    (2 => T2)
112);
113
114impl_encode_and_into_types_for_tuples!(
115    (0 => T0),
116    (1 => T1),
117    (2 => T2),
118    (3 => T3)
119);
120
121impl_encode_and_into_types_for_tuples!(
122    (0 => T0),
123    (1 => T1),
124    (2 => T2),
125    (3 => T3),
126    (4 => T4)
127);
128
129impl_encode_and_into_types_for_tuples!(
130    (0 => T0),
131    (1 => T1),
132    (2 => T2),
133    (3 => T3),
134    (4 => T4),
135    (5 => T5)
136);
137
138impl_encode_and_into_types_for_tuples!(
139    (0 => T0),
140    (1 => T1),
141    (2 => T2),
142    (3 => T3),
143    (4 => T4),
144    (5 => T5),
145    (6 => T6)
146);