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