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