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
19pub trait IgnoreName {
21 type Unnamed<'a>
23 where
24 Self: 'a;
25
26 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
177pub trait WithAbiType {
179 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
344pub trait WithPlainAbiType: WithAbiType {
346 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
385pub trait IntoPlainAbi: IntoAbi {
387 fn as_plain_abi(&self) -> PlainAbiValue;
391
392 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
503pub trait IntoAbi {
505 fn as_abi(&self) -> AbiValue;
509
510 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 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 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 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 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
866pub trait FromPlainAbi: Sized {
868 fn from_plain_abi(value: PlainAbiValue) -> Result<Self>;
870}
871
872pub trait FromAbi: Sized {
874 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 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
1287pub trait FromAbiIter<T> {
1293 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
1315unsafe fn cast_vec<T1, T2>(v: Vec<T1>) -> Vec<T2> {
1320 let mut v = std::mem::ManuallyDrop::new(v);
1326
1327 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}