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::{AbiVersion, 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 AddressStd,
311 Bytes,
313 FixedBytes(usize),
315 String,
317 Token,
321 Tuple(Arc<[NamedAbiType]>),
323 Array(Arc<Self>),
325 FixedArray(Arc<Self>, usize),
327 Map(PlainAbiType, Arc<Self>),
329 Optional(Arc<Self>),
331 Ref(Arc<Self>),
333}
334
335impl AbiType {
336 pub fn named<T: Into<String>>(self, name: T) -> NamedAbiType {
338 NamedAbiType {
339 name: Arc::from(name.into()),
340 ty: self,
341 }
342 }
343
344 pub fn as_plain(&self) -> Option<PlainAbiType> {
346 Some(match self {
347 Self::Uint(n) => PlainAbiType::Uint(*n),
348 Self::Int(n) => PlainAbiType::Int(*n),
349 Self::Bool => PlainAbiType::Bool,
350 Self::Address => PlainAbiType::Address,
351 _ => return None,
352 })
353 }
354
355 pub fn max_size(&self, abi_version: AbiVersion) -> CellTreeStats {
357 match self {
358 Self::Uint(n) | Self::Int(n) => CellTreeStats {
359 bit_count: *n as _,
360 cell_count: 0,
361 },
362 Self::VarUint(n) | Self::VarInt(n) => {
363 let value_bytes: u8 = n.get() - 1;
364 let bit_count = (8 - value_bytes.leading_zeros()) as u64 + (value_bytes as u64 * 8);
365 CellTreeStats {
366 bit_count,
367 cell_count: 0,
368 }
369 }
370 Self::Bool => CellTreeStats {
371 bit_count: 1,
372 cell_count: 0,
373 },
374
375 Self::FixedBytes(bytes) if abi_version >= AbiVersion::V2_4 => CellTreeStats {
376 bit_count: *bytes as u64 * 8,
377 cell_count: 0,
378 },
379 Self::Cell | Self::Bytes | Self::FixedBytes(_) | Self::String | Self::Ref(_) => {
380 CellTreeStats {
381 bit_count: 0,
382 cell_count: 1,
383 }
384 }
385 Self::Address => CellTreeStats {
386 bit_count: IntAddr::BITS_MAX as _,
387 cell_count: 0,
388 },
389 Self::AddressStd => CellTreeStats {
390 bit_count: StdAddr::BITS_MAX as _,
391 cell_count: 0,
392 },
393 Self::Token => CellTreeStats {
394 bit_count: Tokens::MAX_BITS as _,
395 cell_count: 0,
396 },
397 Self::Array(_) => CellTreeStats {
398 bit_count: 33,
399 cell_count: 1,
400 },
401 Self::FixedArray(..) | Self::Map(..) => CellTreeStats {
402 bit_count: 1,
403 cell_count: 1,
404 },
405 Self::Optional(ty) => {
406 let ty_size = ty.max_size(abi_version);
407 if ty_size.bit_count < MAX_BIT_LEN as u64
408 && ty_size.cell_count < MAX_REF_COUNT as u64
409 {
410 CellTreeStats {
411 bit_count: 1,
412 cell_count: 0,
413 } + ty_size
414 } else {
415 CellTreeStats {
416 bit_count: 1,
417 cell_count: 1,
418 }
419 }
420 }
421 Self::Tuple(items) => items.iter().map(|item| item.ty.max_size(abi_version)).sum(),
422 }
423 }
424
425 pub fn max_bits(&self, abi_version: AbiVersion) -> usize {
427 self.max_size(abi_version).bit_count as usize
428 }
429
430 pub fn max_refs(&self, abi_version: AbiVersion) -> usize {
432 self.max_size(abi_version).cell_count as usize
433 }
434
435 fn components(&self) -> Option<&[NamedAbiType]> {
436 match self {
437 Self::Tuple(types) => Some(types),
438 Self::Array(ty) => ty.components(),
439 Self::FixedArray(ty, _) => ty.components(),
440 Self::Map(_, value_ty) => value_ty.components(),
441 Self::Optional(ty) => ty.components(),
442 Self::Ref(ty) => ty.components(),
443 _ => None,
444 }
445 }
446
447 pub(crate) fn components_mut(&mut self) -> Option<&mut Arc<[NamedAbiType]>> {
448 match self {
449 Self::Tuple(types) => Some(types),
450 Self::Array(ty) => Arc::make_mut(ty).components_mut(),
451 Self::FixedArray(ty, _) => Arc::make_mut(ty).components_mut(),
452 Self::Map(_, value_ty) => Arc::make_mut(value_ty).components_mut(),
453 Self::Optional(ty) => Arc::make_mut(ty).components_mut(),
454 Self::Ref(ty) => Arc::make_mut(ty).components_mut(),
455 _ => None,
456 }
457 }
458
459 pub fn flatten(self) -> AbiTypeFlatten {
467 match self {
468 AbiType::Tuple(tuple) => {
469 let mut items = tuple.to_vec();
470 items.reverse();
471 AbiTypeFlatten::Tuple(items)
472 }
473 ty => AbiTypeFlatten::Single(Some(ty)),
474 }
475 }
476
477 #[inline]
479 pub fn varuint(size: u8) -> Self {
480 Self::VarUint(NonZeroU8::new(size).unwrap())
481 }
482
483 #[inline]
485 pub fn varint(size: u8) -> Self {
486 Self::VarInt(NonZeroU8::new(size).unwrap())
487 }
488
489 #[inline]
491 pub fn tuple<I, T>(values: I) -> Self
492 where
493 I: IntoIterator<Item = T>,
494 NamedAbiType: From<T>,
495 {
496 Self::Tuple(values.into_iter().map(NamedAbiType::from).collect())
497 }
498
499 #[inline]
501 pub fn unnamed_tuple<I>(values: I) -> Self
502 where
503 I: IntoIterator<Item = AbiType>,
504 {
505 Self::Tuple(
506 values
507 .into_iter()
508 .enumerate()
509 .map(|(i, ty)| NamedAbiType::from_index(i, ty))
510 .collect(),
511 )
512 }
513
514 #[inline]
516 pub fn array<T>(ty: T) -> Self
517 where
518 Arc<AbiType>: From<T>,
519 {
520 Self::Array(Arc::<AbiType>::from(ty))
521 }
522
523 #[inline]
525 pub fn fixedarray<T>(ty: T, len: usize) -> Self
526 where
527 Arc<AbiType>: From<T>,
528 {
529 Self::FixedArray(Arc::<AbiType>::from(ty), len)
530 }
531
532 #[inline]
534 pub fn map<V>(key_ty: PlainAbiType, value_ty: V) -> Self
535 where
536 Arc<AbiType>: From<V>,
537 {
538 Self::Map(key_ty, Arc::<AbiType>::from(value_ty))
539 }
540
541 #[inline]
543 pub fn optional<T>(ty: T) -> Self
544 where
545 Arc<AbiType>: From<T>,
546 {
547 Self::Optional(Arc::<AbiType>::from(ty))
548 }
549
550 #[inline]
552 pub fn reference<T>(ty: T) -> Self
553 where
554 Arc<AbiType>: From<T>,
555 {
556 Self::Ref(Arc::<AbiType>::from(ty))
557 }
558
559 pub(crate) fn from_simple_str(s: &str) -> Result<Self, ParseAbiTypeError> {
560 if let Some(arr_ty) = s.strip_suffix(']') {
561 let (ty, len) = ok!(arr_ty
562 .rsplit_once('[')
563 .ok_or(ParseAbiTypeError::InvalidArrayType));
564
565 let len = if len.is_empty() {
566 None
567 } else {
568 Some(ok!(len
569 .parse::<usize>()
570 .map_err(ParseAbiTypeError::InvalidArrayLength)))
571 };
572
573 let ty = ok!(Self::from_simple_str(ty).map(Arc::new));
574 return Ok(match len {
575 None => Self::Array(ty),
576 Some(len) => Self::FixedArray(ty, len),
577 });
578 }
579
580 Ok(match s {
581 "bool" => Self::Bool,
582 "cell" => Self::Cell,
583 "address" => Self::Address,
584 "address_std" => Self::AddressStd,
585 "bytes" => Self::Bytes,
586 "string" => Self::String,
587 "gram" | "token" => Self::Token,
588 "tuple" => Self::Tuple(Arc::from([].as_slice())),
589 _ => {
590 if let Some(s) = s.strip_prefix("uint") {
591 Self::Uint(ok!(s
592 .parse::<u16>()
593 .map_err(ParseAbiTypeError::InvalidBitLen)))
594 } else if let Some(s) = s.strip_prefix("int") {
595 Self::Int(ok!(s
596 .parse::<u16>()
597 .map_err(ParseAbiTypeError::InvalidBitLen)))
598 } else if let Some(s) = s.strip_prefix("varuint") {
599 Self::VarUint(ok!(s
600 .parse::<NonZeroU8>()
601 .map_err(ParseAbiTypeError::InvalidByteLen)))
602 } else if let Some(s) = s.strip_prefix("varint") {
603 Self::VarInt(ok!(s
604 .parse::<NonZeroU8>()
605 .map_err(ParseAbiTypeError::InvalidByteLen)))
606 } else if let Some(s) = s.strip_prefix("fixedbytes") {
607 Self::FixedBytes(ok!(s
608 .parse::<usize>()
609 .map_err(ParseAbiTypeError::InvalidByteLen)))
610 } else if let Some(s) = s.strip_prefix("map(") {
611 let s = ok!(s
612 .strip_suffix(')')
613 .ok_or(ParseAbiTypeError::UnterminatedInnerType));
614 let (key_ty, value_ty) = ok!(s
615 .split_once(',')
616 .ok_or(ParseAbiTypeError::ValueTypeNotFound));
617
618 Self::Map(
619 ok!(PlainAbiType::from_str(key_ty)),
620 ok!(Self::from_simple_str(value_ty).map(Arc::new)),
621 )
622 } else if let Some(s) = s.strip_prefix("optional(") {
623 let s = ok!(s
624 .strip_suffix(')')
625 .ok_or(ParseAbiTypeError::UnterminatedInnerType));
626
627 Self::Optional(ok!(Self::from_simple_str(s).map(Arc::new)))
628 } else if let Some(s) = s.strip_prefix("ref(") {
629 let s = ok!(s
630 .strip_suffix(')')
631 .ok_or(ParseAbiTypeError::UnterminatedInnerType));
632
633 Self::Ref(ok!(Self::from_simple_str(s).map(Arc::new)))
634 } else {
635 return Err(ParseAbiTypeError::UnknownType);
636 }
637 }
638 })
639 }
640
641 fn display_simple(&self) -> DisplayAbiTypeSimple<'_> {
642 DisplayAbiTypeSimple(self)
643 }
644}
645
646impl AsRef<AbiType> for AbiType {
647 #[inline]
648 fn as_ref(&self) -> &AbiType {
649 self
650 }
651}
652
653impl std::fmt::Display for AbiType {
654 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
655 let s = match self {
656 Self::Uint(n) => return write!(f, "uint{n}"),
657 Self::Int(n) => return write!(f, "int{n}"),
658 Self::VarUint(n) => return write!(f, "varuint{n}"),
659 Self::VarInt(n) => return write!(f, "varint{n}"),
660 Self::Bool => "bool",
661 Self::Cell => "cell",
662 Self::Address => "address",
663 Self::AddressStd => "address_std",
664 Self::Bytes => "bytes",
665 Self::FixedBytes(n) => return write!(f, "fixedbytes{n}"),
666 Self::String => "string",
667 Self::Token => "gram",
668 Self::Tuple(items) => {
669 if items.is_empty() {
670 "()"
671 } else {
672 let mut first = true;
673 ok!(f.write_str("("));
674 for item in items.as_ref() {
675 if !std::mem::take(&mut first) {
676 ok!(f.write_str(","));
677 }
678 ok!(std::fmt::Display::fmt(&item.ty, f));
679 }
680 ")"
681 }
682 }
683 Self::Array(ty) => return write!(f, "{ty}[]"),
684 Self::FixedArray(ty, n) => return write!(f, "{ty}[{n}]"),
685 Self::Map(key_ty, value_ty) => return write!(f, "map({key_ty},{value_ty})"),
686 Self::Optional(ty) => return write!(f, "optional({ty})"),
687 Self::Ref(ty) => return write!(f, "ref({ty})"),
688 };
689 f.write_str(s)
690 }
691}
692
693#[derive(Clone, Copy)]
694struct DisplayAbiTypeSimple<'a>(&'a AbiType);
695
696impl std::fmt::Display for DisplayAbiTypeSimple<'_> {
697 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
698 match self.0 {
699 AbiType::Tuple(_) => f.write_str("tuple"),
700 AbiType::Array(ty) => write!(f, "{}[]", ty.display_simple()),
701 AbiType::FixedArray(ty, n) => write!(f, "{}[{n}]", ty.display_simple()),
702 AbiType::Map(key_ty, value_ty) => {
703 write!(f, "map({key_ty},{})", value_ty.display_simple())
704 }
705 AbiType::Optional(ty) => write!(f, "optional({})", ty.display_simple()),
706 AbiType::Ref(ty) => write!(f, "ref({})", ty.display_simple()),
707 ty => std::fmt::Display::fmt(ty, f),
708 }
709 }
710}
711
712impl PartialEq for WithoutName<AbiType> {
713 fn eq(&self, other: &Self) -> bool {
714 match (&self.0, &other.0) {
715 (AbiType::Uint(a), AbiType::Uint(b)) => a.eq(b),
716 (AbiType::Int(a), AbiType::Int(b)) => a.eq(b),
717 (AbiType::VarUint(a), AbiType::VarUint(b)) => a.eq(b),
718 (AbiType::VarInt(a), AbiType::VarInt(b)) => a.eq(b),
719 (AbiType::Bool, AbiType::Bool) => true,
720 (AbiType::Cell, AbiType::Cell) => true,
721 (AbiType::Address, AbiType::Address) => true,
722 (AbiType::AddressStd, AbiType::AddressStd) => true,
723 (AbiType::Bytes, AbiType::Bytes) => true,
724 (AbiType::FixedBytes(a), AbiType::FixedBytes(b)) => a.eq(b),
725 (AbiType::String, AbiType::String) => true,
726 (AbiType::Token, AbiType::Token) => true,
727 (AbiType::Tuple(a), AbiType::Tuple(b)) => {
728 WithoutName::wrap_slice(a.as_ref()).eq(WithoutName::wrap_slice(b.as_ref()))
729 }
730 (AbiType::Array(a), AbiType::Array(b)) => {
731 WithoutName::wrap(a.as_ref()).eq(WithoutName::wrap(b.as_ref()))
732 }
733 (AbiType::FixedArray(a, an), AbiType::FixedArray(b, bn)) => {
734 WithoutName::wrap(a.as_ref()).eq(WithoutName::wrap(b.as_ref())) && an.eq(bn)
735 }
736 (AbiType::Map(ak, av), AbiType::Map(bk, bv)) => {
737 ak.eq(bk) && WithoutName::wrap(av.as_ref()).eq(WithoutName::wrap(bv.as_ref()))
738 }
739 (AbiType::Optional(a), AbiType::Optional(b)) => {
740 WithoutName::wrap(a.as_ref()).eq(WithoutName::wrap(b.as_ref()))
741 }
742 (AbiType::Ref(a), AbiType::Ref(b)) => {
743 WithoutName::wrap(a.as_ref()).eq(WithoutName::wrap(b.as_ref()))
744 }
745 _ => false,
746 }
747 }
748}
749
750impl Hash for WithoutName<AbiType> {
751 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
752 core::mem::discriminant(&self.0).hash(state);
753 match &self.0 {
754 AbiType::Uint(x) => x.hash(state),
755 AbiType::Int(x) => x.hash(state),
756 AbiType::VarUint(x) => x.hash(state),
757 AbiType::VarInt(x) => x.hash(state),
758 AbiType::Bool => {}
759 AbiType::Cell => {}
760 AbiType::Address => {}
761 AbiType::AddressStd => {}
762 AbiType::Bytes => {}
763 AbiType::FixedBytes(x) => x.hash(state),
764 AbiType::String => {}
765 AbiType::Token => {}
766 AbiType::Tuple(x) => WithoutName::wrap_slice(x.as_ref()).hash(state),
767 AbiType::Array(x) => WithoutName::wrap(x.as_ref()).hash(state),
768 AbiType::FixedArray(x, n) => {
769 WithoutName::wrap(x.as_ref()).hash(state);
770 n.hash(state);
771 }
772 AbiType::Map(k, v) => {
773 k.hash(state);
774 WithoutName::wrap(v.as_ref()).hash(state);
775 }
776 AbiType::Optional(x) => WithoutName::wrap(x.as_ref()).hash(state),
777 AbiType::Ref(x) => WithoutName::wrap(x.as_ref()).hash(state),
778 }
779 }
780}
781
782#[derive(Clone)]
784pub enum AbiTypeFlatten {
785 #[doc(hidden)]
786 Single(Option<AbiType>),
787 #[doc(hidden)]
788 Tuple(Vec<NamedAbiType>),
789}
790
791impl Iterator for AbiTypeFlatten {
792 type Item = AbiType;
793
794 fn size_hint(&self) -> (usize, Option<usize>) {
795 let size = match self {
796 Self::Single(item) => item.is_some() as usize,
797 Self::Tuple(items) => items.len(),
798 };
799 (size, Some(size))
800 }
801
802 fn next(&mut self) -> Option<Self::Item> {
803 match self {
804 Self::Single(item) => item.take(),
805 Self::Tuple(items) => items.pop().map(|item| item.ty),
806 }
807 }
808}
809
810#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
813pub enum PlainAbiType {
814 Uint(u16),
816 Int(u16),
818 Bool,
820 Address,
824}
825
826impl PlainAbiType {
827 pub fn key_bits(&self) -> u16 {
829 match self {
830 Self::Uint(n) | Self::Int(n) => *n,
831 Self::Bool => 1,
832 Self::Address => StdAddr::BITS_WITHOUT_ANYCAST,
833 }
834 }
835}
836
837impl From<PlainAbiType> for AbiType {
838 fn from(value: PlainAbiType) -> Self {
839 match value {
840 PlainAbiType::Uint(n) => Self::Uint(n),
841 PlainAbiType::Int(n) => Self::Int(n),
842 PlainAbiType::Bool => Self::Bool,
843 PlainAbiType::Address => Self::Address,
844 }
845 }
846}
847
848impl FromStr for PlainAbiType {
849 type Err = ParseAbiTypeError;
850
851 fn from_str(s: &str) -> Result<Self, Self::Err> {
852 Ok(match s {
853 "bool" => Self::Bool,
854 "address" => Self::Address,
855 s => {
856 if let Some(s) = s.strip_prefix("uint") {
857 Self::Uint(ok!(s
858 .parse::<u16>()
859 .map_err(ParseAbiTypeError::InvalidBitLen)))
860 } else if let Some(s) = s.strip_prefix("int") {
861 Self::Int(ok!(s
862 .parse::<u16>()
863 .map_err(ParseAbiTypeError::InvalidBitLen)))
864 } else {
865 return Err(ParseAbiTypeError::UnknownType);
866 }
867 }
868 })
869 }
870}
871
872impl std::fmt::Display for PlainAbiType {
873 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
874 let s = match self {
875 Self::Uint(n) => return write!(f, "uint{n}"),
876 Self::Int(n) => return write!(f, "int{n}"),
877 Self::Bool => "bool",
878 Self::Address => "address",
879 };
880 f.write_str(s)
881 }
882}
883
884#[inline]
885fn collect_str<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
886where
887 T: std::fmt::Display,
888 S: serde::ser::Serializer,
889{
890 serializer.collect_str(value)
891}
892
893#[cfg(test)]
894mod tests {
895 use std::collections::BTreeMap;
896
897 use super::*;
898 use crate::abi::traits::{WithAbiType, WithPlainAbiType};
899
900 #[test]
901 fn correct_full_signature() {
902 macro_rules! assert_eq_sig {
903 ($expr:expr, $signature:literal) => {
904 assert_eq!(($expr).to_string(), $signature)
905 };
906 }
907
908 assert_eq_sig!(AbiType::Uint(100), "uint100");
909 assert_eq_sig!(AbiType::Int(100), "int100");
910 assert_eq_sig!(AbiType::varuint(16), "varuint16");
911 assert_eq_sig!(AbiType::varint(16), "varint16");
912 assert_eq_sig!(AbiType::Bool, "bool");
913 assert_eq_sig!(AbiType::Cell, "cell");
914 assert_eq_sig!(AbiType::Address, "address");
915 assert_eq_sig!(AbiType::Bytes, "bytes");
916 assert_eq_sig!(AbiType::FixedBytes(123), "fixedbytes123");
917 assert_eq_sig!(AbiType::String, "string");
918 assert_eq_sig!(AbiType::Token, "gram");
919
920 assert_eq_sig!(AbiType::unnamed_tuple([]), "()");
921 assert_eq_sig!(AbiType::unnamed_tuple([AbiType::Uint(321)]), "(uint321)");
922 assert_eq_sig!(
923 AbiType::unnamed_tuple([AbiType::Uint(123), AbiType::Address]),
924 "(uint123,address)"
925 );
926
927 assert_eq_sig!(AbiType::array(AbiType::Address), "address[]");
928 assert_eq_sig!(
929 AbiType::array(AbiType::array(AbiType::Address)),
930 "address[][]"
931 );
932 assert_eq_sig!(AbiType::array(AbiType::unnamed_tuple([])), "()[]");
933 assert_eq_sig!(
934 AbiType::array(AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool])),
935 "(address,bool)[]"
936 );
937
938 assert_eq_sig!(AbiType::fixedarray(AbiType::Address, 10), "address[10]");
939 assert_eq_sig!(
940 AbiType::fixedarray(AbiType::fixedarray(AbiType::Address, 123), 321),
941 "address[123][321]"
942 );
943 assert_eq_sig!(
944 AbiType::fixedarray(AbiType::unnamed_tuple([]), 100),
945 "()[100]"
946 );
947 assert_eq_sig!(
948 AbiType::fixedarray(
949 AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool]),
950 1000
951 ),
952 "(address,bool)[1000]"
953 );
954
955 assert_eq_sig!(
956 AbiType::map(PlainAbiType::Uint(123), AbiType::Address),
957 "map(uint123,address)"
958 );
959 assert_eq_sig!(
960 AbiType::map(PlainAbiType::Uint(123), AbiType::unnamed_tuple([])),
961 "map(uint123,())"
962 );
963 assert_eq_sig!(
964 AbiType::map(
965 PlainAbiType::Uint(123),
966 AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool])
967 ),
968 "map(uint123,(address,bool))"
969 );
970 assert_eq_sig!(
971 AbiType::map(
972 PlainAbiType::Uint(123),
973 AbiType::fixedarray(AbiType::Address, 123)
974 ),
975 "map(uint123,address[123])"
976 );
977
978 assert_eq_sig!(AbiType::optional(AbiType::Address), "optional(address)");
979 assert_eq_sig!(
980 AbiType::optional(AbiType::unnamed_tuple([])),
981 "optional(())"
982 );
983 assert_eq_sig!(
984 AbiType::optional(AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool])),
985 "optional((address,bool))"
986 );
987 assert_eq_sig!(
988 AbiType::optional(AbiType::fixedarray(AbiType::Address, 123)),
989 "optional(address[123])"
990 );
991
992 assert_eq_sig!(AbiType::reference(AbiType::Address), "ref(address)");
993 assert_eq_sig!(AbiType::reference(AbiType::unnamed_tuple([])), "ref(())");
994 assert_eq_sig!(
995 AbiType::reference(AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool])),
996 "ref((address,bool))"
997 );
998 assert_eq_sig!(
999 AbiType::reference(AbiType::fixedarray(AbiType::Address, 123)),
1000 "ref(address[123])"
1001 );
1002
1003 assert_eq_sig!(
1004 AbiType::array(AbiType::unnamed_tuple([
1005 AbiType::Bool,
1006 AbiType::Uint(123),
1007 AbiType::array(AbiType::map(
1008 PlainAbiType::Address,
1009 AbiType::unnamed_tuple([AbiType::Uint(32), AbiType::String]),
1010 )),
1011 ])),
1012 "(bool,uint123,map(address,(uint32,string))[])[]"
1013 );
1014 }
1015
1016 #[test]
1017 fn correct_simple_signature() {
1018 macro_rules! assert_eq_sig {
1019 ($expr:expr, $signature:literal) => {
1020 assert_eq!(format!("{}", ($expr).display_simple()), $signature)
1021 };
1022 }
1023
1024 assert_eq_sig!(AbiType::Uint(100), "uint100");
1025 assert_eq_sig!(AbiType::Int(100), "int100");
1026 assert_eq_sig!(AbiType::varuint(16), "varuint16");
1027 assert_eq_sig!(AbiType::varint(16), "varint16");
1028 assert_eq_sig!(AbiType::Bool, "bool");
1029 assert_eq_sig!(AbiType::Cell, "cell");
1030 assert_eq_sig!(AbiType::Address, "address");
1031 assert_eq_sig!(AbiType::Bytes, "bytes");
1032 assert_eq_sig!(AbiType::FixedBytes(123), "fixedbytes123");
1033 assert_eq_sig!(AbiType::String, "string");
1034 assert_eq_sig!(AbiType::Token, "gram");
1035
1036 assert_eq_sig!(AbiType::unnamed_tuple([]), "tuple");
1037 assert_eq_sig!(AbiType::unnamed_tuple([AbiType::Uint(321)]), "tuple");
1038 assert_eq_sig!(
1039 AbiType::unnamed_tuple([AbiType::Uint(123), AbiType::Address]),
1040 "tuple"
1041 );
1042
1043 assert_eq_sig!(AbiType::array(AbiType::Address), "address[]");
1044 assert_eq_sig!(
1045 AbiType::array(AbiType::array(AbiType::Address)),
1046 "address[][]"
1047 );
1048 assert_eq_sig!(AbiType::array(AbiType::unnamed_tuple([])), "tuple[]");
1049 assert_eq_sig!(
1050 AbiType::array(AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool])),
1051 "tuple[]"
1052 );
1053
1054 assert_eq_sig!(AbiType::fixedarray(AbiType::Address, 10), "address[10]");
1055 assert_eq_sig!(
1056 AbiType::fixedarray(AbiType::fixedarray(AbiType::Address, 123), 321),
1057 "address[123][321]"
1058 );
1059 assert_eq_sig!(
1060 AbiType::fixedarray(AbiType::unnamed_tuple([]), 100),
1061 "tuple[100]"
1062 );
1063 assert_eq_sig!(
1064 AbiType::fixedarray(
1065 AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool]),
1066 1000
1067 ),
1068 "tuple[1000]"
1069 );
1070
1071 assert_eq_sig!(
1072 AbiType::map(PlainAbiType::Uint(123), AbiType::Address),
1073 "map(uint123,address)"
1074 );
1075 assert_eq_sig!(
1076 AbiType::map(PlainAbiType::Uint(123), AbiType::unnamed_tuple([])),
1077 "map(uint123,tuple)"
1078 );
1079 assert_eq_sig!(
1080 AbiType::map(
1081 PlainAbiType::Uint(123),
1082 AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool])
1083 ),
1084 "map(uint123,tuple)"
1085 );
1086 assert_eq_sig!(
1087 AbiType::map(
1088 PlainAbiType::Uint(123),
1089 AbiType::fixedarray(AbiType::Address, 123)
1090 ),
1091 "map(uint123,address[123])"
1092 );
1093
1094 assert_eq_sig!(AbiType::optional(AbiType::Address), "optional(address)");
1095 assert_eq_sig!(
1096 AbiType::optional(AbiType::unnamed_tuple([])),
1097 "optional(tuple)"
1098 );
1099 assert_eq_sig!(
1100 AbiType::optional(AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool])),
1101 "optional(tuple)"
1102 );
1103 assert_eq_sig!(
1104 AbiType::optional(AbiType::fixedarray(AbiType::Address, 123)),
1105 "optional(address[123])"
1106 );
1107
1108 assert_eq_sig!(AbiType::reference(AbiType::Address), "ref(address)");
1109 assert_eq_sig!(AbiType::reference(AbiType::unnamed_tuple([])), "ref(tuple)");
1110 assert_eq_sig!(
1111 AbiType::reference(AbiType::unnamed_tuple([AbiType::Address, AbiType::Bool])),
1112 "ref(tuple)"
1113 );
1114 assert_eq_sig!(
1115 AbiType::reference(AbiType::fixedarray(AbiType::Address, 123)),
1116 "ref(address[123])"
1117 );
1118
1119 assert_eq_sig!(
1120 AbiType::array(AbiType::unnamed_tuple([
1121 AbiType::Bool,
1122 AbiType::Uint(123),
1123 AbiType::array(AbiType::map(
1124 PlainAbiType::Address,
1125 AbiType::unnamed_tuple([AbiType::Uint(32), AbiType::String]),
1126 )),
1127 ])),
1128 "tuple[]"
1129 );
1130 }
1131
1132 #[test]
1133 fn from_to_json() {
1134 const RAW: &str = r#"{
1135 "name":"info",
1136 "type":"tuple",
1137 "components": [
1138 {"name":"total","type":"uint64"},
1139 {"name":"withdrawValue","type":"uint64"},
1140 {"name":"reinvest","type":"bool"},
1141 {"name":"reward","type":"uint64"},
1142 {"name":"stakes","type":"map(uint64,uint64)"},
1143 {"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)"},
1144 {"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)"},
1145 {"name":"vestingDonor","type":"address"},
1146 {"name":"lockDonor","type":"address"}
1147 ]
1148 }"#;
1149
1150 let ty = serde_json::from_str::<NamedAbiType>(RAW).unwrap();
1151
1152 let complex_item_ty = AbiType::tuple([
1153 ("remainingAmount", u64::abi_type()),
1154 ("lastWithdrawalTime", u64::abi_type()),
1155 ("withdrawalPeriod", u32::abi_type()),
1156 ("withdrawalValue", u64::abi_type()),
1157 ("owner", IntAddr::abi_type()),
1158 ]);
1159
1160 assert_eq!(
1161 ty,
1162 NamedAbiType::new(
1163 "info",
1164 AbiType::Tuple(Arc::from(vec![
1165 NamedAbiType::new("total", u64::abi_type()),
1166 NamedAbiType::new("withdrawValue", u64::abi_type()),
1167 NamedAbiType::new("reinvest", bool::abi_type()),
1168 NamedAbiType::new("reward", u64::abi_type()),
1169 NamedAbiType::new("stakes", BTreeMap::<u64, u64>::abi_type()),
1170 NamedAbiType::new(
1171 "vestings",
1172 AbiType::map(u64::plain_abi_type(), complex_item_ty.clone())
1173 ),
1174 NamedAbiType::new(
1175 "locks",
1176 AbiType::map(u64::plain_abi_type(), complex_item_ty)
1177 ),
1178 NamedAbiType::new("vestingDonor", IntAddr::abi_type()),
1179 NamedAbiType::new("lockDonor", IntAddr::abi_type()),
1180 ]))
1181 )
1182 );
1183
1184 let normalized = serde_json::from_str::<serde_json::Value>(RAW).unwrap();
1185 let serialized = serde_json::to_value(ty).unwrap();
1186 assert_eq!(serialized, normalized);
1187 }
1188}