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
20pub trait IgnoreName {
22 type Unnamed<'a>
24 where
25 Self: 'a;
26
27 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
178pub trait WithAbiType {
180 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
342pub trait WithPlainAbiType: WithAbiType {
344 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
383pub trait IntoPlainAbi: IntoAbi {
385 fn as_plain_abi(&self) -> PlainAbiValue;
389
390 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
501pub trait IntoAbi {
503 fn as_abi(&self) -> AbiValue;
507
508 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 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 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 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 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
851pub trait FromPlainAbi: Sized {
853 fn from_plain_abi(value: PlainAbiValue) -> Result<Self>;
855}
856
857pub trait FromAbi: Sized {
859 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 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
1235pub trait FromAbiIter<T> {
1241 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
1263unsafe fn cast_vec<T1, T2>(v: Vec<T1>) -> Vec<T2> {
1268 let mut v = std::mem::ManuallyDrop::new(v);
1274
1275 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}