1use 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#[derive(Clone, Debug, Default)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15pub struct Abi {
16 pub name: String,
18 #[cfg_attr(feature = "serde", serde(rename = "type"))]
20 pub ty: Type,
21 pub inputs: Vec<Arg>,
23 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 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#[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,
72 #[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}