tycho_types/abi/
traits.rs

1use std::collections::{BTreeMap, HashMap};
2use std::hash::{BuildHasher, Hash};
3use std::num::NonZeroU8;
4use std::rc::Rc;
5use std::sync::Arc;
6
7use anyhow::Result;
8use bytes::Bytes;
9use num_bigint::{BigInt, BigUint};
10use num_traits::ToPrimitive;
11
12use super::{
13    AbiType, AbiValue, NamedAbiType, NamedAbiValue, PlainAbiType, PlainAbiValue, WithoutName,
14};
15use crate::cell::{Cell, HashBytes, Lazy};
16use crate::models::message::{IntAddr, StdAddr, VarAddr};
17use crate::num::*;
18
19/// ABI entity wrapper.
20pub trait IgnoreName {
21    /// Wrapped ABI entity.
22    type Unnamed<'a>
23    where
24        Self: 'a;
25
26    /// Wraps an ABI entity into [`WithoutName`].
27    fn ignore_name(&self) -> Self::Unnamed<'_>;
28}
29
30impl<T: IgnoreName> IgnoreName for &'_ T {
31    type Unnamed<'a>
32        = T::Unnamed<'a>
33    where
34        Self: 'a;
35
36    #[inline]
37    fn ignore_name(&self) -> Self::Unnamed<'_> {
38        T::ignore_name(self)
39    }
40}
41
42impl<T> IgnoreName for Vec<T>
43where
44    [T]: IgnoreName,
45{
46    type Unnamed<'a>
47        = <[T] as IgnoreName>::Unnamed<'a>
48    where
49        Self: 'a;
50
51    #[inline]
52    fn ignore_name(&self) -> Self::Unnamed<'_> {
53        <[T] as IgnoreName>::ignore_name(self.as_slice())
54    }
55}
56
57impl<T: IgnoreName> IgnoreName for Box<T> {
58    type Unnamed<'a>
59        = T::Unnamed<'a>
60    where
61        Self: 'a;
62
63    #[inline]
64    fn ignore_name(&self) -> Self::Unnamed<'_> {
65        T::ignore_name(self.as_ref())
66    }
67}
68
69impl<T: IgnoreName> IgnoreName for Arc<T> {
70    type Unnamed<'a>
71        = T::Unnamed<'a>
72    where
73        Self: 'a;
74
75    #[inline]
76    fn ignore_name(&self) -> Self::Unnamed<'_> {
77        T::ignore_name(self.as_ref())
78    }
79}
80
81impl<T: IgnoreName> IgnoreName for Rc<T> {
82    type Unnamed<'a>
83        = T::Unnamed<'a>
84    where
85        Self: 'a;
86
87    #[inline]
88    fn ignore_name(&self) -> Self::Unnamed<'_> {
89        T::ignore_name(self.as_ref())
90    }
91}
92
93impl<T: IgnoreName> IgnoreName for Option<T> {
94    type Unnamed<'a>
95        = Option<T::Unnamed<'a>>
96    where
97        Self: 'a;
98
99    #[inline]
100    fn ignore_name(&self) -> Self::Unnamed<'_> {
101        self.as_ref().map(|t| T::ignore_name(t))
102    }
103}
104
105impl IgnoreName for AbiType {
106    type Unnamed<'a> = &'a WithoutName<AbiType>;
107
108    #[inline]
109    fn ignore_name(&self) -> Self::Unnamed<'_> {
110        WithoutName::wrap(self)
111    }
112}
113
114impl IgnoreName for [AbiType] {
115    type Unnamed<'a> = &'a [WithoutName<AbiType>];
116
117    #[inline]
118    fn ignore_name(&self) -> Self::Unnamed<'_> {
119        WithoutName::wrap_slice(self)
120    }
121}
122
123impl IgnoreName for NamedAbiType {
124    type Unnamed<'a> = &'a WithoutName<NamedAbiType>;
125
126    #[inline]
127    fn ignore_name(&self) -> Self::Unnamed<'_> {
128        WithoutName::wrap(self)
129    }
130}
131
132impl IgnoreName for [NamedAbiType] {
133    type Unnamed<'a> = &'a [WithoutName<NamedAbiType>];
134
135    #[inline]
136    fn ignore_name(&self) -> Self::Unnamed<'_> {
137        WithoutName::wrap_slice(self)
138    }
139}
140
141impl IgnoreName for AbiValue {
142    type Unnamed<'a> = &'a WithoutName<AbiValue>;
143
144    #[inline]
145    fn ignore_name(&self) -> Self::Unnamed<'_> {
146        WithoutName::wrap(self)
147    }
148}
149
150impl IgnoreName for [AbiValue] {
151    type Unnamed<'a> = &'a [WithoutName<AbiValue>];
152
153    #[inline]
154    fn ignore_name(&self) -> Self::Unnamed<'_> {
155        WithoutName::wrap_slice(self)
156    }
157}
158
159impl IgnoreName for NamedAbiValue {
160    type Unnamed<'a> = &'a WithoutName<NamedAbiValue>;
161
162    #[inline]
163    fn ignore_name(&self) -> Self::Unnamed<'_> {
164        WithoutName::wrap(self)
165    }
166}
167
168impl IgnoreName for [NamedAbiValue] {
169    type Unnamed<'a> = &'a [WithoutName<NamedAbiValue>];
170
171    #[inline]
172    fn ignore_name(&self) -> Self::Unnamed<'_> {
173        WithoutName::wrap_slice(self)
174    }
175}
176
177/// A type with a known ABI type.
178pub trait WithAbiType {
179    /// Returns a corresponding ABI type.
180    fn abi_type() -> AbiType;
181}
182
183macro_rules! impl_with_abi_type {
184    ($($ty:ty => $ident:ident$(($n:expr))?),*$(,)?) => {$(
185        impl WithAbiType for $ty {
186            fn abi_type() -> AbiType {
187                AbiType::$ident$(($n))?
188            }
189        }
190    )*};
191}
192
193impl_with_abi_type! {
194    u8 => Uint(8),
195    u16 => Uint(16),
196    u32 => Uint(32),
197    u64 => Uint(64),
198    u128 => Uint(128),
199    HashBytes => Uint(256),
200    SplitDepth => Uint(5),
201    Uint9 => Uint(9),
202    Uint12 => Uint(12),
203    Uint15 => Uint(15),
204
205    i8 => Int(8),
206    i16 => Int(16),
207    i32 => Int(32),
208    i64 => Int(64),
209    i128 => Int(128),
210
211    bool => Bool,
212
213    VarUint24 => VarUint(NonZeroU8::new(4).unwrap()),
214    VarUint56 => VarUint(NonZeroU8::new(8).unwrap()),
215    VarUint248 => VarUint(NonZeroU8::new(32).unwrap()),
216
217    Tokens => Token,
218
219    Cell => Cell,
220
221    Bytes => Bytes,
222    String => String,
223    str => String,
224
225    IntAddr => Address,
226    StdAddr => Address,
227    VarAddr => Address,
228}
229
230impl<T: WithAbiType> WithAbiType for &T {
231    fn abi_type() -> AbiType {
232        T::abi_type()
233    }
234}
235
236impl<T: WithAbiType> WithAbiType for &mut T {
237    fn abi_type() -> AbiType {
238        T::abi_type()
239    }
240}
241
242impl<T: WithAbiType> WithAbiType for Box<T> {
243    fn abi_type() -> AbiType {
244        T::abi_type()
245    }
246}
247
248impl<T: WithAbiType> WithAbiType for Arc<T> {
249    fn abi_type() -> AbiType {
250        T::abi_type()
251    }
252}
253
254impl<T: WithAbiType> WithAbiType for Rc<T> {
255    fn abi_type() -> AbiType {
256        T::abi_type()
257    }
258}
259
260impl<T: WithAbiType> WithAbiType for Option<T> {
261    fn abi_type() -> AbiType {
262        AbiType::Optional(Arc::new(T::abi_type()))
263    }
264}
265
266impl<T: WithAbiType> WithAbiType for Vec<T> {
267    fn abi_type() -> AbiType {
268        if typeid::of::<T>() == typeid::of::<u8>() {
269            AbiType::Bytes
270        } else {
271            AbiType::Array(Arc::new(T::abi_type()))
272        }
273    }
274}
275
276impl<T: WithAbiType> WithAbiType for [T] {
277    fn abi_type() -> AbiType {
278        if typeid::of::<T>() == typeid::of::<u8>() {
279            AbiType::Bytes
280        } else {
281            AbiType::Array(Arc::new(T::abi_type()))
282        }
283    }
284}
285
286impl<T: WithAbiType, const N: usize> WithAbiType for [T; N] {
287    fn abi_type() -> AbiType {
288        if typeid::of::<T>() == typeid::of::<u8>() {
289            AbiType::FixedBytes(N)
290        } else {
291            AbiType::FixedArray(Arc::new(T::abi_type()), N)
292        }
293    }
294}
295
296impl<K: WithPlainAbiType, V: WithAbiType> WithAbiType for BTreeMap<K, V> {
297    fn abi_type() -> AbiType {
298        AbiType::Map(K::plain_abi_type(), Arc::new(V::abi_type()))
299    }
300}
301
302impl<K: WithPlainAbiType, V: WithAbiType, S> WithAbiType for HashMap<K, V, S> {
303    fn abi_type() -> AbiType {
304        AbiType::Map(K::plain_abi_type(), Arc::new(V::abi_type()))
305    }
306}
307
308#[cfg(feature = "models")]
309impl<T: WithAbiType> WithAbiType for Lazy<T> {
310    fn abi_type() -> AbiType {
311        AbiType::Ref(Arc::new(T::abi_type()))
312    }
313}
314
315impl WithAbiType for () {
316    fn abi_type() -> AbiType {
317        AbiType::Tuple(Arc::from([].as_slice()))
318    }
319}
320
321macro_rules! impl_with_abi_type_for_tuple {
322    ($($i:literal: $t:ident),+$(,)?) => {
323        impl<$($t: WithAbiType),*> WithAbiType for ($($t),+,) {
324            fn abi_type() -> AbiType {
325                AbiType::Tuple(Arc::from(vec![
326                    $(NamedAbiType::from_index($i, <$t as WithAbiType>::abi_type())),*
327                ]))
328            }
329        }
330    };
331}
332
333impl_with_abi_type_for_tuple! { 0: T0 }
334impl_with_abi_type_for_tuple! { 0: T0, 1: T1 }
335impl_with_abi_type_for_tuple! { 0: T0, 1: T1, 2: T2 }
336impl_with_abi_type_for_tuple! { 0: T0, 1: T1, 2: T2, 3: T3 }
337impl_with_abi_type_for_tuple! { 0: T0, 1: T1, 2: T2, 3: T3, 4: T4 }
338impl_with_abi_type_for_tuple! { 0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5 }
339impl_with_abi_type_for_tuple! { 0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6 }
340
341/// A type with a known plain ABI type.
342pub trait WithPlainAbiType: WithAbiType {
343    /// Returns a corresponding plain ABI type.
344    fn plain_abi_type() -> PlainAbiType;
345}
346
347macro_rules! impl_with_plain_abi_type {
348    ($($ty:ty => $ident:ident$(($n:literal))?),*$(,)?) => {$(
349        impl WithPlainAbiType for $ty {
350            fn plain_abi_type() -> PlainAbiType {
351                PlainAbiType::$ident$(($n))?
352            }
353        }
354    )*};
355}
356
357impl_with_plain_abi_type! {
358    u8 => Uint(8),
359    u16 => Uint(16),
360    u32 => Uint(32),
361    u64 => Uint(64),
362    u128 => Uint(128),
363    HashBytes => Uint(256),
364    SplitDepth => Uint(5),
365    Uint9 => Uint(9),
366    Uint12 => Uint(12),
367    Uint15 => Uint(15),
368
369    i8 => Int(8),
370    i16 => Int(16),
371    i32 => Int(32),
372    i64 => Int(64),
373    i128 => Int(128),
374
375    bool => Bool,
376
377    IntAddr => Address,
378    StdAddr => Address,
379    VarAddr => Address,
380}
381
382/// A type which can be converted into a plain ABI value.
383pub trait IntoPlainAbi: IntoAbi {
384    /// Returns a corresponding plain ABI value.
385    ///
386    /// NOTE: use [`IntoPlainAbi::into_plain_abi`] when building ABI from a temp value.
387    fn as_plain_abi(&self) -> PlainAbiValue;
388
389    /// Converts into a corresponding plain ABI value.
390    fn into_plain_abi(self) -> PlainAbiValue
391    where
392        Self: Sized;
393}
394
395macro_rules! impl_into_plain_abi {
396    ($($ty:ty => |$n:ident| { $expr1:expr, $expr2:expr $(,)? }),*$(,)?) => {$(
397        impl IntoPlainAbi for $ty {
398            #[inline]
399            fn as_plain_abi(&self) -> PlainAbiValue {
400                let $n = self;
401                $expr1
402            }
403
404            #[inline]
405            fn into_plain_abi(self) -> PlainAbiValue
406            where
407                Self: Sized
408            {
409                let $n = self;
410                $expr2
411            }
412        }
413    )*};
414}
415
416impl_into_plain_abi! {
417    PlainAbiValue => |v| { v.clone(), v },
418
419    u8 => |v| {
420        PlainAbiValue::Uint(8, BigUint::from(*v)),
421        PlainAbiValue::Uint(8, BigUint::from(v)),
422    },
423    u16 => |v| {
424        PlainAbiValue::Uint(16, BigUint::from(*v)),
425        PlainAbiValue::Uint(16, BigUint::from(v)),
426    },
427    u32 => |v| {
428        PlainAbiValue::Uint(32, BigUint::from(*v)),
429        PlainAbiValue::Uint(32, BigUint::from(v)),
430    },
431    u64 => |v| {
432        PlainAbiValue::Uint(64, BigUint::from(*v)),
433        PlainAbiValue::Uint(64, BigUint::from(v)),
434    },
435    u128 => |v| {
436        PlainAbiValue::Uint(128, BigUint::from(*v)),
437        PlainAbiValue::Uint(128, BigUint::from(v)),
438    },
439    HashBytes => |v| {
440        PlainAbiValue::Uint(256, BigUint::from_bytes_be(v.as_array())),
441        PlainAbiValue::Uint(256, BigUint::from_bytes_be(v.as_array())),
442    },
443    SplitDepth => |v| {
444        PlainAbiValue::Uint(5, BigUint::from(v.into_bit_len())),
445        PlainAbiValue::Uint(5, BigUint::from(v.into_bit_len())),
446    },
447    Uint9 => |v| {
448        PlainAbiValue::Uint(9, BigUint::from(v.into_inner())),
449        PlainAbiValue::Uint(9, BigUint::from(v.into_inner())),
450    },
451    Uint12 => |v| {
452        PlainAbiValue::Uint(12, BigUint::from(v.into_inner())),
453        PlainAbiValue::Uint(12, BigUint::from(v.into_inner())),
454    },
455    Uint15 => |v| {
456        PlainAbiValue::Uint(15, BigUint::from(v.into_inner())),
457        PlainAbiValue::Uint(15, BigUint::from(v.into_inner())),
458    },
459
460    i8 => |v| {
461        PlainAbiValue::Int(8, BigInt::from(*v)),
462        PlainAbiValue::Int(8, BigInt::from(v)),
463    },
464    i16 => |v| {
465        PlainAbiValue::Int(16, BigInt::from(*v)),
466        PlainAbiValue::Int(16, BigInt::from(v)),
467    },
468    i32 => |v| {
469        PlainAbiValue::Int(32, BigInt::from(*v)),
470        PlainAbiValue::Int(32, BigInt::from(v)),
471    },
472    i64 => |v| {
473        PlainAbiValue::Int(64, BigInt::from(*v)),
474        PlainAbiValue::Int(64, BigInt::from(v)),
475    },
476    i128 => |v| {
477        PlainAbiValue::Int(128, BigInt::from(*v)),
478        PlainAbiValue::Int(128, BigInt::from(v)),
479    },
480
481    bool => |v| {
482        PlainAbiValue::Bool(*v),
483        PlainAbiValue::Bool(v),
484    },
485
486    IntAddr => |v| {
487        PlainAbiValue::Address(Box::new(v.clone())),
488        PlainAbiValue::Address(Box::new(v)),
489    },
490    StdAddr => |v| {
491        PlainAbiValue::Address(Box::new(v.clone().into())),
492        PlainAbiValue::Address(Box::new(v.into())),
493    },
494    VarAddr => |v| {
495        PlainAbiValue::Address(Box::new(v.clone().into())),
496        PlainAbiValue::Address(Box::new(v.into())),
497    },
498}
499
500/// A type which can be converted into an ABI value.
501pub trait IntoAbi {
502    /// Returns a corresponding ABI value.
503    ///
504    /// NOTE: use [`IntoAbi::into_abi`] when building ABI from a temp value.
505    fn as_abi(&self) -> AbiValue;
506
507    /// Converts into a corresponding ABI value.
508    fn into_abi(self) -> AbiValue
509    where
510        Self: Sized;
511}
512
513macro_rules! impl_into_abi {
514    ($($ty:ty => |$n:ident| { $expr1:expr, $expr2:expr $(,)? }),*$(,)?) => {$(
515        impl IntoAbi for $ty {
516            #[inline]
517            fn as_abi(&self) -> AbiValue {
518                let $n = self;
519                $expr1
520            }
521
522            #[inline]
523            fn into_abi(self) -> AbiValue
524            where
525                Self: Sized
526            {
527                let $n = self;
528                $expr2
529            }
530        }
531    )*};
532}
533
534impl_into_abi! {
535    AbiValue => |v| { v.clone(), v },
536    PlainAbiValue => |v| { v.clone().into(), v.into() },
537
538    u8 => |v| {
539        AbiValue::Uint(8, BigUint::from(*v)),
540        AbiValue::Uint(8, BigUint::from(v)),
541    },
542    u16 => |v| {
543        AbiValue::Uint(16, BigUint::from(*v)),
544        AbiValue::Uint(16, BigUint::from(v)),
545    },
546    u32 => |v| {
547        AbiValue::Uint(32, BigUint::from(*v)),
548        AbiValue::Uint(32, BigUint::from(v)),
549    },
550    u64 => |v| {
551        AbiValue::Uint(64, BigUint::from(*v)),
552        AbiValue::Uint(64, BigUint::from(v)),
553    },
554    u128 => |v| {
555        AbiValue::Uint(128, BigUint::from(*v)),
556        AbiValue::Uint(128, BigUint::from(v)),
557    },
558    HashBytes => |v| {
559        AbiValue::Uint(256, BigUint::from_bytes_be(v.as_array())),
560        AbiValue::Uint(256, BigUint::from_bytes_be(v.as_array())),
561    },
562    SplitDepth => |v| {
563        AbiValue::Uint(5, BigUint::from(v.into_bit_len())),
564        AbiValue::Uint(5, BigUint::from(v.into_bit_len())),
565    },
566    Uint9 => |v| {
567        AbiValue::Uint(9, BigUint::from(v.into_inner())),
568        AbiValue::Uint(9, BigUint::from(v.into_inner())),
569    },
570    Uint12 => |v| {
571        AbiValue::Uint(12, BigUint::from(v.into_inner())),
572        AbiValue::Uint(12, BigUint::from(v.into_inner())),
573    },
574    Uint15 => |v| {
575        AbiValue::Uint(15, BigUint::from(v.into_inner())),
576        AbiValue::Uint(15, BigUint::from(v.into_inner())),
577    },
578
579    i8 => |v| {
580        AbiValue::Int(8, BigInt::from(*v)),
581        AbiValue::Int(8, BigInt::from(v)),
582    },
583    i16 => |v| {
584        AbiValue::Int(16, BigInt::from(*v)),
585        AbiValue::Int(16, BigInt::from(v)),
586    },
587    i32 => |v| {
588        AbiValue::Int(32, BigInt::from(*v)),
589        AbiValue::Int(32, BigInt::from(v)),
590    },
591    i64 => |v| {
592        AbiValue::Int(64, BigInt::from(*v)),
593        AbiValue::Int(64, BigInt::from(v)),
594    },
595    i128 => |v| {
596        AbiValue::Int(128, BigInt::from(*v)),
597        AbiValue::Int(128, BigInt::from(v)),
598    },
599
600    bool => |v| {
601        AbiValue::Bool(*v),
602        AbiValue::Bool(v),
603    },
604
605    VarUint24 => |v| {
606        AbiValue::VarUint(NonZeroU8::new(4).unwrap(), BigUint::from(v.into_inner())),
607        AbiValue::VarUint(NonZeroU8::new(4).unwrap(), BigUint::from(v.into_inner())),
608    },
609    VarUint56 => |v| {
610        AbiValue::VarUint(NonZeroU8::new(8).unwrap(), BigUint::from(v.into_inner())),
611        AbiValue::VarUint(NonZeroU8::new(8).unwrap(), BigUint::from(v.into_inner())),
612    },
613
614    Tokens => |v| {
615        AbiValue::Token(*v),
616        AbiValue::Token(v),
617    },
618
619    Cell => |v| {
620        AbiValue::Cell(v.clone()),
621        AbiValue::Cell(v),
622    },
623
624    Bytes => |v| {
625        AbiValue::Bytes(v.clone()),
626        AbiValue::Bytes(v),
627    },
628    String => |v| {
629        AbiValue::String(v.clone()),
630        AbiValue::String(v),
631    },
632
633    IntAddr => |v| {
634        AbiValue::Address(Box::new(v.clone())),
635        AbiValue::Address(Box::new(v)),
636    },
637    StdAddr => |v| {
638        AbiValue::Address(Box::new(v.clone().into())),
639        AbiValue::Address(Box::new(v.into())),
640    },
641    VarAddr => |v| {
642        AbiValue::Address(Box::new(v.clone().into())),
643        AbiValue::Address(Box::new(v.into())),
644    },
645}
646
647impl IntoAbi for str {
648    #[inline]
649    fn as_abi(&self) -> AbiValue {
650        AbiValue::String(self.to_owned())
651    }
652
653    #[inline]
654    #[allow(dead_code)]
655    fn into_abi(self) -> AbiValue
656    where
657        for<'a> str: Sized,
658    {
659        unreachable!()
660    }
661}
662
663impl<T: WithAbiType + IntoAbi> IntoAbi for [T] {
664    fn as_abi(&self) -> AbiValue {
665        if typeid::of::<T>() == typeid::of::<u8>() {
666            // SAFETY: T is definitely u8
667            let bytes = unsafe { std::slice::from_raw_parts(self.as_ptr().cast(), self.len()) };
668            AbiValue::Bytes(Bytes::copy_from_slice(bytes))
669        } else {
670            AbiValue::Array(
671                Arc::new(T::abi_type()),
672                self.iter().map(T::as_abi).collect(),
673            )
674        }
675    }
676
677    #[inline]
678    #[allow(dead_code)]
679    fn into_abi(self) -> AbiValue
680    where
681        for<'a> [T]: Sized,
682    {
683        unreachable!()
684    }
685}
686
687impl<T: WithAbiType + IntoAbi, const N: usize> IntoAbi for [T; N] {
688    fn as_abi(&self) -> AbiValue {
689        if typeid::of::<T>() == typeid::of::<u8>() {
690            // SAFETY: T is definitely u8
691            let bytes = unsafe { std::slice::from_raw_parts(self.as_ptr().cast(), self.len()) };
692            AbiValue::FixedBytes(Bytes::copy_from_slice(bytes))
693        } else {
694            AbiValue::FixedArray(
695                Arc::new(T::abi_type()),
696                self.iter().map(T::as_abi).collect(),
697            )
698        }
699    }
700
701    fn into_abi(self) -> AbiValue
702    where
703        Self: Sized,
704    {
705        if typeid::of::<T>() == typeid::of::<u8>() {
706            // SAFETY: T is definitely u8
707            let bytes = unsafe { std::slice::from_raw_parts(self.as_ptr().cast(), self.len()) };
708            AbiValue::FixedBytes(Bytes::copy_from_slice(bytes))
709        } else {
710            AbiValue::FixedArray(
711                Arc::new(T::abi_type()),
712                self.into_iter().map(T::into_abi).collect(),
713            )
714        }
715    }
716}
717
718impl<T: WithAbiType + IntoAbi> IntoAbi for Vec<T> {
719    #[inline]
720    fn as_abi(&self) -> AbiValue {
721        <[T]>::as_abi(self.as_slice())
722    }
723
724    fn into_abi(self) -> AbiValue
725    where
726        Self: Sized,
727    {
728        if typeid::of::<T>() == typeid::of::<u8>() {
729            // SAFETY: `T` is the same type as `u8`.
730            AbiValue::Bytes(Bytes::from(unsafe { cast_vec::<T, u8>(self) }))
731        } else {
732            AbiValue::Array(
733                Arc::new(T::abi_type()),
734                self.into_iter().map(T::into_abi).collect(),
735            )
736        }
737    }
738}
739
740impl<K: WithPlainAbiType + IntoPlainAbi, V: WithAbiType + IntoAbi> IntoAbi for BTreeMap<K, V> {
741    fn as_abi(&self) -> AbiValue {
742        AbiValue::Map(
743            K::plain_abi_type(),
744            Arc::new(V::abi_type()),
745            self.iter()
746                .map(|(key, value)| (K::as_plain_abi(key), V::as_abi(value)))
747                .collect(),
748        )
749    }
750
751    fn into_abi(self) -> AbiValue
752    where
753        Self: Sized,
754    {
755        AbiValue::Map(
756            K::plain_abi_type(),
757            Arc::new(V::abi_type()),
758            self.into_iter()
759                .map(|(key, value)| (K::into_plain_abi(key), V::into_abi(value)))
760                .collect(),
761        )
762    }
763}
764
765impl<K: WithPlainAbiType + IntoPlainAbi, V: WithAbiType + IntoAbi, S> IntoAbi for HashMap<K, V, S> {
766    fn as_abi(&self) -> AbiValue {
767        AbiValue::Map(
768            K::plain_abi_type(),
769            Arc::new(V::abi_type()),
770            self.iter()
771                .map(|(key, value)| (K::as_plain_abi(key), V::as_abi(value)))
772                .collect(),
773        )
774    }
775
776    fn into_abi(self) -> AbiValue
777    where
778        Self: Sized,
779    {
780        AbiValue::Map(
781            K::plain_abi_type(),
782            Arc::new(V::abi_type()),
783            self.into_iter()
784                .map(|(key, value)| (K::into_plain_abi(key), V::into_abi(value)))
785                .collect(),
786        )
787    }
788}
789
790impl<T: WithAbiType + IntoAbi> IntoAbi for Option<T> {
791    #[inline]
792    fn as_abi(&self) -> AbiValue {
793        AbiValue::Optional(
794            Arc::new(T::abi_type()),
795            self.as_ref().map(T::as_abi).map(Box::new),
796        )
797    }
798
799    #[inline]
800    fn into_abi(self) -> AbiValue
801    where
802        Self: Sized,
803    {
804        AbiValue::Optional(Arc::new(T::abi_type()), self.map(T::into_abi).map(Box::new))
805    }
806}
807
808impl IntoAbi for () {
809    #[inline]
810    fn as_abi(&self) -> AbiValue {
811        AbiValue::Tuple(Vec::new())
812    }
813
814    #[inline]
815    fn into_abi(self) -> AbiValue
816    where
817        Self: Sized,
818    {
819        self.as_abi()
820    }
821}
822
823macro_rules! impl_into_abi_for_tuple {
824    ($($i:tt: $t:ident),+$(,)?) => {
825        impl<$($t: IntoAbi),*> IntoAbi for ($($t),+,) {
826            fn as_abi(&self) -> AbiValue {
827                AbiValue::Tuple(vec![
828                    $(NamedAbiValue::from_index($i, <$t as IntoAbi>::as_abi(&self.$i))),*
829                ])
830            }
831
832            fn into_abi(self) -> AbiValue
833            where
834                Self: Sized,
835            {
836                AbiValue::Tuple(vec![
837                    $(NamedAbiValue::from_index($i, <$t as IntoAbi>::into_abi(self.$i))),*
838                ])
839            }
840        }
841    };
842}
843
844impl_into_abi_for_tuple! { 0: T0 }
845impl_into_abi_for_tuple! { 0: T0, 1: T1 }
846impl_into_abi_for_tuple! { 0: T0, 1: T1, 2: T2 }
847impl_into_abi_for_tuple! { 0: T0, 1: T1, 2: T2, 3: T3 }
848impl_into_abi_for_tuple! { 0: T0, 1: T1, 2: T2, 3: T3, 4: T4 }
849impl_into_abi_for_tuple! { 0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5 }
850impl_into_abi_for_tuple! { 0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6 }
851
852/// A type which can be converted from a plain ABI value.
853pub trait FromPlainAbi: Sized {
854    /// Constructs self from the plain ABI value.
855    fn from_plain_abi(value: PlainAbiValue) -> Result<Self>;
856}
857
858/// A type which can be converted from an ABI value.
859pub trait FromAbi: Sized {
860    /// Constructs self from the ABI value.
861    fn from_abi(value: AbiValue) -> Result<Self>;
862}
863
864fn expected_type(expected: &'static str, value: &AbiValue) -> anyhow::Error {
865    anyhow::Error::from(crate::abi::error::AbiError::TypeMismatch {
866        expected: Box::from(expected),
867        ty: value.display_type().to_string().into(),
868    })
869}
870
871fn expected_plain_type(expected: &'static str, value: &PlainAbiValue) -> anyhow::Error {
872    anyhow::Error::from(crate::abi::error::AbiError::TypeMismatch {
873        expected: Box::from(expected),
874        ty: value.display_type().to_string().into(),
875    })
876}
877
878macro_rules! impl_from_abi_for_int {
879    ($($ty:ty => ($variant:ident($bits:literal), $s:literal, $expr:tt)),*$(,)?) => {$(
880        impl FromAbi for $ty {
881            fn from_abi(value: AbiValue) -> Result<Self> {
882                match &value {
883                    AbiValue::$variant($bits, v) => match ToPrimitive::$expr(v) {
884                        Some(value) => Ok(value),
885                        None => Err(anyhow::Error::from(crate::error::Error::IntOverflow)),
886                    },
887                    value => Err(expected_type($s, value)),
888                }
889            }
890        }
891
892        impl FromPlainAbi for $ty {
893            fn from_plain_abi(value: PlainAbiValue) -> Result<Self> {
894                match &value {
895                    PlainAbiValue::$variant($bits, v) => match ToPrimitive::$expr(v) {
896                        Some(value) => Ok(value),
897                        None => Err(anyhow::Error::from(crate::error::Error::IntOverflow)),
898                    },
899                    value => Err(expected_plain_type($s, value)),
900                }
901            }
902        }
903    )*};
904}
905
906impl_from_abi_for_int! {
907    u8 => (Uint(8), "uint8", to_u8),
908    u16 => (Uint(16), "uint16", to_u16),
909    u32 => (Uint(32), "uint32", to_u32),
910    u64 => (Uint(64), "uint64", to_u64),
911    u128 => (Uint(128), "uint128", to_u128),
912
913    i8 => (Int(8), "int8", to_i8),
914    i16 => (Int(16), "int16", to_i16),
915    i32 => (Int(32), "int32", to_i32),
916    i64 => (Int(64), "int64", to_i64),
917    i128 => (Int(128), "int128", to_i128),
918}
919
920impl FromAbi for AbiValue {
921    #[inline]
922    fn from_abi(value: AbiValue) -> Result<Self> {
923        Ok(value)
924    }
925}
926
927impl FromAbi for bool {
928    fn from_abi(value: AbiValue) -> Result<Self> {
929        match &value {
930            AbiValue::Bool(value) => Ok(*value),
931            value => Err(expected_type("bool", value)),
932        }
933    }
934}
935
936impl FromPlainAbi for bool {
937    fn from_plain_abi(value: PlainAbiValue) -> Result<Self> {
938        match &value {
939            PlainAbiValue::Bool(value) => Ok(*value),
940            value => Err(expected_plain_type("bool", value)),
941        }
942    }
943}
944
945impl FromAbi for VarUint24 {
946    fn from_abi(value: AbiValue) -> Result<Self> {
947        match &value {
948            AbiValue::VarUint(size, v) if size.get() == 4 => match v.to_u32() {
949                Some(value) => Ok(Self::new(value)),
950                None => Err(anyhow::Error::from(crate::error::Error::IntOverflow)),
951            },
952            value => Err(expected_type("varuint4", value)),
953        }
954    }
955}
956
957impl FromAbi for VarUint56 {
958    fn from_abi(value: AbiValue) -> Result<Self> {
959        match &value {
960            AbiValue::VarUint(size, v) if size.get() == 8 => match v.to_u64() {
961                Some(value) => Ok(Self::new(value)),
962                None => Err(anyhow::Error::from(crate::error::Error::IntOverflow)),
963            },
964            value => Err(expected_type("varuint8", value)),
965        }
966    }
967}
968
969impl FromAbi for Tokens {
970    fn from_abi(value: AbiValue) -> Result<Self> {
971        match value {
972            AbiValue::VarUint(size, v) if size.get() == 16 => match v.to_u128() {
973                Some(value) => Ok(Self::new(value)),
974                None => Err(anyhow::Error::from(crate::error::Error::IntOverflow)),
975            },
976            AbiValue::Token(tokens) => Ok(tokens),
977            value => Err(expected_type("varuint8", &value)),
978        }
979    }
980}
981
982impl FromAbi for HashBytes {
983    fn from_abi(value: AbiValue) -> Result<Self> {
984        match &value {
985            AbiValue::Uint(256, v) => {
986                let mut result = HashBytes::ZERO;
987
988                let bytes = v.to_bytes_be();
989                let bytes_len = bytes.len();
990                match 32usize.checked_sub(bytes_len) {
991                    None => result.0.copy_from_slice(&bytes[bytes_len - 32..]),
992                    Some(pad) => result.0[pad..].copy_from_slice(&bytes),
993                };
994
995                Ok(result)
996            }
997            value => Err(expected_type("uint256", value)),
998        }
999    }
1000}
1001
1002impl FromPlainAbi for HashBytes {
1003    fn from_plain_abi(value: PlainAbiValue) -> Result<Self> {
1004        match &value {
1005            PlainAbiValue::Uint(256, v) => {
1006                let mut result = HashBytes::ZERO;
1007
1008                let bytes = v.to_bytes_be();
1009                let bytes_len = bytes.len();
1010                match 32usize.checked_sub(bytes_len) {
1011                    None => result.0.copy_from_slice(&bytes[bytes_len - 32..]),
1012                    Some(pad) => result.0[pad..].copy_from_slice(&bytes),
1013                };
1014
1015                Ok(result)
1016            }
1017            value => Err(expected_plain_type("uint256", value)),
1018        }
1019    }
1020}
1021
1022impl FromAbi for Cell {
1023    fn from_abi(value: AbiValue) -> Result<Self> {
1024        match value {
1025            AbiValue::Cell(cell) => Ok(cell),
1026            value => Err(expected_type("cell", &value)),
1027        }
1028    }
1029}
1030
1031impl FromAbi for Bytes {
1032    fn from_abi(value: AbiValue) -> Result<Self> {
1033        match value {
1034            AbiValue::Bytes(bytes) | AbiValue::FixedBytes(bytes) => Ok(bytes),
1035            value => Err(expected_type("bytes or fixedbytes", &value)),
1036        }
1037    }
1038}
1039
1040impl FromAbi for String {
1041    fn from_abi(value: AbiValue) -> Result<Self> {
1042        match value {
1043            AbiValue::String(string) => Ok(string),
1044            value => Err(expected_type("string", &value)),
1045        }
1046    }
1047}
1048
1049impl FromAbi for IntAddr {
1050    fn from_abi(value: AbiValue) -> Result<Self> {
1051        match value {
1052            AbiValue::Address(address) => Ok(*address),
1053            value => Err(expected_type("address", &value)),
1054        }
1055    }
1056}
1057
1058impl FromPlainAbi for IntAddr {
1059    fn from_plain_abi(value: PlainAbiValue) -> Result<Self> {
1060        match value {
1061            PlainAbiValue::Address(address) => Ok(*address),
1062            value => Err(expected_plain_type("address", &value)),
1063        }
1064    }
1065}
1066
1067impl FromAbi for StdAddr {
1068    fn from_abi(value: AbiValue) -> Result<Self> {
1069        if let AbiValue::Address(address) = &value {
1070            if let IntAddr::Std(address) = address.as_ref() {
1071                return Ok(address.clone());
1072            }
1073        }
1074        Err(expected_type("std address", &value))
1075    }
1076}
1077
1078impl FromPlainAbi for StdAddr {
1079    fn from_plain_abi(value: PlainAbiValue) -> Result<Self> {
1080        if let PlainAbiValue::Address(address) = &value {
1081            if let IntAddr::Std(address) = address.as_ref() {
1082                return Ok(address.clone());
1083            }
1084        }
1085        Err(expected_plain_type("std address", &value))
1086    }
1087}
1088
1089impl FromAbi for VarAddr {
1090    fn from_abi(value: AbiValue) -> Result<Self> {
1091        if let AbiValue::Address(address) = &value {
1092            if let IntAddr::Var(address) = address.as_ref() {
1093                return Ok(address.clone());
1094            }
1095        }
1096        Err(expected_type("var address", &value))
1097    }
1098}
1099
1100impl FromPlainAbi for VarAddr {
1101    fn from_plain_abi(value: PlainAbiValue) -> Result<Self> {
1102        if let PlainAbiValue::Address(address) = &value {
1103            if let IntAddr::Var(address) = address.as_ref() {
1104                return Ok(address.clone());
1105            }
1106        }
1107        Err(expected_plain_type("var address", &value))
1108    }
1109}
1110
1111impl<T: FromAbi> FromAbi for Vec<T> {
1112    fn from_abi(value: AbiValue) -> Result<Self> {
1113        if typeid::of::<T>() == typeid::of::<u8>() {
1114            match value {
1115                AbiValue::Bytes(bytes) | AbiValue::FixedBytes(bytes) => {
1116                    let bytes = Vec::<u8>::from(bytes);
1117                    // SAFETY: `T` is the same type as `u8`.
1118                    Ok(unsafe { cast_vec::<u8, T>(bytes) })
1119                }
1120                value => Err(expected_type("bytes or fixedbytes", &value)),
1121            }
1122        } else {
1123            let items = match value {
1124                AbiValue::Array(_, items) | AbiValue::FixedArray(_, items) => items,
1125                value => return Err(expected_type("array", &value)),
1126            };
1127            let mut result = Vec::with_capacity(items.len());
1128            for item in items {
1129                result.push(ok!(T::from_abi(item)));
1130            }
1131            Ok(result)
1132        }
1133    }
1134}
1135
1136impl<K: FromPlainAbi + Ord, V: FromAbi> FromAbi for BTreeMap<K, V> {
1137    fn from_abi(value: AbiValue) -> Result<Self> {
1138        match value {
1139            AbiValue::Map(_, _, map) => {
1140                let mut result = BTreeMap::new();
1141                for (key, value) in map {
1142                    result.insert(ok!(K::from_plain_abi(key)), ok!(V::from_abi(value)));
1143                }
1144                Ok(result)
1145            }
1146            value => Err(expected_type("map", &value)),
1147        }
1148    }
1149}
1150
1151impl<K: FromPlainAbi + Eq + Hash, V: FromAbi, S: BuildHasher + Default> FromAbi
1152    for HashMap<K, V, S>
1153{
1154    fn from_abi(value: AbiValue) -> Result<Self> {
1155        match value {
1156            AbiValue::Map(_, _, map) => {
1157                let mut result = HashMap::with_capacity_and_hasher(map.len(), S::default());
1158                for (key, value) in map {
1159                    result.insert(ok!(K::from_plain_abi(key)), ok!(V::from_abi(value)));
1160                }
1161                Ok(result)
1162            }
1163            value => Err(expected_type("map", &value)),
1164        }
1165    }
1166}
1167
1168impl<T: FromAbi> FromAbi for Option<T> {
1169    fn from_abi(value: AbiValue) -> Result<Self> {
1170        match value {
1171            AbiValue::Optional(_, value) => match value {
1172                Some(value) => T::from_abi(*value).map(Some),
1173                None => Ok(None),
1174            },
1175            value => Err(expected_type("optional", &value)),
1176        }
1177    }
1178}
1179
1180impl FromAbi for () {
1181    fn from_abi(value: AbiValue) -> Result<Self> {
1182        if let AbiValue::Tuple(items) = &value {
1183            if items.is_empty() {
1184                return Ok(());
1185            }
1186        }
1187        Err(expected_type("()", &value))
1188    }
1189}
1190
1191macro_rules! impl_from_abi_for_tuple {
1192    ($len:literal => $($t:ident),+$(,)?) => {
1193        impl<$($t: FromAbi),*> FromAbi for ($($t),+,) {
1194            fn from_abi(value: AbiValue) -> Result<Self> {
1195                match value {
1196                    AbiValue::Tuple(items) if items.len() == $len => {
1197                        let mut items = items.into_iter();
1198                        Ok(($(ok!(<$t as FromAbi>::from_abi(items.next().expect("exists").value))),*,))
1199                    }
1200                    value => Err(expected_type("tuple", &value))
1201                }
1202            }
1203        }
1204    };
1205}
1206
1207impl_from_abi_for_tuple! { 1 => T0 }
1208impl_from_abi_for_tuple! { 2 => T0, T1 }
1209impl_from_abi_for_tuple! { 3 => T0, T1, T2 }
1210impl_from_abi_for_tuple! { 4 => T0, T1, T2, T3 }
1211impl_from_abi_for_tuple! { 5 => T0, T1, T2, T3, T4 }
1212impl_from_abi_for_tuple! { 6 => T0, T1, T2, T3, T4, T5 }
1213impl_from_abi_for_tuple! { 7 => T0, T1, T2, T3, T4, T5, T6 }
1214
1215impl<T: FromAbi> FromAbi for Box<T> {
1216    #[inline]
1217    fn from_abi(value: AbiValue) -> Result<Self> {
1218        T::from_abi(value).map(Box::new)
1219    }
1220}
1221
1222impl<T: FromAbi> FromAbi for Arc<T> {
1223    #[inline]
1224    fn from_abi(value: AbiValue) -> Result<Self> {
1225        T::from_abi(value).map(Arc::new)
1226    }
1227}
1228
1229impl<T: FromAbi> FromAbi for Rc<T> {
1230    #[inline]
1231    fn from_abi(value: AbiValue) -> Result<Self> {
1232        T::from_abi(value).map(Rc::new)
1233    }
1234}
1235
1236/// A wrapper around ABI values iterator that converts
1237/// each item using the [`FromAbi`] trait.
1238///
1239/// It should be used to parse fields as tuple items
1240/// for some struct `T` (which must implement [`WithAbiType`]).
1241pub trait FromAbiIter<T> {
1242    /// Advances the iterator and returns the next value.
1243    fn next_value<V: FromAbi>(&mut self) -> Result<V>;
1244}
1245
1246impl<T, I> FromAbiIter<T> for I
1247where
1248    T: WithAbiType,
1249    I: Iterator<Item = NamedAbiValue>,
1250{
1251    fn next_value<V: FromAbi>(&mut self) -> Result<V> {
1252        match Iterator::next(self) {
1253            Some(item) => V::from_abi(item.value),
1254            None => Err(anyhow::Error::from(
1255                crate::abi::error::AbiError::TypeMismatch {
1256                    expected: T::abi_type().to_string().into_boxed_str(),
1257                    ty: Box::from("tuple part"),
1258                },
1259            )),
1260        }
1261    }
1262}
1263
1264/// # Safety
1265///
1266/// The following must be true:
1267/// - `T1` must have the same memory layout as `T2`.
1268unsafe fn cast_vec<T1, T2>(v: Vec<T1>) -> Vec<T2> {
1269    // The code is the same as in the offical example:
1270    // https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.from_raw_parts
1271
1272    // Prevent running `self`'s destructor so we are in complete control
1273    // of the allocation.
1274    let mut v = std::mem::ManuallyDrop::new(v);
1275
1276    // Pull out the various important pieces of information about `v`
1277    let p = v.as_mut_ptr().cast::<T2>();
1278    let len = v.len();
1279    let cap = v.capacity();
1280
1281    unsafe { Vec::<T2>::from_raw_parts(p, len, cap) }
1282}
1283
1284#[cfg(test)]
1285mod tests {
1286    use ahash::HashSet;
1287
1288    use super::*;
1289    use crate::prelude::CellFamily;
1290
1291    #[test]
1292    fn tuple_to_abi() {
1293        let target_abi = AbiValue::unnamed_tuple([
1294            AbiValue::uint(32, 123u32),
1295            AbiValue::uint(32, 321u32),
1296            AbiValue::Bool(true),
1297            AbiValue::unnamed_tuple([
1298                AbiValue::Cell(Cell::empty_cell()),
1299                AbiValue::Optional(Arc::new(AbiType::Bool), None),
1300            ]),
1301        ]);
1302
1303        let abi = (123u32, 321u32, true, (Cell::empty_cell(), None::<bool>));
1304
1305        assert_eq!(abi.into_abi(), target_abi);
1306    }
1307
1308    #[test]
1309    fn entities_without_name() {
1310        let only_signatures = HashSet::from_iter(
1311            [
1312                u32::abi_type().named("u32"),
1313                bool::abi_type().named("bool"),
1314                <(u32, bool)>::abi_type().named("(u32,bool)"),
1315            ]
1316            .map(WithoutName),
1317        );
1318
1319        assert!(only_signatures.contains(u32::abi_type().named("qwe").ignore_name()));
1320        assert!(only_signatures.contains(u32::abi_type().ignore_name()));
1321
1322        assert!(only_signatures.contains(bool::abi_type().named("asd").ignore_name()));
1323        assert!(only_signatures.contains(bool::abi_type().ignore_name()));
1324
1325        assert!(only_signatures.contains(<(u32, bool)>::abi_type().named("zxc").ignore_name()));
1326        assert!(only_signatures.contains(<(u32, bool)>::abi_type().ignore_name()));
1327
1328        assert!(!only_signatures.contains(u64::abi_type().ignore_name()));
1329    }
1330}