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