1use crate::{Doc, Ident, Visibility};
2use std::fmt::{Debug, Formatter};
3
4pub enum Arg<T> {
5 Basic {
7 name: Ident,
8 ty: T,
9 default: Option<T>,
10 },
11 Unpack { names: Vec<Ident>, ty: T },
14 SelfArg { mutable: bool, reference: bool },
16 Kwargs { name: Ident, ty: T },
18 Variadic { name: Ident, ty: T },
20}
21
22impl<T> Arg<T> {
23 pub fn ident(&self) -> Option<&Ident> {
24 let name = match self {
25 Arg::Basic { name, .. } => name,
26 Arg::Unpack { .. } => return None,
27 Arg::SelfArg { .. } => return None,
28 Arg::Kwargs { name, .. } => name,
29 Arg::Variadic { name, .. } => name,
30 };
31 Some(name)
32 }
33
34 pub fn ty(&self) -> Option<&T> {
35 let ty = match self {
36 Arg::Basic { ty, .. } => ty,
37 Arg::Unpack { ty, .. } => ty,
38 Arg::SelfArg { .. } => return None,
39 Arg::Kwargs { ty, .. } => ty,
40 Arg::Variadic { ty, .. } => ty,
41 };
42 Some(ty)
43 }
44}
45
46pub struct Function<T> {
47 pub name: Ident,
48 pub args: Vec<Arg<T>>,
49 pub ret: T,
50 pub body: T,
51 pub doc: Option<Doc>,
52 pub is_async: bool,
53 pub vis: Visibility,
54 pub attributes: Vec<T>,
55}
56
57impl<T> Function<T> {
58 pub fn body(mut self, body: T) -> Self {
59 self.body = body;
60 self
61 }
62}
63
64impl<T> Debug for Function<T>
65where
66 T: Debug,
67{
68 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
69 f.debug_struct("Function")
70 .field("name", &self.name)
71 .field("ret", &self.ret)
72 .field("args", &"..")
73 .field("body", &"..")
74 .finish()
75 }
76}
77
78impl<T> Default for Function<T>
79where
80 T: Default,
81{
82 fn default() -> Self {
83 Self {
84 name: Ident("".to_string()),
85 args: vec![],
86 ret: T::default(),
87 body: T::default(),
88 doc: None,
89 is_async: false,
90 vis: Default::default(),
91 attributes: vec![],
92 }
93 }
94}
95
96pub fn build_struct(mut s: impl Iterator<Item = impl AsRef<str>>) -> String {
98 let mut r = String::from("{");
99 let mut t = s.next();
100 while let Some(u) = &t {
101 r.push_str(u.as_ref());
102 t = s.next();
103 if t.is_some() {
104 r.push_str(", ");
105 }
106 }
107 r.push('}');
108 r
109}
110
111pub fn build_dict<'a>(s: impl Iterator<Item = (&'a str, &'a str)>) -> String {
113 build_struct(s.map(|(k, v)| format!("\"{}\": {}", k, v)))
114}