1use std::collections::BTreeMap;
2use std::num::NonZeroU8;
3use std::sync::Arc;
4
5use anyhow::Result;
6use bytes::Bytes;
7use num_bigint::{BigInt, BigUint};
8
9use super::ty::*;
10use super::{IntoAbi, IntoPlainAbi, WithAbiType, WithPlainAbiType, WithoutName};
11use crate::abi::error::AbiError;
12use crate::cell::{Cell, CellFamily};
13use crate::models::{AnyAddr, IntAddr, StdAddr};
14use crate::num::Tokens;
15
16mod de;
17pub(crate) mod ser;
18
19#[derive(Debug, Clone, Eq, PartialEq)]
21pub struct NamedAbiValue {
22 pub name: Arc<str>,
24 pub value: AbiValue,
26}
27
28impl NamedAbiValue {
29 pub fn check_types(items: &[Self], types: &[NamedAbiType]) -> Result<()> {
31 anyhow::ensure!(Self::have_types(items, types), AbiError::TypeMismatch {
32 expected: DisplayTupleType(types).to_string().into(),
33 ty: DisplayTupleValueType(items).to_string().into(),
34 });
35 Ok(())
36 }
37
38 pub fn have_types(items: &[Self], types: &[NamedAbiType]) -> bool {
40 items.len() == types.len()
41 && items
42 .iter()
43 .zip(types.iter())
44 .all(|(item, t)| item.value.has_type(&t.ty))
45 }
46
47 pub fn from_index(index: usize, value: AbiValue) -> Self {
49 Self {
50 name: format!("value{index}").into(),
51 value,
52 }
53 }
54
55 pub fn check_type<T: AsRef<AbiType>>(&self, ty: T) -> Result<()> {
57 fn type_mismatch(this: &NamedAbiValue, expected: &AbiType) -> AbiError {
58 AbiError::TypeMismatch {
59 expected: expected.to_string().into(),
60 ty: this.value.display_type().to_string().into(),
61 }
62 }
63 let ty = ty.as_ref();
64 anyhow::ensure!(self.value.has_type(ty), type_mismatch(self, ty));
65 Ok(())
66 }
67}
68
69impl From<(String, AbiValue)> for NamedAbiValue {
70 #[inline]
71 fn from((name, value): (String, AbiValue)) -> Self {
72 Self {
73 name: name.into(),
74 value,
75 }
76 }
77}
78
79impl<'a> From<(&'a str, AbiValue)> for NamedAbiValue {
80 #[inline]
81 fn from((name, value): (&'a str, AbiValue)) -> Self {
82 Self {
83 name: Arc::from(name),
84 value,
85 }
86 }
87}
88
89impl From<(usize, AbiValue)> for NamedAbiValue {
90 #[inline]
91 fn from((index, value): (usize, AbiValue)) -> Self {
92 Self::from_index(index, value)
93 }
94}
95
96impl NamedAbiType {
97 pub fn make_default_value(&self) -> NamedAbiValue {
99 NamedAbiValue {
100 name: self.name.clone(),
101 value: self.ty.make_default_value(),
102 }
103 }
104}
105
106impl PartialEq for WithoutName<NamedAbiValue> {
107 #[inline]
108 fn eq(&self, other: &Self) -> bool {
109 WithoutName::wrap(&self.0.value).eq(WithoutName::wrap(&other.0.value))
110 }
111}
112
113impl std::borrow::Borrow<WithoutName<AbiValue>> for WithoutName<NamedAbiValue> {
114 fn borrow(&self) -> &WithoutName<AbiValue> {
115 WithoutName::wrap(&self.0.value)
116 }
117}
118
119#[derive(Debug, Clone, Eq, PartialEq)]
121pub enum AbiValue {
122 Uint(u16, BigUint),
124 Int(u16, BigInt),
126 VarUint(NonZeroU8, BigUint),
128 VarInt(NonZeroU8, BigInt),
130 Bool(bool),
132 Cell(Cell),
136 Address(Box<AnyAddr>),
140 AddressStd(Option<Box<StdAddr>>),
143 Bytes(Bytes),
145 FixedBytes(Bytes),
147 String(String),
149 Token(Tokens),
153 Tuple(Vec<NamedAbiValue>),
155 Array(Arc<AbiType>, Vec<Self>),
157 FixedArray(Arc<AbiType>, Vec<Self>),
159 Map(
161 PlainAbiType,
162 Arc<AbiType>,
163 BTreeMap<PlainAbiValue, AbiValue>,
164 ),
165 Optional(Arc<AbiType>, Option<Box<Self>>),
167 Ref(Box<Self>),
169}
170
171impl AbiValue {
172 pub fn named<T: Into<String>>(self, name: T) -> NamedAbiValue {
174 NamedAbiValue {
175 name: Arc::from(name.into()),
176 value: self,
177 }
178 }
179
180 pub fn check_type<T: AsRef<AbiType>>(&self, ty: T) -> Result<()> {
182 fn type_mismatch(value: &AbiValue, expected: &AbiType) -> AbiError {
183 AbiError::TypeMismatch {
184 expected: expected.to_string().into(),
185 ty: value.display_type().to_string().into(),
186 }
187 }
188 let ty = ty.as_ref();
189 anyhow::ensure!(self.has_type(ty), type_mismatch(self, ty));
190 Ok(())
191 }
192
193 pub fn has_type(&self, ty: &AbiType) -> bool {
195 match (self, ty) {
196 (Self::Uint(n, _), AbiType::Uint(t)) => n == t,
197 (Self::Int(n, _), AbiType::Int(t)) => n == t,
198 (Self::VarUint(n, _), AbiType::VarUint(t)) => n == t,
199 (Self::VarInt(n, _), AbiType::VarInt(t)) => n == t,
200 (Self::FixedBytes(bytes), AbiType::FixedBytes(len)) => bytes.len() == *len,
201 (Self::Tuple(items), AbiType::Tuple(types)) => NamedAbiValue::have_types(items, types),
202 (Self::Array(ty, _), AbiType::Array(t)) => ty == t,
203 (Self::FixedArray(ty, items), AbiType::FixedArray(t, len)) => {
204 items.len() == *len && ty == t
205 }
206 (Self::Map(key_ty, value_ty, _), AbiType::Map(k, v)) => key_ty == k && value_ty == v,
207 (Self::Optional(ty, _), AbiType::Optional(t)) => ty == t,
208 (Self::Ref(value), AbiType::Ref(t)) => value.has_type(t),
209 (Self::Bool(_), AbiType::Bool)
210 | (Self::Cell(_), AbiType::Cell)
211 | (Self::Address(_), AbiType::Address)
212 | (Self::AddressStd(_), AbiType::AddressStd)
213 | (Self::Bytes(_), AbiType::Bytes)
214 | (Self::String(_), AbiType::String)
215 | (Self::Token(_), AbiType::Token) => true,
216 _ => false,
217 }
218 }
219
220 pub fn get_type(&self) -> AbiType {
222 match self {
223 AbiValue::Uint(n, _) => AbiType::Uint(*n),
224 AbiValue::Int(n, _) => AbiType::Int(*n),
225 AbiValue::VarUint(n, _) => AbiType::VarUint(*n),
226 AbiValue::VarInt(n, _) => AbiType::VarInt(*n),
227 AbiValue::Bool(_) => AbiType::Bool,
228 AbiValue::Cell(_) => AbiType::Cell,
229 AbiValue::Address(_) => AbiType::Address,
230 AbiValue::AddressStd(_) => AbiType::AddressStd,
231 AbiValue::Bytes(_) => AbiType::Bytes,
232 AbiValue::FixedBytes(bytes) => AbiType::FixedBytes(bytes.len()),
233 AbiValue::String(_) => AbiType::String,
234 AbiValue::Token(_) => AbiType::Token,
235 AbiValue::Tuple(items) => AbiType::Tuple(
236 items
237 .iter()
238 .map(|item| NamedAbiType::new(item.name.clone(), item.value.get_type()))
239 .collect(),
240 ),
241 AbiValue::Array(ty, _) => AbiType::Array(ty.clone()),
242 AbiValue::FixedArray(ty, items) => AbiType::FixedArray(ty.clone(), items.len()),
243 AbiValue::Map(key_ty, value_ty, _) => AbiType::Map(*key_ty, value_ty.clone()),
244 AbiValue::Optional(ty, _) => AbiType::Optional(ty.clone()),
245 AbiValue::Ref(value) => AbiType::Ref(Arc::new(value.get_type())),
246 }
247 }
248
249 #[inline]
251 pub fn display_type(&self) -> impl std::fmt::Display + '_ {
252 DisplayValueType(self)
253 }
254
255 #[inline]
257 pub fn uint<T>(bits: u16, value: T) -> Self
258 where
259 BigUint: From<T>,
260 {
261 Self::Uint(bits, BigUint::from(value))
262 }
263
264 #[inline]
266 pub fn int<T>(bits: u16, value: T) -> Self
267 where
268 BigInt: From<T>,
269 {
270 Self::Int(bits, BigInt::from(value))
271 }
272
273 #[inline]
275 pub fn varuint<T>(size: u8, value: T) -> Self
276 where
277 BigUint: From<T>,
278 {
279 Self::VarUint(NonZeroU8::new(size).unwrap(), BigUint::from(value))
280 }
281
282 #[inline]
284 pub fn varint<T>(size: u8, value: T) -> Self
285 where
286 BigInt: From<T>,
287 {
288 Self::VarInt(NonZeroU8::new(size).unwrap(), BigInt::from(value))
289 }
290
291 #[inline]
293 pub fn address<T>(value: T) -> Self
294 where
295 AnyAddr: From<T>,
296 {
297 Self::Address(Box::new(AnyAddr::from(value)))
298 }
299
300 #[inline]
302 pub fn address_std<T>(value: T) -> Self
303 where
304 StdAddr: From<T>,
305 {
306 Self::AddressStd(Some(Box::new(StdAddr::from(value))))
308 }
309
310 #[inline]
312 pub fn bytes<T>(value: T) -> Self
313 where
314 Bytes: From<T>,
315 {
316 Self::Bytes(Bytes::from(value))
317 }
318
319 #[inline]
321 pub fn fixedbytes<T>(value: T) -> Self
322 where
323 Bytes: From<T>,
324 {
325 Self::FixedBytes(Bytes::from(value))
326 }
327
328 #[inline]
330 pub fn tuple<I, T>(values: I) -> Self
331 where
332 I: IntoIterator<Item = T>,
333 NamedAbiValue: From<T>,
334 {
335 Self::Tuple(values.into_iter().map(NamedAbiValue::from).collect())
336 }
337
338 #[inline]
340 pub fn unnamed_tuple<I>(values: I) -> Self
341 where
342 I: IntoIterator<Item = AbiValue>,
343 {
344 Self::Tuple(
345 values
346 .into_iter()
347 .enumerate()
348 .map(|(i, value)| NamedAbiValue::from_index(i, value))
349 .collect(),
350 )
351 }
352
353 #[inline]
355 pub fn array<T, I>(values: I) -> Self
356 where
357 T: WithAbiType + IntoAbi,
358 I: IntoIterator<Item = T>,
359 {
360 Self::Array(
361 Arc::new(T::abi_type()),
362 values.into_iter().map(IntoAbi::into_abi).collect(),
363 )
364 }
365
366 #[inline]
368 pub fn fixedarray<T, I>(values: I) -> Self
369 where
370 T: WithAbiType + IntoAbi,
371 I: IntoIterator<Item = T>,
372 {
373 Self::FixedArray(
374 Arc::new(T::abi_type()),
375 values.into_iter().map(IntoAbi::into_abi).collect(),
376 )
377 }
378
379 #[inline]
381 pub fn map<K, V, I>(entries: I) -> Self
382 where
383 K: WithPlainAbiType + IntoPlainAbi,
384 V: WithAbiType + IntoAbi,
385 I: IntoIterator<Item = (K, V)>,
386 {
387 Self::Map(
388 K::plain_abi_type(),
389 Arc::new(V::abi_type()),
390 entries
391 .into_iter()
392 .map(|(key, value)| (key.into_plain_abi(), value.into_abi()))
393 .collect(),
394 )
395 }
396
397 #[inline]
399 pub fn optional<T>(value: Option<T>) -> Self
400 where
401 T: WithAbiType + IntoAbi,
402 {
403 Self::Optional(
404 Arc::new(T::abi_type()),
405 value.map(T::into_abi).map(Box::new),
406 )
407 }
408
409 #[inline]
411 pub fn reference<T>(value: T) -> Self
412 where
413 T: IntoAbi,
414 {
415 Self::Ref(Box::new(value.into_abi()))
416 }
417}
418
419impl AbiType {
420 pub fn make_default_value(&self) -> AbiValue {
422 match self {
423 AbiType::Uint(bits) => AbiValue::Uint(*bits, BigUint::default()),
424 AbiType::Int(bits) => AbiValue::Int(*bits, BigInt::default()),
425 AbiType::VarUint(size) => AbiValue::VarUint(*size, BigUint::default()),
426 AbiType::VarInt(size) => AbiValue::VarInt(*size, BigInt::default()),
427 AbiType::Bool => AbiValue::Bool(false),
428 AbiType::Cell => AbiValue::Cell(Cell::empty_cell()),
429 AbiType::Address => AbiValue::Address(Box::default()),
430 AbiType::AddressStd => AbiValue::AddressStd(None),
431 AbiType::Bytes => AbiValue::Bytes(Bytes::default()),
432 AbiType::FixedBytes(len) => AbiValue::FixedBytes(Bytes::from(vec![0u8; *len])),
433 AbiType::String => AbiValue::String(String::default()),
434 AbiType::Token => AbiValue::Token(Tokens::ZERO),
435 AbiType::Tuple(items) => {
436 let mut tuple = Vec::with_capacity(items.len());
437 for item in items.as_ref() {
438 tuple.push(item.make_default_value());
439 }
440 AbiValue::Tuple(tuple)
441 }
442 AbiType::Array(ty) => AbiValue::Array(ty.clone(), Vec::new()),
443 AbiType::FixedArray(ty, items) => {
444 AbiValue::FixedArray(ty.clone(), vec![ty.make_default_value(); *items])
445 }
446 AbiType::Map(key_ty, value_ty) => {
447 AbiValue::Map(*key_ty, value_ty.clone(), BTreeMap::default())
448 }
449 AbiType::Optional(ty) => AbiValue::Optional(ty.clone(), None),
450 AbiType::Ref(ty) => AbiValue::Ref(Box::new(ty.make_default_value())),
451 }
452 }
453}
454
455impl PartialEq for WithoutName<AbiValue> {
456 fn eq(&self, other: &Self) -> bool {
457 match (&self.0, &other.0) {
458 (AbiValue::Uint(an, a), AbiValue::Uint(bn, b)) => an.eq(bn) && a.eq(b),
459 (AbiValue::Int(an, a), AbiValue::Int(bn, b)) => an.eq(bn) && a.eq(b),
460 (AbiValue::VarUint(an, a), AbiValue::VarUint(bn, b)) => an.eq(bn) && a.eq(b),
461 (AbiValue::VarInt(an, a), AbiValue::VarInt(bn, b)) => an.eq(bn) && a.eq(b),
462 (AbiValue::Bool(a), AbiValue::Bool(b)) => a.eq(b),
463 (AbiValue::Cell(a), AbiValue::Cell(b)) => a.eq(b),
464 (AbiValue::Address(a), AbiValue::Address(b)) => a.eq(b),
465 (AbiValue::AddressStd(a), AbiValue::AddressStd(b)) => a.eq(b),
466 (AbiValue::Bytes(a), AbiValue::Bytes(b)) => a.eq(b),
467 (AbiValue::FixedBytes(a), AbiValue::FixedBytes(b)) => a.eq(b),
468 (AbiValue::String(a), AbiValue::String(b)) => a.eq(b),
469 (AbiValue::Token(a), AbiValue::Token(b)) => a.eq(b),
470 (AbiValue::Tuple(a), AbiValue::Tuple(b)) => {
471 WithoutName::wrap_slice(a.as_slice()).eq(WithoutName::wrap_slice(b.as_slice()))
472 }
473 (AbiValue::Array(at, av), AbiValue::Array(bt, bv))
474 | (AbiValue::FixedArray(at, av), AbiValue::FixedArray(bt, bv)) => {
475 WithoutName::wrap(at.as_ref()).eq(WithoutName::wrap(bt.as_ref()))
476 && WithoutName::wrap_slice(av.as_slice())
477 .eq(WithoutName::wrap_slice(bv.as_slice()))
478 }
479 (AbiValue::Map(akt, avt, a), AbiValue::Map(bkt, bvt, b)) => {
480 akt.eq(bkt)
481 && WithoutName::wrap(avt.as_ref()).eq(WithoutName::wrap(bvt.as_ref()))
482 && WithoutName::wrap(a).eq(WithoutName::wrap(b))
483 }
484 (AbiValue::Optional(at, a), AbiValue::Optional(bt, b)) => {
485 WithoutName::wrap(at.as_ref()).eq(WithoutName::wrap(bt.as_ref()))
486 && a.as_deref()
487 .map(WithoutName::wrap)
488 .eq(&b.as_deref().map(WithoutName::wrap))
489 }
490 (AbiValue::Ref(a), AbiValue::Ref(b)) => {
491 WithoutName::wrap(a.as_ref()).eq(WithoutName::wrap(b.as_ref()))
492 }
493 _unused => false,
494 }
495 }
496}
497
498#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
501pub enum PlainAbiValue {
502 Uint(u16, BigUint),
504 Int(u16, BigInt),
506 Bool(bool),
508 Address(Box<IntAddr>),
512}
513
514impl PlainAbiValue {
515 pub fn has_type(&self, ty: &PlainAbiType) -> bool {
517 match (self, ty) {
518 (Self::Uint(n, _), PlainAbiType::Uint(t)) => n == t,
519 (Self::Int(n, _), PlainAbiType::Int(t)) => n == t,
520 (Self::Bool(_), PlainAbiType::Bool) | (Self::Address(_), PlainAbiType::Address) => true,
521 _ => false,
522 }
523 }
524
525 #[inline]
527 pub fn display_type(&self) -> impl std::fmt::Display + '_ {
528 DisplayPlainValueType(self)
529 }
530}
531
532impl From<PlainAbiValue> for AbiValue {
533 fn from(value: PlainAbiValue) -> Self {
534 match value {
535 PlainAbiValue::Uint(n, value) => Self::Uint(n, value),
536 PlainAbiValue::Int(n, value) => Self::Int(n, value),
537 PlainAbiValue::Bool(value) => Self::Bool(value),
538 PlainAbiValue::Address(value) => {
539 let addr = match value.as_ref() {
540 IntAddr::Std(addr) => AnyAddr::Std(addr.clone()),
541 IntAddr::Var(addr) => AnyAddr::Var(addr.clone()),
542 };
543 AbiValue::Address(Box::new(addr))
544 }
545 }
546 }
547}
548
549#[derive(Debug, Clone, Eq, PartialEq)]
551pub enum AbiHeader {
552 Time(u64),
554 Expire(u32),
556 PublicKey(Option<Box<ed25519_dalek::VerifyingKey>>),
558}
559
560impl AbiHeader {
561 pub fn has_type(&self, ty: &AbiHeaderType) -> bool {
563 matches!(
564 (self, ty),
565 (Self::Time(_), AbiHeaderType::Time)
566 | (Self::Expire(_), AbiHeaderType::Expire)
567 | (Self::PublicKey(_), AbiHeaderType::PublicKey)
568 )
569 }
570
571 #[inline]
573 pub fn display_type(&self) -> impl std::fmt::Display + '_ {
574 DisplayHeaderType(self)
575 }
576}
577
578struct DisplayHeaderType<'a>(&'a AbiHeader);
579
580impl std::fmt::Display for DisplayHeaderType<'_> {
581 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
582 f.write_str(match self.0 {
583 AbiHeader::Time(_) => "time",
584 AbiHeader::Expire(_) => "expire",
585 AbiHeader::PublicKey(_) => "pubkey",
586 })
587 }
588}
589
590struct DisplayPlainValueType<'a>(&'a PlainAbiValue);
591
592impl std::fmt::Display for DisplayPlainValueType<'_> {
593 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
594 f.write_str(match self.0 {
595 PlainAbiValue::Uint(n, _) => return write!(f, "uint{n}"),
596 PlainAbiValue::Int(n, _) => return write!(f, "int{n}"),
597 PlainAbiValue::Bool(_) => "bool",
598 PlainAbiValue::Address(_) => "address",
599 })
600 }
601}
602
603struct DisplayValueType<'a>(&'a AbiValue);
604
605impl std::fmt::Display for DisplayValueType<'_> {
606 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
607 let s = match self.0 {
608 AbiValue::Uint(n, _) => return write!(f, "uint{n}"),
609 AbiValue::Int(n, _) => return write!(f, "int{n}"),
610 AbiValue::VarUint(n, _) => return write!(f, "varuint{n}"),
611 AbiValue::VarInt(n, _) => return write!(f, "varint{n}"),
612 AbiValue::Bool(_) => "bool",
613 AbiValue::Cell(_) => "cell",
614 AbiValue::Address(_) => "address",
615 AbiValue::AddressStd(_) => "address_std",
616 AbiValue::Bytes(_) => "bytes",
617 AbiValue::FixedBytes(bytes) => return write!(f, "fixedbytes{}", bytes.len()),
618 AbiValue::String(_) => "string",
619 AbiValue::Token(_) => "gram",
620 AbiValue::Tuple(items) => {
621 return std::fmt::Display::fmt(&DisplayTupleValueType(items), f);
622 }
623 AbiValue::Array(ty, _) => return write!(f, "{ty}[]"),
624 AbiValue::FixedArray(ty, items) => return write!(f, "{ty}[{}]", items.len()),
625 AbiValue::Map(key_ty, value_ty, _) => return write!(f, "map({key_ty},{value_ty})"),
626 AbiValue::Optional(ty, _) => return write!(f, "optional({ty})"),
627 AbiValue::Ref(val) => return write!(f, "ref({})", val.display_type()),
628 };
629 f.write_str(s)
630 }
631}
632
633struct DisplayTupleValueType<'a>(&'a [NamedAbiValue]);
634
635impl std::fmt::Display for DisplayTupleValueType<'_> {
636 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
637 let s = if self.0.is_empty() {
638 "()"
639 } else {
640 let mut first = true;
641 ok!(f.write_str("("));
642 for item in self.0 {
643 if !std::mem::take(&mut first) {
644 ok!(f.write_str(","));
645 }
646 ok!(write!(f, "{}", item.value.display_type()));
647 }
648 ")"
649 };
650 f.write_str(s)
651 }
652}
653
654struct DisplayTupleType<'a>(&'a [NamedAbiType]);
655
656impl std::fmt::Display for DisplayTupleType<'_> {
657 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
658 let s = if self.0.is_empty() {
659 "()"
660 } else {
661 let mut first = true;
662 ok!(f.write_str("("));
663 for item in self.0 {
664 if !std::mem::take(&mut first) {
665 ok!(f.write_str(","));
666 }
667 ok!(write!(f, "{}", item.ty));
668 }
669 ")"
670 };
671 f.write_str(s)
672 }
673}