php_codegen/
method.rs

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}