1use std::vec::Vec;
2use elements;
3use super::invoke::{Invoke, Identity};
4use super::misc::{ValueTypeBuilder, ValueTypesBuilder, OptionalValueTypeBuilder};
5
6pub enum Signature {
8 TypeReference(u32),
9 Inline(elements::FunctionType),
10}
11
12pub struct SignatureBuilder<F=Identity> {
14 callback: F,
15 signature: elements::FunctionType,
16}
17
18impl SignatureBuilder {
19 pub fn new() -> Self {
21 SignatureBuilder::with_callback(Identity)
22 }
23}
24
25impl<F> SignatureBuilder<F> where F: Invoke<elements::FunctionType> {
26 pub fn with_callback(callback: F) -> Self {
28 SignatureBuilder {
29 callback: callback,
30 signature: elements::FunctionType::default(),
31 }
32 }
33
34 pub fn with_param(mut self, value_type: elements::ValueType) -> Self {
36 self.signature.params_mut().push(value_type);
37 self
38 }
39
40 pub fn with_params(mut self, value_types: Vec<elements::ValueType>) -> Self {
42 self.signature.params_mut().extend(value_types);
43 self
44 }
45
46 pub fn with_return_type(mut self, return_type: Option<elements::ValueType>) -> Self {
48 *self.signature.return_type_mut() = return_type;
49 self
50 }
51
52 pub fn param(self) -> ValueTypeBuilder<Self> {
54 ValueTypeBuilder::with_callback(self)
55 }
56
57 pub fn params(self) -> ValueTypesBuilder<Self> {
59 ValueTypesBuilder::with_callback(self)
60 }
61
62 pub fn return_type(self) -> OptionalValueTypeBuilder<Self> {
64 OptionalValueTypeBuilder::with_callback(self)
65 }
66
67 pub fn build(self) -> F::Result {
69 self.callback.invoke(self.signature)
70 }
71
72 pub fn build_sig(self) -> Signature {
74 Signature::Inline(self.signature)
75 }
76}
77
78impl<F> Invoke<Vec<elements::ValueType>> for SignatureBuilder<F>
79 where F: Invoke<elements::FunctionType>
80{
81 type Result = Self;
82
83 fn invoke(self, args: Vec<elements::ValueType>) -> Self {
84 self.with_params(args)
85 }
86}
87
88impl<F> Invoke<Option<elements::ValueType>> for SignatureBuilder<F>
89 where F: Invoke<elements::FunctionType>
90{
91 type Result = Self;
92
93 fn invoke(self, arg: Option<elements::ValueType>) -> Self {
94 self.with_return_type(arg)
95 }
96}
97
98impl<F> Invoke<elements::ValueType> for SignatureBuilder<F>
99 where F: Invoke<elements::FunctionType>
100{
101 type Result = Self;
102
103 fn invoke(self, arg: elements::ValueType) -> Self {
104 self.with_param(arg)
105 }
106}
107
108pub struct TypeRefBuilder<F=Identity> {
110 callback: F,
111 type_ref: u32,
112}
113
114impl<F> TypeRefBuilder<F> where F: Invoke<u32> {
115 pub fn with_callback(callback: F) -> Self {
117 TypeRefBuilder {
118 callback: callback,
119 type_ref: 0
120 }
121 }
122
123 pub fn val(mut self, val: u32) -> Self {
125 self.type_ref = val;
126 self
127 }
128
129 pub fn build(self) -> F::Result { self.callback.invoke(self.type_ref) }
131}
132
133pub struct SignaturesBuilder<F=Identity> {
135 callback: F,
136 section: Vec<Signature>,
137}
138
139impl SignaturesBuilder {
140 pub fn new() -> Self {
142 SignaturesBuilder::with_callback(Identity)
143 }
144}
145
146impl<F> SignaturesBuilder<F> {
147 pub fn with_callback(callback: F) -> Self {
149 SignaturesBuilder {
150 callback: callback,
151 section: Vec::new(),
152 }
153 }
154
155 pub fn with_signature(mut self, signature: Signature) -> Self {
157 self.section.push(signature);
158 self
159 }
160
161 pub fn type_ref(self) -> TypeRefBuilder<Self> {
163 TypeRefBuilder::with_callback(self)
164 }
165}
166
167impl<F> SignaturesBuilder<F> where F: Invoke<SignatureBindings> {
168 pub fn signature(self) -> SignatureBuilder<Self> {
170 SignatureBuilder::with_callback(self)
171 }
172}
173
174impl<F> Invoke<elements::FunctionType> for SignaturesBuilder<F> {
175 type Result = Self;
176
177 fn invoke(self, signature: elements::FunctionType) -> Self {
178 self.with_signature(Signature::Inline(signature))
179 }
180}
181
182impl<F> Invoke<u32> for SignaturesBuilder<F> {
183 type Result = Self;
184
185 fn invoke(self, type_ref: u32) -> Self {
186 self.with_signature(Signature::TypeReference(type_ref))
187 }
188}
189
190impl<F> SignaturesBuilder<F> where F: Invoke<elements::FunctionSection> {
191
192 pub fn build(self) -> F::Result {
194 let mut result = elements::FunctionSection::default();
195 for f in self.section.into_iter() {
196 if let Signature::TypeReference(type_ref) = f {
197 result.entries_mut().push(elements::Func::new(type_ref));
198 } else {
199 unreachable!(); }
201 }
202 self.callback.invoke(result)
203 }
204}
205
206pub type SignatureBindings = Vec<Signature>;
208
209impl<F> SignaturesBuilder<F> where F: Invoke<SignatureBindings> {
210 pub fn bind(self) -> F::Result {
212 self.callback.invoke(self.section)
213 }
214}
215
216pub struct FuncBodyBuilder<F=Identity> {
218 callback: F,
219 body: elements::FuncBody,
220}
221
222impl<F> FuncBodyBuilder<F> {
223 pub fn with_callback(callback: F) -> Self {
225 FuncBodyBuilder {
226 callback: callback,
227 body: elements::FuncBody::new(Vec::new(), elements::Instructions::empty()),
228 }
229 }
230}
231
232impl<F> FuncBodyBuilder<F> where F: Invoke<elements::FuncBody> {
233 pub fn with_func(mut self, func: elements::FuncBody) -> Self {
235 self.body = func;
236 self
237 }
238
239 pub fn with_locals(mut self, locals: Vec<elements::Local>) -> Self {
241 self.body.locals_mut().extend(locals);
242 self
243 }
244
245 pub fn with_instructions(mut self, instructions: elements::Instructions) -> Self {
247 *self.body.code_mut() = instructions;
248 self
249 }
250
251 pub fn build(self) -> F::Result {
253 self.callback.invoke(self.body)
254 }
255}
256
257pub struct FunctionDefinition {
259 pub is_main: bool,
261 pub signature: Signature,
263 pub code: elements::FuncBody,
265}
266
267impl Default for FunctionDefinition {
268 fn default() -> Self {
269 FunctionDefinition {
270 is_main: false,
271 signature: Signature::TypeReference(0),
272 code: elements::FuncBody::empty(),
273 }
274 }
275}
276
277pub struct FunctionBuilder<F=Identity> {
279 callback: F,
280 func: FunctionDefinition,
281}
282
283impl FunctionBuilder {
284 pub fn new() -> Self {
286 FunctionBuilder::with_callback(Identity)
287 }
288}
289
290impl<F> FunctionBuilder<F> where F: Invoke<FunctionDefinition> {
291 pub fn with_callback(callback: F) -> Self {
293 FunctionBuilder {
294 callback: callback,
295 func: Default::default(),
296 }
297 }
298
299 pub fn main(mut self) -> Self {
301 self.func.is_main = true;
302 self
303 }
304
305 pub fn signature(self) -> SignatureBuilder<Self> {
307 SignatureBuilder::with_callback(self)
308 }
309
310 pub fn with_signature(mut self, signature: Signature) -> Self {
312 self.func.signature = signature;
313 self
314 }
315
316 pub fn body(self) -> FuncBodyBuilder<Self> {
318 FuncBodyBuilder::with_callback(self)
319 }
320
321 pub fn with_body(mut self, body: elements::FuncBody) -> Self {
323 self.func.code = body;
324 self
325 }
326
327 pub fn build(self) -> F::Result {
329 self.callback.invoke(self.func)
330 }
331}
332
333impl<F> Invoke<elements::FunctionType> for FunctionBuilder<F> where F: Invoke<FunctionDefinition> {
334 type Result = Self;
335
336 fn invoke(self, signature: elements::FunctionType) -> Self {
337 self.with_signature(Signature::Inline(signature))
338 }
339}
340
341impl<F> Invoke<u32> for FunctionBuilder<F> where F: Invoke<FunctionDefinition> {
342 type Result = Self;
343
344 fn invoke(self, type_ref: u32) -> Self {
345 self.with_signature(Signature::TypeReference(type_ref))
346 }
347}
348
349impl<F> Invoke<elements::FuncBody> for FunctionBuilder<F> where F: Invoke<FunctionDefinition> {
350 type Result = Self;
351
352 fn invoke(self, body: elements::FuncBody) -> Self::Result {
353 self.with_body(body)
354 }
355}
356
357pub fn signatures() -> SignaturesBuilder {
359 SignaturesBuilder::new()
360}
361
362pub fn signature() -> SignatureBuilder {
364 SignatureBuilder::new()
365}
366
367pub fn function() -> FunctionBuilder {
369 FunctionBuilder::new()
370}
371
372#[cfg(test)]
373mod tests {
374
375 use super::{signatures, function};
376 use elements;
377
378 #[test]
379 fn example() {
380 let result = signatures()
381 .type_ref().val(1).build()
382 .build();
383
384 assert_eq!(result.entries().len(), 1);
385
386 let result = signatures()
387 .signature()
388 .param().i32()
389 .param().i32()
390 .return_type().i64()
391 .build()
392 .bind();
393
394 assert_eq!(result.len(), 1);
395 }
396
397 #[test]
398 fn func_example() {
399 let func = function()
400 .signature()
401 .param().i32()
402 .return_type().i32()
403 .build()
404 .body()
405 .with_instructions(elements::Instructions::empty())
406 .build()
407 .build();
408
409 assert_eq!(func.code.locals().len(), 0);
410 assert_eq!(func.code.code().elements().len(), 1);
411 }
412}