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