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