Skip to main content

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