1use std::borrow::Cow;
2use std::hash::Hash;
3use std::num::NonZeroU8;
4use std::str::FromStr;
5use std::sync::Arc;
6
7use serde::{Deserialize, Serialize};
8
9use super::error::{ParseAbiTypeError, ParseNamedAbiTypeError};
10use crate::abi::WithoutName;
11use crate::cell::{CellTreeStats, MAX_BIT_LEN, MAX_REF_COUNT};
12use crate::models::{IntAddr, StdAddr};
13use crate::num::Tokens;
14
15#[derive(Debug, Clone, Eq, PartialEq, Hash)]
17pub struct NamedAbiType {
18 pub name: Arc<str>,
20 pub ty: AbiType,
22}
23
24impl NamedAbiType {
25 #[inline]
27 pub fn new<T>(name: T, ty: AbiType) -> Self
28 where
29 T: Into<Arc<str>>,
30 {
31 Self {
32 name: name.into(),
33 ty,
34 }
35 }
36
37 pub fn from_index(index: usize, ty: AbiType) -> Self {
39 Self::new(format!("value{index}"), ty)
40 }
41
42 pub fn flatten(self) -> NamedAbiTypeFlatten {
50 match self.ty {
51 AbiType::Tuple(tuple) => {
52 let mut items = tuple.to_vec();
53 items.reverse();
54 NamedAbiTypeFlatten::Tuple(items)
55 }
56 ty => NamedAbiTypeFlatten::Single(Some(NamedAbiType {
57 name: self.name,
58 ty,
59 })),
60 }
61 }
62}
63
64impl AsRef<AbiType> for NamedAbiType {
65 #[inline]
66 fn as_ref(&self) -> &AbiType {
67 &self.ty
68 }
69}
70
71impl Serialize for NamedAbiType {
72 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
73 where
74 S: serde::ser::Serializer,
75 {
76 #[derive(Serialize)]
77 struct Helper<'a> {
78 name: &'a str,
79 #[serde(rename = "type", serialize_with = "collect_str")]
80 ty: DisplayAbiTypeSimple<'a>,
81 #[serde(skip_serializing_if = "Option::is_none")]
82 components: Option<&'a [NamedAbiType]>,
83 }
84
85 Helper {
86 name: &self.name,
87 ty: self.ty.display_simple(),
88 components: self.ty.components(),
89 }
90 .serialize(serializer)
91 }
92}
93
94impl<'de> Deserialize<'de> for NamedAbiType {
95 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
96 where
97 D: serde::Deserializer<'de>,
98 {
99 use serde::de::Error;
100
101 #[derive(Deserialize)]
102 struct Helper<'a> {
103 name: String,
104 #[serde(rename = "type", borrow)]
105 ty: Cow<'a, str>,
106 #[serde(default)]
107 components: Option<Vec<Helper<'a>>>,
108 }
109
110 impl TryFrom<Helper<'_>> for NamedAbiType {
111 type Error = ParseNamedAbiTypeError;
112
113 fn try_from(value: Helper<'_>) -> Result<Self, Self::Error> {
114 let mut ty = match AbiType::from_simple_str(&value.ty) {
115 Ok(ty) => ty,
116 Err(error) => {
117 return Err(ParseNamedAbiTypeError::InvalidType {
118 ty: value.ty.into(),
119 error,
120 });
121 }
122 };
123
124 match (ty.components_mut(), value.components) {
125 (Some(ty), Some(components)) => {
126 *ty = ok!(components
127 .into_iter()
128 .map(Self::try_from)
129 .collect::<Result<Arc<[_]>, _>>());
130 }
131 (Some(_), None) => {
132 return Err(ParseNamedAbiTypeError::ExpectedComponents {
133 ty: value.ty.into(),
134 })
135 }
136 (None, Some(_)) => {
137 return Err(ParseNamedAbiTypeError::UnexpectedComponents {
138 ty: value.ty.into(),
139 });
140 }
141 (None, None) => {}
142 }
143
144 Ok(Self {
145 name: value.name.into(),
146 ty,
147 })
148 }
149 }
150
151 let helper = ok!(<Helper as Deserialize>::deserialize(deserializer));
152 helper.try_into().map_err(Error::custom)
153 }
154}
155
156impl From<(String, AbiType)> for NamedAbiType {
157 #[inline]
158 fn from((name, ty): (String, AbiType)) -> Self {
159 Self {
160 name: name.into(),
161 ty,
162 }
163 }
164}
165
166impl<'a> From<(&'a str, AbiType)> for NamedAbiType {
167 #[inline]
168 fn from((name, ty): (&'a str, AbiType)) -> Self {
169 Self {
170 name: Arc::from(name),
171 ty,
172 }
173 }
174}
175
176impl From<(usize, AbiType)> for NamedAbiType {
177 #[inline]
178 fn from((index, ty): (usize, AbiType)) -> Self {
179 Self::from_index(index, ty)
180 }
181}
182
183impl PartialEq for WithoutName<NamedAbiType> {
184 #[inline]
185 fn eq(&self, other: &Self) -> bool {
186 WithoutName::wrap(&self.0.ty).eq(WithoutName::wrap(&other.0.ty))
187 }
188}
189
190impl Hash for WithoutName<NamedAbiType> {
191 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
192 WithoutName::wrap(&self.0.ty).hash(state);
193 }
194}
195
196impl std::borrow::Borrow<WithoutName<AbiType>> for WithoutName<NamedAbiType> {
197 fn borrow(&self) -> &WithoutName<AbiType> {
198 WithoutName::wrap(&self.0.ty)
199 }
200}
201
202#[derive(Clone)]
204pub enum NamedAbiTypeFlatten {
205 #[doc(hidden)]
206 Single(Option<NamedAbiType>),
207 #[doc(hidden)]
208 Tuple(Vec<NamedAbiType>),
209}
210
211impl Iterator for NamedAbiTypeFlatten {
212 type Item = NamedAbiType;
213
214 fn size_hint(&self) -> (usize, Option<usize>) {
215 let size = match self {
216 Self::Single(item) => item.is_some() as usize,
217 Self::Tuple(items) => items.len(),
218 };
219 (size, Some(size))
220 }
221
222 fn next(&mut self) -> Option<Self::Item> {
223 match self {
224 Self::Single(item) => item.take(),
225 Self::Tuple(items) => items.pop(),
226 }
227 }
228}
229
230#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
232pub enum AbiHeaderType {
233 Time,
235 Expire,
237 PublicKey,
239}
240
241impl FromStr for AbiHeaderType {
242 type Err = ParseAbiTypeError;
243
244 fn from_str(s: &str) -> Result<Self, Self::Err> {
245 Ok(match s {
246 "time" => Self::Time,
247 "expire" => Self::Expire,
248 "pubkey" => Self::PublicKey,
249 _ => return Err(ParseAbiTypeError::UnknownType),
250 })
251 }
252}
253
254impl std::fmt::Display for AbiHeaderType {
255 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
256 f.write_str(match self {
257 Self::Time => "time",
258 Self::Expire => "expire",
259 Self::PublicKey => "pubkey",
260 })
261 }
262}
263
264impl Serialize for AbiHeaderType {
265 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
266 where
267 S: serde::Serializer,
268 {
269 serializer.collect_str(&self)
270 }
271}
272
273impl<'de> Deserialize<'de> for AbiHeaderType {
274 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
275 where
276 D: serde::Deserializer<'de>,
277 {
278 use serde::de::Error;
279
280 #[derive(Deserialize)]
281 #[serde(transparent)]
282 struct Helper<'a>(#[serde(borrow)] Cow<'a, str>);
283
284 Self::from_str(&ok!(Helper::deserialize(deserializer)).0).map_err(Error::custom)
285 }
286}
287
288#[derive(Debug, Clone, Eq, PartialEq, Hash)]
290pub enum AbiType {
291 Uint(u16),
293 Int(u16),
295 VarUint(NonZeroU8),
297 VarInt(NonZeroU8),
299 Bool,
301 Cell,
305 Address,
309 Bytes,
311 FixedBytes(usize),
313 String,
315 Token,
319 Tuple(Arc<[NamedAbiType]>),
321 Array(Arc<Self>),
323 FixedArray(Arc<Self>, usize),
325 Map(PlainAbiType, Arc<Self>),
327 Optional(Arc<Self>),
329 Ref(Arc<Self>),
331}
332
333impl AbiType {
334 pub fn named<T: Into<String>>(self, name: T) -> NamedAbiType {
336 NamedAbiType {
337 name: Arc::from(name.into()),
338 ty: self,
339 }
340 }
341
342 pub fn as_plain(&self) -> Option<PlainAbiType> {
344 Some(match self {
345 Self::Uint(n) => PlainAbiType::Uint(*n),
346 Self::Int(n) => PlainAbiType::Int(*n),
347 Self::Bool => PlainAbiType::Bool,
348 Self::Address => PlainAbiType::Address,
349 _ => return None,
350 })
351 }
352
353 pub fn max_size(&self) -> CellTreeStats {
355 match self {
356 Self::Uint(n) | Self::Int(n) => CellTreeStats {
357 bit_count: *n as _,
358 cell_count: 0,
359 },
360 Self::VarUint(n) | Self::VarInt(n) => {
361 let value_bytes: u8 = n.get() - 1;
362 let bit_count = (8 - value_bytes.leading_zeros()) as u64 + (value_bytes as u64 * 8);
363 CellTreeStats {
364 bit_count,
365 cell_count: 0,
366 }
367 }
368 Self::Bool => CellTreeStats {
369 bit_count: 1,
370 cell_count: 0,
371 },
372 Self::Cell | Self::Bytes | Self::FixedBytes(_) | Self::String | Self::Ref(_) => {
373 CellTreeStats {
374 bit_count: 0,
375 cell_count: 1,
376 }
377 }
378 Self::Address => CellTreeStats {
379 bit_count: IntAddr::BITS_MAX as _,
380 cell_count: 0,
381 },
382 Self::Token => CellTreeStats {
383 bit_count: Tokens::MAX_BITS as _,
384 cell_count: 0,
385 },
386 Self::Array(_) => CellTreeStats {
387 bit_count: 33,
388 cell_count: 1,
389 },
390 Self::FixedArray(..) | Self::Map(..) => CellTreeStats {
391 bit_count: 1,
392 cell_count: 1,
393 },
394 Self::Optional(ty) => {
395 let ty_size = ty.max_size();
396 if ty_size.bit_count < MAX_BIT_LEN as u64
397 && ty_size.cell_count < MAX_REF_COUNT as u64
398 {
399 CellTreeStats {
400 bit_count: 1,
401 cell_count: 0,
402 } + ty_size
403 } else {
404 CellTreeStats {
405 bit_count: 1,
406 cell_count: 1,
407 }
408 }
409 }
410 Self::Tuple(items) => items.iter().map(|item| item.ty.max_size()).sum(),
411 }
412 }
413
414 pub fn max_bits(&self) -> usize {
416 self.max_size().bit_count as usize
417 }
418
419 pub fn max_refs(&self) -> usize {
421 self.max_size().cell_count as usize
422 }
423
424 fn components(&self) -> Option<&[NamedAbiType]> {
425 match self {
426 Self::Tuple(types) => Some(types),
427 Self::Array(ty) => ty.components(),
428 Self::FixedArray(ty, _) => ty.components(),
429 Self::Map(_, value_ty) => value_ty.components(),
430 Self::Optional(ty) => ty.components(),
431 Self::Ref(ty) => ty.components(),
432 _ => None,
433 }
434 }
435
436 fn components_mut(&mut self) -> Option<&mut Arc<[NamedAbiType]>> {
437 match self {
438 Self::Tuple(types) => Some(types),
439 Self::Array(ty) => Arc::make_mut(ty).components_mut(),
440 Self::FixedArray(ty, _) => Arc::make_mut(ty).components_mut(),
441 Self::Map(_, value_ty) => Arc::make_mut(value_ty).components_mut(),
442 Self::Optional(ty) => Arc::make_mut(ty).components_mut(),
443 Self::Ref(ty) => Arc::make_mut(ty).components_mut(),
444 _ => None,
445 }
446 }
447
448 pub fn flatten(self) -> AbiTypeFlatten {
456 match self {
457 AbiType::Tuple(tuple) => {
458 let mut items = tuple.to_vec();
459 items.reverse();
460 AbiTypeFlatten::Tuple(items)
461 }
462 ty => AbiTypeFlatten::Single(Some(ty)),
463 }
464 }
465
466 #[inline]
468 pub fn varuint(size: u8) -> Self {
469 Self::VarUint(NonZeroU8::new(size).unwrap())
470 }
471
472 #[inline]
474 pub fn varint(size: u8) -> Self {
475 Self::VarInt(NonZeroU8::new(size).unwrap())
476 }
477
478 #[inline]
480 pub fn tuple<I, T>(values: I) -> Self
481 where
482 I: IntoIterator<Item = T>,
483 NamedAbiType: From<T>,
484 {
485 Self::Tuple(values.into_iter().map(NamedAbiType::from).collect())
486 }
487
488 #[inline]
490 pub fn unnamed_tuple<I>(values: I) -> Self
491 where
492 I: IntoIterator<Item = AbiType>,
493 {
494 Self::Tuple(
495 values
496 .into_iter()
497 .enumerate()
498 .map(|(i, ty)| NamedAbiType::from_index(i, ty))
499 .collect(),
500 )
501 }
502
503 #[inline]
505 pub fn array<T>(ty: T) -> Self
506 where
507 Arc<AbiType>: From<T>,
508 {
509 Self::Array(Arc::<AbiType>::from(ty))
510 }
511
512 #[inline]
514 pub fn fixedarray<T>(ty: T, len: usize) -> Self
515 where
516 Arc<AbiType>: From<T>,
517 {
518 Self::FixedArray(Arc::<AbiType>::from(ty), len)
519 }
520
521 #[inline]
523 pub fn map<V>(key_ty: PlainAbiType, value_ty: V) -> Self
524 where
525 Arc<AbiType>: From<V>,
526 {
527 Self::Map(key_ty, Arc::<AbiType>::from(value_ty))
528 }
529
530 #[inline]
532 pub fn optional<T>(ty: T) -> Self
533 where
534 Arc<AbiType>: From<T>,
535 {
536 Self::Optional(Arc::<AbiType>::from(ty))
537 }
538
539 #[inline]
541 pub fn reference<T>(ty: T) -> Self
542 where
543 Arc<AbiType>: From<T>,
544 {
545 Self::Ref(Arc::<AbiType>::from(ty))
546 }
547
548 fn from_simple_str(s: &str) -> Result<Self, ParseAbiTypeError> {
549 if let Some(arr_ty) = s.strip_suffix(']') {
550 let (ty, len) = ok!(arr_ty
551 .rsplit_once('[')
552 .ok_or(ParseAbiTypeError::InvalidArrayType));
553
554 let len = if len.is_empty() {
555 None
556 } else {
557 Some(ok!(len
558 .parse::<usize>()
559 .map_err(ParseAbiTypeError::InvalidArrayLength)))
560 };
561
562 let ty = ok!(Self::from_simple_str(ty).map(Arc::new));
563 return Ok(match len {
564 None => Self::Array(ty),
565 Some(len) => Self::FixedArray(ty, len),
566 });
567 }
568
569 Ok(match s {
570 "bool" => Self::Bool,
571 "cell" => Self::Cell,
572 "address" => Self::Address,
573 "bytes" => Self::Bytes,
574 "string" => Self::String,
575 "gram" | "token" => Self::Token,
576 "tuple" => Self::Tuple(Arc::from([].as_slice())),
577 _ => {
578 if let Some(s) = s.strip_prefix("uint") {
579 Self::Uint(ok!(s
580 .parse::<u16>()
581 .map_err(ParseAbiTypeError::InvalidBitLen)))
582 } else if let Some(s) = s.strip_prefix("int") {
583 Self::Int(ok!(s
584 .parse::<u16>()
585 .map_err(ParseAbiTypeError::InvalidBitLen)))
586 } else if let Some(s) = s.strip_prefix("varuint") {
587 Self::VarUint(ok!(s
588 .parse::<NonZeroU8>()
589 .map_err(ParseAbiTypeError::InvalidByteLen)))
590 } else if let Some(s) = s.strip_prefix("varint") {
591 Self::VarInt(ok!(s
592 .parse::<NonZeroU8>()
593 .map_err(ParseAbiTypeError::InvalidByteLen)))
594 } else if let Some(s) = s.strip_prefix("fixedbytes") {
595 Self::FixedBytes(ok!(s
596 .parse::<usize>()
597 .map_err(ParseAbiTypeError::InvalidByteLen)))
598 } else if let Some(s) = s.strip_prefix("map(") {
599 let s = ok!(s
600 .strip_suffix(')')
601 .ok_or(ParseAbiTypeError::UnterminatedInnerType));
602 let (key_ty, value_ty) = ok!(s
603 .split_once(',')
604 .ok_or(ParseAbiTypeError::ValueTypeNotFound));
605
606 Self::Map(
607 ok!(PlainAbiType::from_str(key_ty)),
608 ok!(Self::from_simple_str(value_ty).map(Arc::new)),
609 )
610 } else if let Some(s) = s.strip_prefix("optional(") {
611 let s = ok!(s
612 .strip_suffix(')')
613 .ok_or(ParseAbiTypeError::UnterminatedInnerType));
614
615 Self::Optional(ok!(Self::from_simple_str(s).map(Arc::new)))
616 } else if let Some(s) = s.strip_prefix("ref(") {
617 let s = ok!(s
618 .strip_suffix(')')
619 .ok_or(ParseAbiTypeError::UnterminatedInnerType));
620
621 Self::Ref(ok!(Self::from_simple_str(s).map(Arc::new)))
622 } else {
623 return Err(ParseAbiTypeError::UnknownType);
624 }
625 }
626 })
627 }
628
629 fn display_simple(&self) -> DisplayAbiTypeSimple<'_> {
630 DisplayAbiTypeSimple(self)
631 }
632}
633
634impl AsRef<AbiType> for AbiType {
635 #[inline]
636 fn as_ref(&self) -> &AbiType {
637 self
638 }
639}
640
641impl std::fmt::Display for AbiType {
642 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
643 let s = match self {
644 Self::Uint(n) => return write!(f, "uint{n}"),
645 Self::Int(n) => return write!(f, "int{n}"),
646 Self::VarUint(n) => return write!(f, "varuint{n}"),
647 Self::VarInt(n) => return write!(f, "varint{n}"),
648 Self::Bool => "bool",
649 Self::Cell => "cell",
650 Self::Address => "address",
651 Self::Bytes => "bytes",
652 Self::FixedBytes(n) => return write!(f, "fixedbytes{n}"),
653 Self::String => "string",
654 Self::Token => "gram",
655 Self::Tuple(items) => {
656 if items.is_empty() {
657 "()"
658 } else {
659 let mut first = true;
660 ok!(f.write_str("("));
661 for item in items.as_ref() {
662 if !std::mem::take(&mut first) {
663 ok!(f.write_str(","));
664 }
665 ok!(std::fmt::Display::fmt(&item.ty, f));
666 }
667 ")"
668 }
669 }
670 Self::Array(ty) => return write!(f, "{ty}[]"),
671 Self::FixedArray(ty, n) => return write!(f, "{ty}[{n}]"),
672 Self::Map(key_ty, value_ty) => return write!(f, "map({key_ty},{value_ty})"),
673 Self::Optional(ty) => return write!(f, "optional({ty})"),
674 Self::Ref(ty) => return write!(f, "ref({ty})"),
675 };
676 f.write_str(s)
677 }
678}
679
680#[derive(Clone, Copy)]
681struct DisplayAbiTypeSimple<'a>(&'a AbiType);
682
683impl std::fmt::Display for DisplayAbiTypeSimple<'_> {
684 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
685 match self.0 {
686 AbiType::Tuple(_) => f.write_str("tuple"),
687 AbiType::Array(ty) => write!(f, "{}[]", ty.display_simple()),
688 AbiType::FixedArray(ty, n) => write!(f, "{}[{n}]", ty.display_simple()),
689 AbiType::Map(key_ty, value_ty) => {
690 write!(f, "map({key_ty},{})", value_ty.display_simple())
691 }
692 AbiType::Optional(ty) => write!(f, "optional({})", ty.display_simple()),
693 AbiType::Ref(ty) => write!(f, "ref({})", ty.display_simple()),
694 ty => std::fmt::Display::fmt(ty, f),
695 }
696 }
697}
698
699impl PartialEq for WithoutName<AbiType> {
700 fn eq(&self, other: &Self) -> bool {
701 match (&self.0, &other.0) {
702 (AbiType::Uint(a), AbiType::Uint(b)) => a.eq(b),
703 (AbiType::Int(a), AbiType::Int(b)) => a.eq(b),
704 (AbiType::VarUint(a), AbiType::VarUint(b)) => a.eq(b),
705 (AbiType::VarInt(a), AbiType::VarInt(b)) => a.eq(b),
706 (AbiType::Bool, AbiType::Bool) => true,
707 (AbiType::Cell, AbiType::Cell) => true,
708 (AbiType::Address, AbiType::Address) => true,
709 (AbiType::Bytes, AbiType::Bytes) => true,
710 (AbiType::FixedBytes(a), AbiType::FixedBytes(b)) => a.eq(b),
711 (AbiType::String, AbiType::String) => true,
712 (AbiType::Token, AbiType::Token) => true,
713 (AbiType::Tuple(a), AbiType::Tuple(b)) => {
714 WithoutName::wrap_slice(a.as_ref()).eq(WithoutName::wrap_slice(b.as_ref()))
715 }
716 (AbiType::Array(a), AbiType::Array(b)) => {
717 WithoutName::wrap(a.as_ref()).eq(WithoutName::wrap(b.as_ref()))
718 }
719 (AbiType::FixedArray(a, an), AbiType::FixedArray(b, bn)) => {
720 WithoutName::wrap(a.as_ref()).eq(WithoutName::wrap(b.as_ref())) && an.eq(bn)
721 }
722 (AbiType::Map(ak, av), AbiType::Map(bk, bv)) => {
723 ak.eq(bk) && WithoutName::wrap(av.as_ref()).eq(WithoutName::wrap(bv.as_ref()))
724 }
725 (AbiType::Optional(a), AbiType::Optional(b)) => {
726 WithoutName::wrap(a.as_ref()).eq(WithoutName::wrap(b.as_ref()))
727 }
728 (AbiType::Ref(a), AbiType::Ref(b)) => {
729 WithoutName::wrap(a.as_ref()).eq(WithoutName::wrap(b.as_ref()))
730 }
731 _ => false,
732 }
733 }
734}
735
736impl Hash for WithoutName<AbiType> {
737 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
738 core::mem::discriminant(&self.0).hash(state);
739 match &self.0 {
740 AbiType::Uint(x) => x.hash(state),
741 AbiType::Int(x) => x.hash(state),
742 AbiType::VarUint(x) => x.hash(state),
743 AbiType::VarInt(x) => x.hash(state),
744 AbiType::Bool => {}
745 AbiType::Cell => {}
746 AbiType::Address => {}
747 AbiType::Bytes => {}
748 AbiType::FixedBytes(x) => x.hash(state),
749 AbiType::String => {}
750 AbiType::Token => {}
751 AbiType::Tuple(x) => WithoutName::wrap_slice(x.as_ref()).hash(state),
752 AbiType::Array(x) => WithoutName::wrap(x.as_ref()).hash(state),
753 AbiType::FixedArray(x, n) => {
754 WithoutName::wrap(x.as_ref()).hash(state);
755 n.hash(state);
756 }
757 AbiType::Map(k, v) => {
758 k.hash(state);
759 WithoutName::wrap(v.as_ref()).hash(state);
760 }
761 AbiType::Optional(x) => WithoutName::wrap(x.as_ref()).hash(state),
762 AbiType::Ref(x) => WithoutName::wrap(x.as_ref()).hash(state),
763 }
764 }
765}
766
767#[derive(Clone)]
769pub enum AbiTypeFlatten {
770 #[doc(hidden)]
771 Single(Option<AbiType>),
772 #[doc(hidden)]
773 Tuple(Vec<NamedAbiType>),
774}
775
776impl Iterator for AbiTypeFlatten {
777 type Item = AbiType;
778
779 fn size_hint(&self) -> (usize, Option<usize>) {
780 let size = match self {
781 Self::Single(item) => item.is_some() as usize,
782 Self::Tuple(items) => items.len(),
783 };
784 (size, Some(size))
785 }
786
787 fn next(&mut self) -> Option<Self::Item> {
788 match self {
789 Self::Single(item) => item.take(),
790 Self::Tuple(items) => items.pop().map(|item| item.ty),
791 }
792 }
793}
794
795#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
798pub enum PlainAbiType {
799 Uint(u16),
801 Int(u16),
803 Bool,
805 Address,
809}
810
811impl PlainAbiType {
812 pub fn key_bits(&self) -> u16 {
814 match self {
815 Self::Uint(n) | Self::Int(n) => *n,
816 Self::Bool => 1,
817 Self::Address => StdAddr::BITS_WITHOUT_ANYCAST,
818 }
819 }
820}
821
822impl From<PlainAbiType> for AbiType {
823 fn from(value: PlainAbiType) -> Self {
824 match value {
825 PlainAbiType::Uint(n) => Self::Uint(n),
826 PlainAbiType::Int(n) => Self::Int(n),
827 PlainAbiType::Bool => Self::Bool,
828 PlainAbiType::Address => Self::Address,
829 }
830 }
831}
832
833impl FromStr for PlainAbiType {
834 type Err = ParseAbiTypeError;
835
836 fn from_str(s: &str) -> Result<Self, Self::Err> {
837 Ok(match s {
838 "bool" => Self::Bool,
839 "address" => Self::Address,
840 s => {
841 if let Some(s) = s.strip_prefix("uint") {
842 Self::Uint(ok!(s
843 .parse::<u16>()
844 .map_err(ParseAbiTypeError::InvalidBitLen)))
845 } else if let Some(s) = s.strip_prefix("int") {
846 Self::Int(ok!(s
847 .parse::<u16>()
848 .map_err(ParseAbiTypeError::InvalidBitLen)))
849 } else {
850 return Err(ParseAbiTypeError::UnknownType);
851 }
852 }
853 })
854 }
855}
856
857impl std::fmt::Display for PlainAbiType {
858 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
859 let s = match self {
860 Self::Uint(n) => return write!(f, "uint{n}"),
861 Self::Int(n) => return write!(f, "int{n}"),
862 Self::Bool => "bool",
863 Self::Address => "address",
864 };
865 f.write_str(s)
866 }
867}
868
869#[inline]
870fn collect_str<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
871where
872 T: std::fmt::Display,
873 S: serde::ser::Serializer,
874{
875 serializer.collect_str(value)
876}
877
878#[cfg(test)]
879mod tests {
880 use std::collections::BTreeMap;
881
882 use super::*;
883 use crate::abi::traits::{WithAbiType, WithPlainAbiType};
884
885 #[test]
886 fn correct_full_signature() {
887 macro_rules! assert_eq_sig {
888 ($expr:expr, $signature:literal) => {
889 assert_eq!(($expr).to_string(), $signature)
890 };
891 }
892
893 assert_eq_sig!(AbiType::Uint(100), "uint100");
894 assert_eq_sig!(AbiType::Int(100), "int100");
895 assert_eq_sig!(AbiType::varuint(16), "varuint16");
896 assert_eq_sig!(AbiType::varint(16), "varint16");
897 assert_eq_sig!(AbiType::Bool, "bool");
898 assert_eq_sig!(AbiType::Cell, "cell");
899 assert_eq_sig!(AbiType::Address, "address");
900 assert_eq_sig!(AbiType::Bytes, "bytes");
901 assert_eq_sig!(AbiType::FixedBytes(123), "fixedbytes123");
902 assert_eq_sig!(AbiType::String, "string");
903 assert_eq_sig!(AbiType::Token, "gram");
904
905 assert_eq_sig!(AbiType::unnamed_tuple([]), "()");
906 assert_eq_sig!(AbiType::unnamed_tuple([AbiType::Uint(321)]), "(uint321)");
907 assert_eq_sig!(
908 AbiType::unnamed_tuple([AbiType::Uint(123), AbiType::Address]),
909 "(uint123,address)"
910 );
911
912 assert_eq_sig!(AbiType::array(AbiType::Address), "address[]");
913 assert_eq_sig!(
914 AbiType::array(AbiType::array(AbiType::Address)),
915 "address[][]"
916 );
917 assert_eq_sig!(AbiType::array(AbiType::unnamed_tuple([])), "()[]");
918 assert_eq_sig!(
919 AbiType::array(AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool])),
920 "(address,bool)[]"
921 );
922
923 assert_eq_sig!(AbiType::fixedarray(AbiType::Address, 10), "address[10]");
924 assert_eq_sig!(
925 AbiType::fixedarray(AbiType::fixedarray(AbiType::Address, 123), 321),
926 "address[123][321]"
927 );
928 assert_eq_sig!(
929 AbiType::fixedarray(AbiType::unnamed_tuple([]), 100),
930 "()[100]"
931 );
932 assert_eq_sig!(
933 AbiType::fixedarray(
934 AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool]),
935 1000
936 ),
937 "(address,bool)[1000]"
938 );
939
940 assert_eq_sig!(
941 AbiType::map(PlainAbiType::Uint(123), AbiType::Address),
942 "map(uint123,address)"
943 );
944 assert_eq_sig!(
945 AbiType::map(PlainAbiType::Uint(123), AbiType::unnamed_tuple([])),
946 "map(uint123,())"
947 );
948 assert_eq_sig!(
949 AbiType::map(
950 PlainAbiType::Uint(123),
951 AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool])
952 ),
953 "map(uint123,(address,bool))"
954 );
955 assert_eq_sig!(
956 AbiType::map(
957 PlainAbiType::Uint(123),
958 AbiType::fixedarray(AbiType::Address, 123)
959 ),
960 "map(uint123,address[123])"
961 );
962
963 assert_eq_sig!(AbiType::optional(AbiType::Address), "optional(address)");
964 assert_eq_sig!(
965 AbiType::optional(AbiType::unnamed_tuple([])),
966 "optional(())"
967 );
968 assert_eq_sig!(
969 AbiType::optional(AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool])),
970 "optional((address,bool))"
971 );
972 assert_eq_sig!(
973 AbiType::optional(AbiType::fixedarray(AbiType::Address, 123)),
974 "optional(address[123])"
975 );
976
977 assert_eq_sig!(AbiType::reference(AbiType::Address), "ref(address)");
978 assert_eq_sig!(AbiType::reference(AbiType::unnamed_tuple([])), "ref(())");
979 assert_eq_sig!(
980 AbiType::reference(AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool])),
981 "ref((address,bool))"
982 );
983 assert_eq_sig!(
984 AbiType::reference(AbiType::fixedarray(AbiType::Address, 123)),
985 "ref(address[123])"
986 );
987
988 assert_eq_sig!(
989 AbiType::array(AbiType::unnamed_tuple([
990 AbiType::Bool,
991 AbiType::Uint(123),
992 AbiType::array(AbiType::map(
993 PlainAbiType::Address,
994 AbiType::unnamed_tuple([AbiType::Uint(32), AbiType::String]),
995 )),
996 ])),
997 "(bool,uint123,map(address,(uint32,string))[])[]"
998 );
999 }
1000
1001 #[test]
1002 fn correct_simple_signature() {
1003 macro_rules! assert_eq_sig {
1004 ($expr:expr, $signature:literal) => {
1005 assert_eq!(format!("{}", ($expr).display_simple()), $signature)
1006 };
1007 }
1008
1009 assert_eq_sig!(AbiType::Uint(100), "uint100");
1010 assert_eq_sig!(AbiType::Int(100), "int100");
1011 assert_eq_sig!(AbiType::varuint(16), "varuint16");
1012 assert_eq_sig!(AbiType::varint(16), "varint16");
1013 assert_eq_sig!(AbiType::Bool, "bool");
1014 assert_eq_sig!(AbiType::Cell, "cell");
1015 assert_eq_sig!(AbiType::Address, "address");
1016 assert_eq_sig!(AbiType::Bytes, "bytes");
1017 assert_eq_sig!(AbiType::FixedBytes(123), "fixedbytes123");
1018 assert_eq_sig!(AbiType::String, "string");
1019 assert_eq_sig!(AbiType::Token, "gram");
1020
1021 assert_eq_sig!(AbiType::unnamed_tuple([]), "tuple");
1022 assert_eq_sig!(AbiType::unnamed_tuple([AbiType::Uint(321)]), "tuple");
1023 assert_eq_sig!(
1024 AbiType::unnamed_tuple([AbiType::Uint(123), AbiType::Address]),
1025 "tuple"
1026 );
1027
1028 assert_eq_sig!(AbiType::array(AbiType::Address), "address[]");
1029 assert_eq_sig!(
1030 AbiType::array(AbiType::array(AbiType::Address)),
1031 "address[][]"
1032 );
1033 assert_eq_sig!(AbiType::array(AbiType::unnamed_tuple([])), "tuple[]");
1034 assert_eq_sig!(
1035 AbiType::array(AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool])),
1036 "tuple[]"
1037 );
1038
1039 assert_eq_sig!(AbiType::fixedarray(AbiType::Address, 10), "address[10]");
1040 assert_eq_sig!(
1041 AbiType::fixedarray(AbiType::fixedarray(AbiType::Address, 123), 321),
1042 "address[123][321]"
1043 );
1044 assert_eq_sig!(
1045 AbiType::fixedarray(AbiType::unnamed_tuple([]), 100),
1046 "tuple[100]"
1047 );
1048 assert_eq_sig!(
1049 AbiType::fixedarray(
1050 AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool]),
1051 1000
1052 ),
1053 "tuple[1000]"
1054 );
1055
1056 assert_eq_sig!(
1057 AbiType::map(PlainAbiType::Uint(123), AbiType::Address),
1058 "map(uint123,address)"
1059 );
1060 assert_eq_sig!(
1061 AbiType::map(PlainAbiType::Uint(123), AbiType::unnamed_tuple([])),
1062 "map(uint123,tuple)"
1063 );
1064 assert_eq_sig!(
1065 AbiType::map(
1066 PlainAbiType::Uint(123),
1067 AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool])
1068 ),
1069 "map(uint123,tuple)"
1070 );
1071 assert_eq_sig!(
1072 AbiType::map(
1073 PlainAbiType::Uint(123),
1074 AbiType::fixedarray(AbiType::Address, 123)
1075 ),
1076 "map(uint123,address[123])"
1077 );
1078
1079 assert_eq_sig!(AbiType::optional(AbiType::Address), "optional(address)");
1080 assert_eq_sig!(
1081 AbiType::optional(AbiType::unnamed_tuple([])),
1082 "optional(tuple)"
1083 );
1084 assert_eq_sig!(
1085 AbiType::optional(AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool])),
1086 "optional(tuple)"
1087 );
1088 assert_eq_sig!(
1089 AbiType::optional(AbiType::fixedarray(AbiType::Address, 123)),
1090 "optional(address[123])"
1091 );
1092
1093 assert_eq_sig!(AbiType::reference(AbiType::Address), "ref(address)");
1094 assert_eq_sig!(AbiType::reference(AbiType::unnamed_tuple([])), "ref(tuple)");
1095 assert_eq_sig!(
1096 AbiType::reference(AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool])),
1097 "ref(tuple)"
1098 );
1099 assert_eq_sig!(
1100 AbiType::reference(AbiType::fixedarray(AbiType::Address, 123)),
1101 "ref(address[123])"
1102 );
1103
1104 assert_eq_sig!(
1105 AbiType::array(AbiType::unnamed_tuple([
1106 AbiType::Bool,
1107 AbiType::Uint(123),
1108 AbiType::array(AbiType::map(
1109 PlainAbiType::Address,
1110 AbiType::unnamed_tuple([AbiType::Uint(32), AbiType::String]),
1111 )),
1112 ])),
1113 "tuple[]"
1114 );
1115 }
1116
1117 #[test]
1118 fn from_to_json() {
1119 const RAW: &str = r#"{
1120 "name":"info",
1121 "type":"tuple",
1122 "components": [
1123 {"name":"total","type":"uint64"},
1124 {"name":"withdrawValue","type":"uint64"},
1125 {"name":"reinvest","type":"bool"},
1126 {"name":"reward","type":"uint64"},
1127 {"name":"stakes","type":"map(uint64,uint64)"},
1128 {"components":[{"name":"remainingAmount","type":"uint64"},{"name":"lastWithdrawalTime","type":"uint64"},{"name":"withdrawalPeriod","type":"uint32"},{"name":"withdrawalValue","type":"uint64"},{"name":"owner","type":"address"}],"name":"vestings","type":"map(uint64,tuple)"},
1129 {"components":[{"name":"remainingAmount","type":"uint64"},{"name":"lastWithdrawalTime","type":"uint64"},{"name":"withdrawalPeriod","type":"uint32"},{"name":"withdrawalValue","type":"uint64"},{"name":"owner","type":"address"}],"name":"locks","type":"map(uint64,tuple)"},
1130 {"name":"vestingDonor","type":"address"},
1131 {"name":"lockDonor","type":"address"}
1132 ]
1133 }"#;
1134
1135 let ty = serde_json::from_str::<NamedAbiType>(RAW).unwrap();
1136
1137 let complex_item_ty = AbiType::tuple([
1138 ("remainingAmount", u64::abi_type()),
1139 ("lastWithdrawalTime", u64::abi_type()),
1140 ("withdrawalPeriod", u32::abi_type()),
1141 ("withdrawalValue", u64::abi_type()),
1142 ("owner", IntAddr::abi_type()),
1143 ]);
1144
1145 assert_eq!(
1146 ty,
1147 NamedAbiType::new(
1148 "info",
1149 AbiType::Tuple(Arc::from(vec![
1150 NamedAbiType::new("total", u64::abi_type()),
1151 NamedAbiType::new("withdrawValue", u64::abi_type()),
1152 NamedAbiType::new("reinvest", bool::abi_type()),
1153 NamedAbiType::new("reward", u64::abi_type()),
1154 NamedAbiType::new("stakes", BTreeMap::<u64, u64>::abi_type()),
1155 NamedAbiType::new(
1156 "vestings",
1157 AbiType::map(u64::plain_abi_type(), complex_item_ty.clone())
1158 ),
1159 NamedAbiType::new(
1160 "locks",
1161 AbiType::map(u64::plain_abi_type(), complex_item_ty)
1162 ),
1163 NamedAbiType::new("vestingDonor", IntAddr::abi_type()),
1164 NamedAbiType::new("lockDonor", IntAddr::abi_type()),
1165 ]))
1166 )
1167 );
1168
1169 let normalized = serde_json::from_str::<serde_json::Value>(RAW).unwrap();
1170 let serialized = serde_json::to_value(ty).unwrap();
1171 assert_eq!(serialized, normalized);
1172 }
1173}