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