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
59 pub const fn new(major: u8, minor: u8) -> Self {
61 Self { major, minor }
62 }
63}
64
65impl FromStr for AbiVersion {
66 type Err = error::ParseAbiVersionError;
67
68 fn from_str(s: &str) -> Result<Self, Self::Err> {
69 let (major, minor) = ok!(s
70 .split_once('.')
71 .ok_or(error::ParseAbiVersionError::InvalidFormat));
72
73 Ok(Self {
74 major: ok!(major
75 .parse()
76 .map_err(error::ParseAbiVersionError::InvalidComponent)),
77 minor: ok!(minor
78 .parse()
79 .map_err(error::ParseAbiVersionError::InvalidComponent)),
80 })
81 }
82}
83
84impl std::fmt::Display for AbiVersion {
85 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86 write!(f, "{}.{}", self.major, self.minor)
87 }
88}
89
90#[repr(transparent)]
93pub struct WithoutName<T>(pub T);
94
95impl<T> WithoutName<T> {
96 pub fn wrap(value: &T) -> &Self {
98 unsafe { &*(value as *const T as *const Self) }
100 }
101
102 pub fn wrap_slice(value: &[T]) -> &[Self] {
104 unsafe { &*(value as *const [T] as *const [Self]) }
106 }
107}
108
109impl<T: std::fmt::Debug> std::fmt::Debug for WithoutName<T> {
110 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111 f.debug_tuple("WithoutName").field(&self.0).finish()
112 }
113}
114
115impl<T: Clone> Clone for WithoutName<T> {
116 #[inline]
117 fn clone(&self) -> Self {
118 WithoutName(self.0.clone())
119 }
120}
121
122impl<T> Eq for WithoutName<T> where WithoutName<T>: PartialEq {}
123
124impl<T> PartialOrd for WithoutName<T>
125where
126 WithoutName<T>: Ord,
127{
128 #[inline]
129 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
130 Some(self.cmp(other))
131 }
132}
133
134impl<T> PartialEq for WithoutName<Vec<T>>
135where
136 WithoutName<T>: PartialEq,
137{
138 fn eq(&self, WithoutName(other): &Self) -> bool {
139 WithoutName::wrap_slice(self.0.as_slice()) == WithoutName::wrap_slice(other.as_slice())
140 }
141}
142
143impl<K, V> PartialEq for WithoutName<std::collections::BTreeMap<K, V>>
144where
145 K: PartialEq,
146 WithoutName<V>: PartialEq,
147{
148 fn eq(&self, WithoutName(other): &Self) -> bool {
149 self.0.len() == other.len()
150 && self.0.iter().zip(other).all(|((ak, av), (bk, bv))| {
151 (ak, WithoutName::wrap(av)) == (bk, WithoutName::wrap(bv))
152 })
153 }
154}
155
156impl<K, V, S> PartialEq for WithoutName<std::collections::HashMap<K, V, S>>
157where
158 K: Eq + Hash,
159 WithoutName<V>: PartialEq,
160 S: BuildHasher,
161{
162 fn eq(&self, WithoutName(other): &Self) -> bool {
163 if self.0.len() != other.len() {
164 return false;
165 }
166
167 self.0.iter().all(|(key, value)| {
168 other
169 .get(key)
170 .is_some_and(|v| WithoutName::wrap(value) == WithoutName::wrap(v))
171 })
172 }
173}