everscale_types/abi/
mod.rs1use std::hash::{BuildHasher, Hash};
4use std::str::FromStr;
5
6pub use self::contract::{
7 Contract, Event, EventBuilder, ExternalInput, Function, FunctionBuilder, UnsignedBody,
8 UnsignedExternalMessage,
9};
10pub use self::signature::{extend_signature_with_id, sign_with_signature_id};
11pub use self::traits::{
12 FromAbi, FromAbiIter, FromPlainAbi, IgnoreName, IntoAbi, IntoPlainAbi, WithAbiType,
13 WithPlainAbiType,
14};
15pub use self::ty::{
16 AbiHeaderType, AbiType, AbiTypeFlatten, NamedAbiType, NamedAbiTypeFlatten, PlainAbiType,
17};
18pub use self::value::{AbiHeader, AbiValue, NamedAbiValue, PlainAbiValue};
19
20pub mod error;
21
22mod contract;
23mod signature;
24mod traits;
25mod ty;
26mod value;
27
28#[cfg(test)]
29mod tests;
30
31#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
33pub struct AbiVersion {
34 pub major: u8,
36 pub minor: u8,
38}
39
40impl AbiVersion {
41 pub const V1_0: Self = Self::new(1, 0);
43 pub const V2_0: Self = Self::new(2, 0);
45 pub const V2_1: Self = Self::new(2, 1);
47 pub const V2_2: Self = Self::new(2, 2);
49 pub const V2_3: Self = Self::new(2, 3);
51
52 pub const fn new(major: u8, minor: u8) -> Self {
54 Self { major, minor }
55 }
56}
57
58impl FromStr for AbiVersion {
59 type Err = error::ParseAbiVersionError;
60
61 fn from_str(s: &str) -> Result<Self, Self::Err> {
62 let (major, minor) = ok!(s
63 .split_once('.')
64 .ok_or(error::ParseAbiVersionError::InvalidFormat));
65
66 Ok(Self {
67 major: ok!(major
68 .parse()
69 .map_err(error::ParseAbiVersionError::InvalidComponent)),
70 minor: ok!(minor
71 .parse()
72 .map_err(error::ParseAbiVersionError::InvalidComponent)),
73 })
74 }
75}
76
77impl std::fmt::Display for AbiVersion {
78 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79 write!(f, "{}.{}", self.major, self.minor)
80 }
81}
82
83#[repr(transparent)]
86pub struct WithoutName<T>(pub T);
87
88impl<T> WithoutName<T> {
89 pub fn wrap(value: &T) -> &Self {
91 unsafe { &*(value as *const T as *const Self) }
93 }
94
95 pub fn wrap_slice(value: &[T]) -> &[Self] {
97 unsafe { &*(value as *const [T] as *const [Self]) }
99 }
100}
101
102impl<T: std::fmt::Debug> std::fmt::Debug for WithoutName<T> {
103 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104 f.debug_tuple("WithoutName").field(&self.0).finish()
105 }
106}
107
108impl<T: Clone> Clone for WithoutName<T> {
109 #[inline]
110 fn clone(&self) -> Self {
111 WithoutName(self.0.clone())
112 }
113}
114
115impl<T> Eq for WithoutName<T> where WithoutName<T>: PartialEq {}
116
117impl<T> PartialOrd for WithoutName<T>
118where
119 WithoutName<T>: Ord,
120{
121 #[inline]
122 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
123 Some(self.cmp(other))
124 }
125}
126
127impl<T> PartialEq for WithoutName<Vec<T>>
128where
129 WithoutName<T>: PartialEq,
130{
131 fn eq(&self, WithoutName(other): &Self) -> bool {
132 WithoutName::wrap_slice(self.0.as_slice()) == WithoutName::wrap_slice(other.as_slice())
133 }
134}
135
136impl<K, V> PartialEq for WithoutName<std::collections::BTreeMap<K, V>>
137where
138 K: PartialEq,
139 WithoutName<V>: PartialEq,
140{
141 fn eq(&self, WithoutName(other): &Self) -> bool {
142 self.0.len() == other.len()
143 && self.0.iter().zip(other).all(|((ak, av), (bk, bv))| {
144 (ak, WithoutName::wrap(av)) == (bk, WithoutName::wrap(bv))
145 })
146 }
147}
148
149impl<K, V, S> PartialEq for WithoutName<std::collections::HashMap<K, V, S>>
150where
151 K: Eq + Hash,
152 WithoutName<V>: PartialEq,
153 S: BuildHasher,
154{
155 fn eq(&self, WithoutName(other): &Self) -> bool {
156 if self.0.len() != other.len() {
157 return false;
158 }
159
160 self.0.iter().all(|(key, value)| {
161 other
162 .get(key)
163 .map_or(false, |v| WithoutName::wrap(value) == WithoutName::wrap(v))
164 })
165 }
166}