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