use std::hash::{BuildHasher, Hash};
use std::str::FromStr;
pub use self::contract::{
Contract, Event, EventBuilder, ExternalInput, Function, FunctionBuilder, UnsignedBody,
UnsignedExternalMessage,
};
pub use self::signature::{extend_signature_with_id, sign_with_signature_id};
pub use self::traits::{
FromAbi, FromAbiIter, FromPlainAbi, IgnoreName, IntoAbi, IntoPlainAbi, WithAbiType,
WithPlainAbiType,
};
pub use self::ty::{AbiHeaderType, AbiType, NamedAbiType, PlainAbiType};
pub use self::value::{AbiHeader, AbiValue, NamedAbiValue, PlainAbiValue};
pub mod error;
mod contract;
mod signature;
mod traits;
mod ty;
mod value;
#[cfg(test)]
mod tests;
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct AbiVersion {
pub major: u8,
pub minor: u8,
}
impl AbiVersion {
pub const V1_0: Self = Self::new(1, 0);
pub const V2_0: Self = Self::new(2, 0);
pub const V2_1: Self = Self::new(2, 1);
pub const V2_2: Self = Self::new(2, 2);
pub const V2_3: Self = Self::new(2, 3);
pub const fn new(major: u8, minor: u8) -> Self {
Self { major, minor }
}
}
impl FromStr for AbiVersion {
type Err = error::ParseAbiVersionError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let (major, minor) = ok!(s
.split_once('.')
.ok_or(error::ParseAbiVersionError::InvalidFormat));
Ok(Self {
major: ok!(major
.parse()
.map_err(error::ParseAbiVersionError::InvalidComponent)),
minor: ok!(minor
.parse()
.map_err(error::ParseAbiVersionError::InvalidComponent)),
})
}
}
impl std::fmt::Display for AbiVersion {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}.{}", self.major, self.minor)
}
}
#[repr(transparent)]
pub struct WithoutName<T>(pub T);
impl<T> WithoutName<T> {
pub fn wrap(value: &T) -> &Self {
unsafe { &*(value as *const T as *const Self) }
}
pub fn wrap_slice(value: &[T]) -> &[Self] {
unsafe { &*(value as *const [T] as *const [Self]) }
}
}
impl<T: std::fmt::Debug> std::fmt::Debug for WithoutName<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("WithoutName").field(&self.0).finish()
}
}
impl<T: Clone> Clone for WithoutName<T> {
#[inline]
fn clone(&self) -> Self {
WithoutName(self.0.clone())
}
}
impl<T> Eq for WithoutName<T> where WithoutName<T>: PartialEq {}
impl<T> PartialOrd for WithoutName<T>
where
WithoutName<T>: Ord,
{
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl<T> PartialEq for WithoutName<Vec<T>>
where
WithoutName<T>: PartialEq,
{
fn eq(&self, WithoutName(other): &Self) -> bool {
WithoutName::wrap_slice(self.0.as_slice()) == WithoutName::wrap_slice(other.as_slice())
}
}
impl<K, V> PartialEq for WithoutName<std::collections::BTreeMap<K, V>>
where
K: PartialEq,
WithoutName<V>: PartialEq,
{
fn eq(&self, WithoutName(other): &Self) -> bool {
self.0.len() == other.len()
&& self.0.iter().zip(other).all(|((ak, av), (bk, bv))| {
(ak, WithoutName::wrap(av)) == (bk, WithoutName::wrap(bv))
})
}
}
impl<K, V, S> PartialEq for WithoutName<std::collections::HashMap<K, V, S>>
where
K: Eq + Hash,
WithoutName<V>: PartialEq,
S: BuildHasher,
{
fn eq(&self, WithoutName(other): &Self) -> bool {
if self.0.len() != other.len() {
return false;
}
self.0.iter().all(|(key, value)| {
other
.get(key)
.map_or(false, |v| WithoutName::wrap(value) == WithoutName::wrap(v))
})
}
}