1use std::fmt::Debug;
2
3use crate::attribute::AttributeGroup;
4use crate::body::Body;
5use crate::comment::Document;
6use crate::data_type::DataType;
7use crate::modifiers::Modifier;
8use crate::modifiers::VisibilityModifier;
9use crate::parameter::Parameter;
10use crate::Generator;
11use crate::Indentation;
12
13#[derive(Debug)]
14pub struct Method {
15 pub documentation: Option<Document>,
16 pub attributes: Vec<AttributeGroup>,
17 pub name: String,
18 pub parameters: Vec<Parameter>,
19 pub return_type: Option<DataType>,
20 pub body: Body,
21 pub modifiers: Vec<Modifier>,
22 pub visibility: Option<VisibilityModifier>,
23}
24
25impl Method {
26 pub fn new<T: ToString>(name: T) -> Self {
27 Self {
28 name: name.to_string(),
29 parameters: vec![],
30 return_type: None,
31 body: Body::default(),
32 modifiers: vec![],
33 attributes: vec![],
34 documentation: None,
35 visibility: None,
36 }
37 }
38
39 pub fn document(mut self, documentation: Document) -> Self {
40 self.documentation = Some(documentation);
41
42 self
43 }
44
45 pub fn attributes(mut self, attributes: AttributeGroup) -> Self {
46 self.attributes.push(attributes);
47
48 self
49 }
50
51 pub fn public(mut self) -> Self {
52 self.visibility = Some(VisibilityModifier::Public);
53
54 self
55 }
56
57 pub fn protected(mut self) -> Self {
58 self.visibility = Some(VisibilityModifier::Protected);
59
60 self
61 }
62
63 pub fn private(mut self) -> Self {
64 self.visibility = Some(VisibilityModifier::Private);
65
66 self
67 }
68
69 pub fn visibility(mut self, visibility: VisibilityModifier) -> Self {
70 self.visibility = Some(visibility);
71
72 self
73 }
74
75 pub fn modifier(mut self, modifier: Modifier) -> Self {
76 self.modifiers.push(modifier);
77
78 self
79 }
80
81 pub fn parameter(mut self, parameter: Parameter) -> Self {
82 self.parameters.push(parameter);
83
84 self
85 }
86
87 pub fn returns(mut self, return_type: DataType) -> Self {
88 self.return_type = Some(return_type);
89
90 self
91 }
92
93 pub fn body<T: Into<Body>>(mut self, body: T) -> Self {
94 self.body = body.into().with_semicolon_for_empty(true);
95
96 self
97 }
98}
99
100impl Generator for Method {
101 fn generate(&self, indentation: Indentation, level: usize) -> String {
102 let mut code = String::new();
103
104 if let Some(document) = &self.documentation {
105 code.push_str(&document.generate(indentation, level));
106 }
107
108 for attribute in &self.attributes {
109 code.push_str(&attribute.generate(indentation, level));
110 }
111
112 code.push_str(&indentation.value(level));
113 if let Some(visibility) = &self.visibility {
114 code.push_str(format!("{} ", visibility.generate(indentation, level)).as_str());
115 }
116
117 if !self.modifiers.is_empty() {
118 code.push_str(
119 &self
120 .modifiers
121 .iter()
122 .map(|modifier| modifier.generate(indentation, level))
123 .collect::<Vec<String>>()
124 .join(" "),
125 );
126
127 code.push(' ');
128 }
129
130 code.push_str(format!("function {}", self.name).as_str());
131 code.push_str(&self.parameters.generate(indentation, level));
132
133 if let Some(return_type) = &self.return_type {
134 code.push_str(format!(": {}", return_type.generate(indentation, level)).as_str());
135 }
136
137 code.push_str(&self.body.generate(indentation, level));
138
139 code
140 }
141}
142
143impl Generator for Vec<Method> {
144 fn generate(&self, indentation: Indentation, level: usize) -> String {
145 let mut code = String::new();
146 if self.is_empty() {
147 return code;
148 }
149
150 for method in self {
151 code.push_str(method.generate(indentation, level).as_str());
152 code.push('\n');
153 }
154
155 code
156 }
157}