1use crate::attribute::AttributeGroup;
2use crate::body::Body;
3use crate::comment::Document;
4use crate::data_type::DataType;
5use crate::parameter::Parameter;
6use crate::Generator;
7use crate::Indentation;
8
9#[derive(Debug)]
10pub struct Function {
11 pub documentation: Option<Document>,
12 pub attributes: Vec<AttributeGroup>,
13 pub name: String,
14 pub parameters: Vec<Parameter>,
15 pub return_type: Option<DataType>,
16 pub body: Body,
17}
18
19impl Function {
20 pub fn new<T: ToString>(name: T) -> Self {
21 Self {
22 name: name.to_string(),
23 parameters: vec![],
24 return_type: None,
25 body: Body::new().with_semicolon_for_empty(false),
26 attributes: vec![],
27 documentation: None,
28 }
29 }
30
31 pub fn document(mut self, documentation: Document) -> Self {
32 self.documentation = Some(documentation);
33
34 self
35 }
36
37 pub fn attributes(mut self, attributes: AttributeGroup) -> Self {
38 self.attributes.push(attributes);
39
40 self
41 }
42
43 pub fn parameter(mut self, parameter: Parameter) -> Self {
44 self.parameters.push(parameter);
45
46 self
47 }
48
49 pub fn returns(mut self, return_type: DataType) -> Self {
50 self.return_type = Some(return_type);
51
52 self
53 }
54
55 pub fn body<T: Into<Body>>(mut self, body: T) -> Self {
56 self.body = body.into();
57 self.body = self.body.with_semicolon_for_empty(false);
58
59 self
60 }
61}
62
63impl Generator for Function {
64 fn generate(&self, indentation: Indentation, level: usize) -> String {
65 let mut code = String::new();
66
67 if let Some(document) = &self.documentation {
68 code.push_str(document.generate(indentation, level).as_str());
69 }
70
71 for attribute in &self.attributes {
72 code.push_str(attribute.generate(indentation, level).as_str());
73 }
74
75 code.push_str(format!("function {}", self.name).as_str());
76 code.push_str(self.parameters.generate(indentation, level).as_str());
77
78 if let Some(return_type) = &self.return_type {
79 code.push_str(format!(": {}", return_type.generate(indentation, level)).as_str());
80 }
81
82 code.push_str(self.body.generate(indentation, level).as_str());
83
84 code
85 }
86}
87
88impl Generator for Vec<Function> {
89 fn generate(&self, indentation: Indentation, level: usize) -> String {
90 let mut code = String::new();
91 if self.is_empty() {
92 return code;
93 }
94
95 for function in self {
96 code.push_str(function.generate(indentation, level).as_str());
97 code.push('\n');
98 }
99
100 code
101 }
102}