postcard_bindgen_core/code_gen/
function.rs1use genco::{lang::Lang, quote, tokens::FormatInto, Tokens};
2
3#[macro_export]
4macro_rules! function_args {
5 ($(($n:expr, $t:expr)),+ $(,)?) => {
6
7 [$(({
8 use genco::tokens::FormatInto;
9 let mut tokens = genco::Tokens::new();
10 $n.format_into(&mut tokens);
11 tokens
12 }, {
13 use genco::tokens::FormatInto;
14 let mut tokens = genco::Tokens::new();
15 $t.format_into(&mut tokens);
16 tokens
17 })),+]
18 };
19 ($($x:expr),+ $(,)?) => {
20
21 [$({
22 use genco::tokens::FormatInto;
23 let mut tokens = genco::Tokens::new();
24 $x.format_into(&mut tokens);
25 tokens
26 }),+]
27 };
28
29}
30
31pub struct FunctionArg<L>
32where
33 L: Lang,
34{
35 pub(super) name: Tokens<L>,
36 pub(super) r#type: Option<Tokens<L>>,
37}
38
39impl<L> FunctionArg<L>
40where
41 L: Lang,
42{
43 pub fn new(name: impl FormatInto<L>, r#type: impl FormatInto<L>) -> Self {
44 Self {
45 name: quote!($name),
46 r#type: Some(quote!($r#type)),
47 }
48 }
49
50 pub fn new_untyped(name: impl FormatInto<L>) -> Self {
51 Self {
52 name: quote!($name),
53 r#type: None,
54 }
55 }
56}
57
58impl<N, T, L> From<(N, T)> for FunctionArg<L>
59where
60 L: Lang,
61 N: FormatInto<L>,
62 T: FormatInto<L>,
63{
64 fn from((name, r#type): (N, T)) -> Self {
65 Self::new(name, r#type)
66 }
67}
68
69impl<L> From<Tokens<L>> for FunctionArg<L>
70where
71 L: Lang,
72{
73 fn from(name: Tokens<L>) -> Self {
74 Self::new_untyped(name)
75 }
76}
77
78pub trait ToArgs<L>
79where
80 L: Lang,
81{
82 fn to_args(self) -> Vec<FunctionArg<L>>;
83}
84
85impl<L, A> ToArgs<L> for Vec<A>
86where
87 L: Lang,
88 A: Into<FunctionArg<L>>,
89{
90 fn to_args(self) -> Vec<FunctionArg<L>> {
91 self.into_iter().map(|a| a.into()).collect()
92 }
93}
94
95impl<L> ToArgs<L> for FunctionArg<L>
96where
97 L: Lang,
98{
99 fn to_args(self) -> Vec<FunctionArg<L>> {
100 vec![self]
101 }
102}
103
104impl<L> ToArgs<L> for ()
105where
106 L: Lang,
107{
108 fn to_args(self) -> Vec<FunctionArg<L>> {
109 Vec::new()
110 }
111}
112
113impl<L, F, const N: usize> ToArgs<L> for [F; N]
114where
115 L: Lang,
116 F: Into<FunctionArg<L>>,
117{
118 fn to_args(self) -> Vec<FunctionArg<L>> {
119 self.into_iter().map(|f| f.into()).collect()
120 }
121}
122
123impl<'a, L, F, const N: usize> ToArgs<L> for &'a [F; N]
124where
125 L: Lang,
126 &'a F: Into<FunctionArg<L>>,
127{
128 fn to_args(self) -> Vec<FunctionArg<L>> {
129 self.iter().map(|f| f.into()).collect()
130 }
131}
132
133pub struct Function<L>
134where
135 L: Lang,
136{
137 pub(super) args: Vec<FunctionArg<L>>,
138 pub(super) name: Tokens<L>,
139 pub(super) body: Tokens<L>,
140 pub(super) return_type: Option<Tokens<L>>,
141 pub(super) doc_string: Option<String>,
142}
143
144impl<L> Function<L>
145where
146 L: Lang,
147{
148 pub fn new(
149 name: impl FormatInto<L>,
150 args: impl ToArgs<L>,
151 body: impl FormatInto<L>,
152 return_type: impl FormatInto<L>,
153 ) -> Self {
154 Self {
155 name: quote!($name),
156 args: args.to_args(),
157 return_type: Some(quote!($return_type)),
158 body: quote!($body),
159 doc_string: None,
160 }
161 }
162
163 pub fn new_untyped(
164 name: impl FormatInto<L>,
165 args: impl ToArgs<L>,
166 body: impl FormatInto<L>,
167 ) -> Self {
168 Self {
169 name: quote!($name),
170 args: args.to_args(),
171 return_type: None,
172 body: quote!($body),
173 doc_string: None,
174 }
175 }
176
177 pub fn with_doc_string(mut self, doc_string: impl ToString) -> Self {
178 self.doc_string = Some(doc_string.to_string());
179 self
180 }
181}