1use primitive_types::{H160, U256};
2
3use super::{
4 AbiDecode, AbiDecodeZero, AbiDecoder, AbiEncode, AbiEncodeZero, AbiEncoder, ABI_WORD_SIZE,
5};
6use crate::{
7 abi::{traits::AbiType, Error, Result},
8 custom_signature::SignatureUnit,
9 make_signature,
10 types::*,
11};
12
13impl<T: AbiType> AbiType for Vec<T> {
14 const SIGNATURE: SignatureUnit = make_signature!(new nameof(T::SIGNATURE) fixed("[]"));
15 const HEAD_WORDS: u32 = 1;
16 const IS_DYNAMIC: bool = true;
17}
18impl<T: AbiEncode> AbiEncode for Vec<T> {
19 fn enc(&self, out: &mut AbiEncoder) {
20 (self.len() as u32).enc(out);
21 if T::IS_DYNAMIC {
22 out.reserve_head(self.len() as u32);
23 for v in self {
24 (self.len() as u32 * ABI_WORD_SIZE + out.tail_size()).enc(out);
25 out.encode_tail(v);
26 }
27 } else {
28 for v in self {
29 out.encode_tail(v);
30 }
31 }
32 }
33}
34impl<T: AbiDecode> AbiDecode for Vec<T> {
35 fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
36 let len = u32::dec(input)?;
37 let mut out = Vec::new();
39 let mut input = input.start_frame();
40 if T::IS_DYNAMIC {
41 for _ in 0..len {
42 let offset = u32::dec(&mut input)?;
43 out.push(T::dec(&mut input.dynamic_at(offset)?)?)
44 }
45 } else {
46 for _ in 0..len {
47 out.push(T::dec(&mut input)?)
48 }
49 }
50 Ok(out)
51 }
52}
53
54impl<T: AbiType, const S: usize> AbiType for [T; S] {
55 const SIGNATURE: SignatureUnit =
56 make_signature!(new nameof(T::SIGNATURE) fixed("[") numof(S) fixed("]"));
57 const HEAD_WORDS: u32 = if T::IS_DYNAMIC {
58 S as u32
59 } else {
60 T::HEAD_WORDS * S as u32
61 };
62 const IS_DYNAMIC: bool = T::IS_DYNAMIC;
63}
64impl<T: AbiEncode, const S: usize> AbiEncode for [T; S] {
65 fn enc(&self, out: &mut AbiEncoder) {
66 if T::IS_DYNAMIC {
67 for v in self {
68 (Self::HEAD_WORDS * self.len() as u32 + out.tail_size()).enc(out);
69 out.encode_tail(v);
70 }
71 } else {
72 for v in self {
73 v.enc(out)
74 }
75 }
76 }
77}
78impl<T: AbiDecode, const S: usize> AbiDecode for [T; S] {
79 fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
80 let mut out = Vec::with_capacity(S);
81 if T::IS_DYNAMIC {
82 for _ in 0..S {
83 let offset = u32::dec(input)?;
84 let mut data = input.dynamic_at(offset)?;
85 out.push(T::dec(&mut data)?);
86 }
87 } else {
88 for _ in 0..S {
89 out.push(T::dec(input)?);
90 }
91 }
92 out.try_into().map_err(|_| Error::InvalidRange)
93 }
94}
95
96impl AbiType for &str {
97 const SIGNATURE: SignatureUnit = make_signature!(new fixed("string"));
98 const HEAD_WORDS: u32 = 1;
99 const IS_DYNAMIC: bool = true;
100}
101impl AbiEncode for &str {
102 fn enc(&self, out: &mut AbiEncoder) {
103 (self.len() as u32).enc(out);
104 for ele in self.as_bytes().chunks(32) {
105 let mut word = [0; ABI_WORD_SIZE as usize];
106 word[0..ele.len()].copy_from_slice(ele);
107 out.append_tail(word);
108 }
109 }
110}
111
112impl AbiType for String {
113 const SIGNATURE: SignatureUnit = <&str>::SIGNATURE;
114 const HEAD_WORDS: u32 = <&str>::HEAD_WORDS;
115 const IS_DYNAMIC: bool = <&str>::IS_DYNAMIC;
116}
117impl AbiEncode for String {
118 fn enc(&self, out: &mut AbiEncoder) {
119 self.as_str().enc(out)
120 }
121}
122impl AbiDecode for String {
123 fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
124 let bytes = Bytes::dec(input)?;
125 String::from_utf8(bytes.0).map_err(|_| Error::InvalidRange)
126 }
127}
128
129impl AbiType for Bytes {
130 const SIGNATURE: SignatureUnit = make_signature!(new fixed("bytes"));
131 const HEAD_WORDS: u32 = 1;
132 const IS_DYNAMIC: bool = true;
133}
134impl AbiEncode for Bytes {
135 fn enc(&self, out: &mut AbiEncoder) {
136 (self.len() as u32).enc(out);
137 for ele in self.0.chunks(32) {
138 let mut word = [0; ABI_WORD_SIZE as usize];
139 word[0..ele.len()].copy_from_slice(ele);
140 out.append_tail(word);
141 }
142 }
143}
144impl AbiDecode for Bytes {
145 fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
146 let len = u32::dec(input)?;
147 let mut out = Vec::new();
149 let full_words = len / 32;
151 for _ in 0..full_words {
152 let word = input.get_head()?;
153 out.extend_from_slice(&word);
154 }
155 let leftovers = len % 32;
156 if leftovers != 0 {
157 let word = input.get_head()?;
158 out.extend_from_slice(&word[..leftovers as usize]);
159 for i in leftovers..32 {
160 if word[i as usize] != 0 {
161 return Err(Error::InvalidRange);
162 }
163 }
164 }
165 Ok(Self(out))
166 }
167}
168
169impl<const S: usize> AbiType for BytesFixed<S> {
170 const SIGNATURE: SignatureUnit = make_signature!(new fixed("bytes") numof(S));
171 const HEAD_WORDS: u32 = (S as u32 + 31) & !31;
173 const IS_DYNAMIC: bool = false;
174}
175impl<const S: usize> AbiEncode for BytesFixed<S> {
176 fn enc(&self, out: &mut AbiEncoder) {
177 for ele in self.0.chunks(32) {
178 let mut word = [0; ABI_WORD_SIZE as usize];
179 word[0..ele.len()].copy_from_slice(ele);
180 out.append_tail(word);
181 }
182 }
183}
184impl<const S: usize> AbiDecode for BytesFixed<S> {
185 fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
186 let mut out = Vec::new();
188 let full_words = S / 32;
190 for _ in 0..full_words {
191 let word = input.get_head()?;
192 out.extend_from_slice(&word);
193 }
194 let leftovers = S % 32;
195 if leftovers != 0 {
196 let word = input.get_head()?;
197 out.extend_from_slice(&word[..leftovers]);
198 if word[leftovers..ABI_WORD_SIZE as usize]
199 .iter()
200 .any(|&v| v != 0)
201 {
202 return Err(Error::InvalidRange);
203 }
204 }
205 out.try_into().map(Self).map_err(|_| Error::InvalidRange)
206 }
207}
208
209impl AbiType for () {
210 const SIGNATURE: SignatureUnit = make_signature!(new fixed("()"));
211 const HEAD_WORDS: u32 = 0;
212 const IS_DYNAMIC: bool = false;
213}
214impl AbiEncode for () {
215 fn enc(&self, _out: &mut AbiEncoder) {}
216}
217impl AbiDecode for () {
218 fn dec(_input: &mut AbiDecoder<'_>) -> Result<Self> {
219 Ok(())
220 }
221}
222
223const fn tuple_comp_head_words<T: AbiType>() -> u32 {
224 if T::IS_DYNAMIC {
225 1
226 } else {
227 T::HEAD_WORDS
228 }
229}
230fn encode_tuple_comp<T: AbiEncode>(comp: &T, total_head: u32, out: &mut AbiEncoder) {
231 if T::IS_DYNAMIC {
232 let head = total_head * ABI_WORD_SIZE + out.tail_size();
233 head.enc(out);
234 out.encode_tail(comp);
235 } else {
236 comp.enc(out);
237 }
238}
239fn decode_tuple_comp<T: AbiDecode>(input: &mut AbiDecoder) -> Result<T> {
240 if T::IS_DYNAMIC {
241 let head = u32::dec(input)?;
242 let mut dynamic = input.dynamic_at(head)?;
243 T::dec(&mut dynamic)
244 } else {
245 T::dec(input)
246 }
247}
248macro_rules! impl_tuples {
249 ($($gen:ident)+) => {
250 impl<$($gen: AbiType,)*> AbiType for ($($gen,)*)
251 where $(
252 $gen: AbiType,
253 )*
254 {
255 const SIGNATURE: SignatureUnit = make_signature!(
256 new fixed("(")
257 $(nameof(<$gen>::SIGNATURE) fixed(","))+
258 shift_left(1)
259 fixed(")")
260 );
261 const HEAD_WORDS: u32 = 0 $(+ tuple_comp_head_words::<$gen>())*;
262 const IS_DYNAMIC: bool = false $(|| $gen::IS_DYNAMIC)*;
263 }
264
265 #[allow(non_snake_case)]
266 impl<$($gen: AbiEncode,)*> AbiEncode for ($($gen,)*) {
267 #[allow(unused_variables)]
268 fn enc(&self, out: &mut AbiEncoder) {
269 #[allow(non_snake_case)]
270 let ($($gen,)*) = self;
271 $(encode_tuple_comp($gen, Self::HEAD_WORDS, out);)*
272 }
273 }
274
275 #[allow(non_snake_case)]
276 impl<$($gen: AbiDecode,)*> AbiDecode for ($($gen,)*) {
277 fn dec(input: &mut AbiDecoder) -> Result<($($gen,)*)> {
278 Ok((
279 $({
280 #[allow(unused_variables)]
281 let $gen = 0;
282 decode_tuple_comp::<$gen>(input)?
283 },)*
284 ))
285 }
286 }
287 };
288 ($($cur:ident)* @ $c:ident $($rest:ident)*) => {
289 impl_tuples!($($cur)*);
290 impl_tuples!($($cur)* $c @ $($rest)*);
291 };
292 ($($cur:ident)* @) => {
293 impl_tuples!($($cur)*);
294 };
295}
296impl_tuples!(A @ B C D E F G H I J K L M N O P);
297
298impl<T: AbiType> AbiType for Option<T> {
300 const SIGNATURE: SignatureUnit = <(bool, T)>::SIGNATURE;
301 const HEAD_WORDS: u32 = <(bool, T)>::HEAD_WORDS;
302 const IS_DYNAMIC: bool = <(bool, T)>::IS_DYNAMIC;
303}
304impl<T: AbiEncode + AbiEncodeZero> AbiEncode for Option<T> {
305 fn enc(&self, out: &mut AbiEncoder) {
306 match self {
307 Some(v) => (true, v).enc(out),
308 None => (false, <Zero<T>>::new()).enc(out),
309 }
310 }
311}
312impl<T: AbiDecode + AbiDecodeZero> AbiDecode for Option<T> {
313 fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
314 let has_value = bool::dec(input)?;
315 if T::IS_DYNAMIC {
316 let off = u32::dec(input)?;
317 let mut input = input.dynamic_at(off)?;
318 if has_value {
319 Some(T::dec(&mut input)).transpose()
320 } else {
321 <Zero<T>>::dec(&mut input)?;
322 Ok(None)
323 }
324 } else if has_value {
325 Some(T::dec(input)).transpose()
326 } else {
327 <Zero<T>>::dec(input)?;
328 Ok(None)
329 }
330 }
331}
332
333impl<T: AbiType> AbiType for Zero<T> {
334 const SIGNATURE: SignatureUnit = T::SIGNATURE;
335 const HEAD_WORDS: u32 = T::HEAD_WORDS;
336 const IS_DYNAMIC: bool = T::IS_DYNAMIC;
337}
338impl<T: AbiEncodeZero> AbiEncode for Zero<T> {
339 fn enc(&self, out: &mut AbiEncoder) {
340 T::enc_zero(out)
341 }
342}
343impl<T: AbiDecodeZero> AbiDecode for Zero<T> {
344 fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
345 T::dec_zero(input)?;
346 Ok(Self::new())
347 }
348}
349
350macro_rules! impl_num_abicode {
351 ($pref:literal $($t:ty)*) => {$(
352 impl AbiType for $t {
353 const SIGNATURE: SignatureUnit = make_signature!(new fixed($pref) numof(<$t>::BITS));
354 const IS_DYNAMIC: bool = false;
355 const HEAD_WORDS: u32 = 1;
356 }
357 impl AbiEncode for $t {
358 fn enc(&self, out: &mut AbiEncoder) {
361 let bytes = self.to_be_bytes();
362 let mut word = [0; ABI_WORD_SIZE as usize];
363 word[ABI_WORD_SIZE as usize - bytes.len()..ABI_WORD_SIZE as usize].copy_from_slice(&bytes);
364 out.append_head(word);
365 }
366 }
367 impl AbiDecode for $t {
368 fn dec(input: &mut AbiDecoder) -> Result<$t> {
369 let head = input.get_head()?;
370 let mut bytes = [0; <$t>::BITS as usize / 8];
371 let offset = 32-(<$t>::BITS as usize / 8);
372 for i in 0..offset {
373 if head[i] != 0 {
374 return Err(Error::InvalidRange);
375 }
376 }
377 bytes.copy_from_slice(&head[offset..32]);
378 Ok(<$t>::from_be_bytes(bytes))
379 }
380 }
381 )*};
382}
383impl_num_abicode!("uint" u8 u16 u32 u64 u128);
384impl_num_abicode!("int" i8 i16 i32 i64 i128);
385
386impl AbiType for bool {
387 const SIGNATURE: SignatureUnit = make_signature!(new fixed("bool"));
388 const IS_DYNAMIC: bool = false;
389 const HEAD_WORDS: u32 = 1;
390}
391impl AbiEncode for bool {
392 fn enc(&self, out: &mut AbiEncoder) {
393 (*self as u32).enc(out)
394 }
395}
396impl AbiDecode for bool {
397 fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
398 let v = u32::dec(input)?;
399 Ok(match v {
400 0 => false,
401 1 => true,
402 _ => return Err(Error::InvalidRange),
403 })
404 }
405}
406impl AbiType for H160 {
407 const SIGNATURE: SignatureUnit = make_signature!(new fixed("address"));
408 const HEAD_WORDS: u32 = 1;
409 const IS_DYNAMIC: bool = false;
410}
411impl AbiEncode for H160 {
412 fn enc(&self, out: &mut AbiEncoder) {
413 let mut word = [0; ABI_WORD_SIZE as usize];
414 word[12..].copy_from_slice(&self.0);
415 out.append_head(word)
416 }
417}
418impl AbiDecode for H160 {
419 fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
420 let data = input.get_head()?;
421 let mut out = [0; 20];
422 out.copy_from_slice(&data[12..]);
423 if data[0..12].iter().any(|&b| b != 0) {
424 return Err(Error::InvalidRange);
425 }
426 Ok(H160(out))
427 }
428}
429
430impl AbiType for U256 {
431 const SIGNATURE: SignatureUnit = make_signature!(new fixed("uint256"));
432 const HEAD_WORDS: u32 = 1;
433 const IS_DYNAMIC: bool = false;
434}
435impl AbiEncode for U256 {
436 fn enc(&self, out: &mut AbiEncoder) {
437 let mut word = [0; ABI_WORD_SIZE as usize];
438 self.to_big_endian(&mut word);
439 out.append_head(word)
440 }
441}
442impl AbiDecode for U256 {
443 fn dec(input: &mut AbiDecoder<'_>) -> Result<Self> {
444 let word = input.get_head()?;
445 Ok(U256::from_big_endian(&word))
446 }
447}