sol_abi/
abi.rs

1//! Solidity ABI abstraction.
2
3use crate::Arg;
4use core::{convert::Infallible, fmt, str::FromStr};
5
6#[cfg(feature = "syn")]
7use quote::ToTokens;
8
9#[cfg(not(feature = "std"))]
10use crate::std::{String, ToString, Vec};
11
12/// Solidity ABI abstraction.
13#[derive(Clone, Debug, Default)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15pub struct Abi {
16    /// ABI name.
17    pub name: String,
18    /// ABI type.
19    #[cfg_attr(feature = "serde", serde(rename = "type"))]
20    pub ty: Type,
21    /// An array of arguments.
22    pub inputs: Vec<Arg>,
23    /// An array of arguments, similar to inputs.
24    pub outputs: Vec<Arg>,
25}
26
27#[cfg(feature = "syn")]
28impl From<&syn::Signature> for Abi {
29    fn from(sig: &syn::Signature) -> Self {
30        let inputs = sig
31            .inputs
32            .iter()
33            .filter_map(|arg| {
34                if let syn::FnArg::Typed(syn::PatType { pat, ty, .. }) = arg {
35                    Some(Arg {
36                        name: pat.to_token_stream().to_string(),
37                        ty: crate::Param::from(ty),
38                    })
39                } else {
40                    None
41                }
42            })
43            .collect();
44
45        let outputs = if let syn::ReturnType::Type(_, ty) = &sig.output {
46            vec![Arg {
47                // TODO: how to name the output?
48                name: "output".into(),
49                ty: crate::Param::from(ty),
50            }]
51        } else {
52            vec![]
53        };
54
55        let name = sig.ident.to_string();
56        Abi {
57            ty: Type::from(name.as_str()),
58            name,
59            inputs,
60            outputs,
61        }
62    }
63}
64
65/// Solidity ABI type.
66#[derive(Clone, Debug, Default)]
67#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
68#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
69pub enum Type {
70    /// Constructor ABI.
71    Constructor,
72    /// Function ABI.
73    #[default]
74    Function,
75}
76
77impl From<&str> for Type {
78    fn from(s: &str) -> Self {
79        match s {
80            "constructor" => Type::Constructor,
81            _ => Type::Function,
82        }
83    }
84}
85
86impl FromStr for Type {
87    type Err = Infallible;
88
89    fn from_str(s: &str) -> Result<Self, Self::Err> {
90        Ok(Self::from(s))
91    }
92}
93
94impl AsRef<str> for Type {
95    fn as_ref(&self) -> &str {
96        match self {
97            Type::Constructor => "constructor",
98            Type::Function => "function",
99        }
100    }
101}
102
103impl fmt::Display for Type {
104    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105        let ty: &str = self.as_ref();
106        write!(f, "{ty}")
107    }
108}