1use crate::attribute::AttributeGroup;
2use crate::comment::Document;
3use crate::data_type::DataType;
4use crate::literal::Value;
5use crate::modifiers::Modifier;
6use crate::modifiers::VisibilityModifier;
7use crate::Generator;
8use crate::Indentation;
9
10#[derive(Debug)]
11pub struct Constant {
12 pub documentation: Option<Document>,
13 pub name: String,
14 pub value: Value,
15}
16
17impl Constant {
18 pub fn new<T: ToString>(name: T) -> Self {
19 Self {
20 documentation: None,
21 name: name.to_string(),
22 value: Value::Null,
23 }
24 }
25
26 pub fn document(mut self, documentation: Document) -> Self {
27 self.documentation = Some(documentation);
28
29 self
30 }
31
32 pub fn valued<T: Into<Value>>(mut self, value: T) -> Self {
33 self.value = value.into();
34
35 self
36 }
37}
38
39impl Generator for Constant {
40 fn generate(&self, indentation: Indentation, level: usize) -> String {
41 let mut output = String::new();
42
43 if let Some(documentation) = &self.documentation {
44 output.push_str(&documentation.generate(indentation, level));
45 }
46
47 output.push_str(&format!(
48 "const {} = {};\n",
49 self.name,
50 self.value.generate(indentation, level)
51 ));
52
53 output
54 }
55}
56
57impl Generator for Vec<Constant> {
58 fn generate(&self, indentation: Indentation, level: usize) -> String {
59 let mut code = String::new();
60 if self.is_empty() {
61 return code;
62 }
63
64 for constant in self {
65 code.push_str(constant.generate(indentation, level).as_str());
66 code.push('\n');
67 }
68
69 code
70 }
71}
72
73impl<T: ToString, Tv: Into<Value>> From<(T, Tv)> for Constant {
74 fn from((name, value): (T, Tv)) -> Self {
75 Self {
76 documentation: None,
77 name: name.to_string(),
78 value: value.into(),
79 }
80 }
81}
82
83#[derive(Debug)]
84pub struct ClassConstant {
85 pub documentation: Option<Document>,
86 pub attributes: Vec<AttributeGroup>,
87 pub visibility: Option<VisibilityModifier>,
88 pub modifiers: Vec<Modifier>,
89 pub data_type: Option<DataType>,
90 pub name: String,
91 pub value: Value,
92}
93
94impl ClassConstant {
95 pub fn new<T: ToString>(name: T) -> Self {
96 Self {
97 documentation: None,
98 attributes: vec![],
99 visibility: None,
100 modifiers: vec![],
101 data_type: None,
102 name: name.to_string(),
103 value: Value::Null,
104 }
105 }
106
107 pub fn document(mut self, documentation: Document) -> Self {
108 self.documentation = Some(documentation);
109
110 self
111 }
112
113 pub fn attributes(mut self, attributes: AttributeGroup) -> Self {
114 self.attributes.push(attributes);
115
116 self
117 }
118
119 pub fn public(mut self) -> Self {
120 self.visibility = Some(VisibilityModifier::Public);
121
122 self
123 }
124
125 pub fn protected(mut self) -> Self {
126 self.visibility = Some(VisibilityModifier::Protected);
127
128 self
129 }
130
131 pub fn private(mut self) -> Self {
132 self.visibility = Some(VisibilityModifier::Private);
133
134 self
135 }
136
137 pub fn visibility(mut self, visibility: VisibilityModifier) -> Self {
138 self.visibility = Some(visibility);
139
140 self
141 }
142
143 pub fn modifier(mut self, modifier: Modifier) -> Self {
144 self.modifiers.push(modifier);
145
146 self
147 }
148
149 pub fn typed<T: Into<DataType>>(mut self, data_type: T) -> Self {
150 self.data_type = Some(data_type.into());
151
152 self
153 }
154
155 pub fn valued<T: Into<Value>>(mut self, value: T) -> Self {
156 self.value = value.into();
157
158 self
159 }
160}
161
162impl Generator for ClassConstant {
163 fn generate(&self, indentation: Indentation, level: usize) -> String {
164 let mut code = String::new();
165
166 if let Some(document) = &self.documentation {
167 code.push_str(&document.generate(indentation, level));
168 }
169
170 for attribute in &self.attributes {
171 code.push_str(&attribute.generate(indentation, level));
172 }
173
174 code.push_str(&indentation.value(level));
175
176 if let Some(visibility) = &self.visibility {
177 code.push_str(&format!("{} ", visibility.generate(indentation, level)));
178 }
179
180 for modifier in &self.modifiers {
181 code.push_str(&format!("{} ", modifier.generate(indentation, level)));
182 }
183
184 if let Some(data_type) = &self.data_type {
185 code.push_str(&format!(
186 "const {} {} = {};\n",
187 data_type.generate(indentation, level),
188 self.name,
189 self.value.generate(indentation, level)
190 ));
191 } else {
192 code.push_str(&format!(
193 "const {} = {};\n",
194 self.name,
195 self.value.generate(indentation, level)
196 ));
197 }
198
199 code
200 }
201}
202
203impl Generator for Vec<ClassConstant> {
204 fn generate(&self, indentation: Indentation, level: usize) -> String {
205 let mut code = String::new();
206 if self.is_empty() {
207 return code;
208 }
209
210 for constant in self {
211 code.push_str(constant.generate(indentation, level).as_str());
212 code.push('\n');
213 }
214
215 code
216 }
217}
218
219impl<T: ToString, Tv: Into<Value>> From<(T, Tv)> for ClassConstant {
220 fn from((name, value): (T, Tv)) -> Self {
221 Self {
222 documentation: None,
223 attributes: vec![],
224 visibility: None,
225 modifiers: vec![],
226 data_type: None,
227 name: name.to_string(),
228 value: value.into(),
229 }
230 }
231}