1use crate::aim::{Writer, WriterLike};
6use nom::{
7 Err as NomErr, IResult, Parser, branch::alt, bytes::complete::tag, combinator::opt,
8 error::Error,
9};
10use std::fmt;
11
12#[derive(Debug, Clone, PartialEq)]
16pub enum Typedef {
17 Any,
19 Array,
21 Collection,
23 Bool,
25 BoolArray,
27 Date,
29 DateArray,
31 Number,
33 NumberArray,
35 Task,
37 TaskArray,
39 Text,
41 TextArray,
43
44 Branch,
46 Closure,
48 Eval,
50 Format,
52 Instance,
54 Node,
56 Retry,
58}
59
60impl Typedef {
61 pub fn convert(input: &str) -> Self {
62 match parse_typedef(input) {
63 Ok((_, typedef)) => typedef,
64 _ => Typedef::Any,
65 }
66 }
67
68 pub fn is_any(&self) -> bool {
70 match self {
71 Typedef::Any | Typedef::Array => true,
72 _ => false,
73 }
74 }
75
76 pub fn is_any_array(&self) -> bool {
78 match self {
79 Typedef::Array => true,
80 _ => false,
81 }
82 }
83
84 pub fn is_collection(&self) -> bool {
86 match self {
87 Typedef::Collection => true,
88 _ => false,
89 }
90 }
91
92 pub fn is_bool(&self) -> bool {
94 match self {
95 Typedef::Bool | Typedef::BoolArray => true,
96 _ => false,
97 }
98 }
99
100 pub fn is_date(&self) -> bool {
102 match self {
103 Typedef::Date | Typedef::DateArray => true,
104 _ => false,
105 }
106 }
107
108 pub fn is_number(&self) -> bool {
110 match self {
111 Typedef::Number | Typedef::NumberArray => true,
112 _ => false,
113 }
114 }
115
116 pub fn is_task(&self) -> bool {
118 match self {
119 Typedef::Task | Typedef::TaskArray => true,
120 _ => false,
121 }
122 }
123
124 pub fn is_text(&self) -> bool {
126 match self {
127 Typedef::Text | Typedef::TextArray => true,
128 _ => false,
129 }
130 }
131
132 pub fn is_literal(&self) -> bool {
134 match self {
135 Typedef::Bool | Typedef::Number | Typedef::Date | Typedef::Task | Typedef::Text => true,
136 _ => false,
137 }
138 }
139
140 pub fn as_literal(&self) -> Self {
142 match self {
143 Typedef::Any | Typedef::Array | Typedef::Collection => Typedef::Any,
144 Typedef::Bool | Typedef::BoolArray => Typedef::Bool,
145 Typedef::Number | Typedef::NumberArray => Typedef::Number,
146 Typedef::Date | Typedef::DateArray => Typedef::Date,
147 Typedef::Task | Typedef::TaskArray => Typedef::Task,
148 Typedef::Text | Typedef::TextArray => Typedef::Text,
149 Typedef::Branch => Typedef::Branch,
150 Typedef::Closure => Typedef::Closure,
151 Typedef::Eval => Typedef::Eval,
152 Typedef::Format => Typedef::Format,
153 Typedef::Instance => Typedef::Instance,
154 Typedef::Node => Typedef::Node,
155 Typedef::Retry => Typedef::Retry,
156 }
157 }
158
159 pub fn is_array(&self) -> bool {
161 match self {
162 Typedef::Array
163 | Typedef::BoolArray
164 | Typedef::NumberArray
165 | Typedef::DateArray
166 | Typedef::TaskArray
167 | Typedef::TextArray => true,
168 _ => false,
169 }
170 }
171
172 pub fn as_array(&self) -> Self {
174 match self {
175 Typedef::Any | Typedef::Array | Typedef::Collection => Typedef::Array,
176 Typedef::Bool | Typedef::BoolArray => Typedef::BoolArray,
177 Typedef::Number | Typedef::NumberArray => Typedef::NumberArray,
178 Typedef::Date | Typedef::DateArray => Typedef::DateArray,
179 Typedef::Task | Typedef::TaskArray => Typedef::TaskArray,
180 Typedef::Text | Typedef::TextArray => Typedef::TextArray,
181 Typedef::Branch => Typedef::Branch,
182 Typedef::Closure => Typedef::Closure,
183 Typedef::Eval => Typedef::Eval,
184 Typedef::Format => Typedef::Format,
185 Typedef::Instance => Typedef::Instance,
186 Typedef::Node => Typedef::Node,
187 Typedef::Retry => Typedef::Retry,
188 }
189 }
190
191 pub fn is_branch(&self) -> bool {
193 match self {
194 Typedef::Branch => true,
195 _ => false,
196 }
197 }
198
199 pub fn is_closure(&self) -> bool {
201 match self {
202 Typedef::Closure => true,
203 _ => false,
204 }
205 }
206
207 pub fn is_eval(&self) -> bool {
209 match self {
210 Typedef::Eval => true,
211 _ => false,
212 }
213 }
214
215 pub fn is_format(&self) -> bool {
217 match self {
218 Typedef::Format => true,
219 _ => false,
220 }
221 }
222
223 pub fn is_instance(&self) -> bool {
225 match self {
226 Typedef::Instance => true,
227 _ => false,
228 }
229 }
230
231 pub fn is_node(&self) -> bool {
233 match self {
234 Typedef::Node => true,
235 _ => false,
236 }
237 }
238
239 pub fn is_retry(&self) -> bool {
241 match self {
242 Typedef::Retry => true,
243 _ => false,
244 }
245 }
246
247 pub fn is_special(&self) -> bool {
249 match self {
250 Typedef::Branch
251 | Typedef::Closure
252 | Typedef::Format
253 | Typedef::Eval
254 | Typedef::Node
255 | Typedef::Retry => true,
256 _ => false,
257 }
258 }
259
260 pub fn as_str(&self) -> &'static str {
269 match self {
270 Typedef::Any => "Any",
271 Typedef::Array => "Any[]",
272 Typedef::Collection => "Collection",
273
274 Typedef::Bool => "Bool",
275 Typedef::BoolArray => "Bool[]",
276 Typedef::Date => "Date",
277 Typedef::DateArray => "Date[]",
278 Typedef::Number => "Number",
279 Typedef::NumberArray => "Number[]",
280 Typedef::Task => "Task",
281 Typedef::TaskArray => "Task[]",
282 Typedef::Text => "Text",
283 Typedef::TextArray => "Text[]",
284
285 Typedef::Branch => "Branch",
286 Typedef::Closure => "Closure",
287 Typedef::Eval => "Eval",
288 Typedef::Format => "Format",
289 Typedef::Instance => "Instance",
290 Typedef::Node => "Node",
291 Typedef::Retry => "Retry",
292 }
293 }
294
295 pub fn print(&self, writer: &mut Writer) {
296 writer.write_str(self.as_str());
297 }
298
299 pub fn to_formula(&self) -> String {
300 let mut writer = Writer::formulizer();
301 writer.write_str(self.as_str());
302 writer.finish()
303 }
304}
305
306impl WriterLike for Typedef {
307 fn write(&self, writer: &mut Writer) {
308 self.print(writer);
309 }
310}
311
312impl fmt::Display for Typedef {
313 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
314 write!(f, "{}", self.to_stringized())
315 }
316}
317
318pub fn parse_typedef(input: &str) -> IResult<&str, Typedef> {
321 let (input, type_marker) = alt((
323 tag("Any"),
324 tag("Bool"),
325 tag("Date"),
326 tag("Number"),
327 tag("Task"),
328 tag("Text"),
329 tag("Collection"),
330 tag("Branch"),
331 tag("Closure"),
332 tag("Eval"),
333 tag("Format"),
334 tag("Instance"),
335 tag("Node"),
336 tag("Retry"),
337 ))
338 .parse(input)?;
339
340 let (input, array_marker) = opt(tag("[]")).parse(input)?;
342 let is_array = array_marker.is_some();
343
344 let typedef = match (type_marker, is_array) {
345 ("Any", false) => Typedef::Any,
346 ("Any", true) => Typedef::Array,
347 ("Bool", false) => Typedef::Bool,
348 ("Bool", true) => Typedef::BoolArray,
349 ("Date", false) => Typedef::Date,
350 ("Date", true) => Typedef::DateArray,
351 ("Number", false) => Typedef::Number,
352 ("Number", true) => Typedef::NumberArray,
353 ("Task", false) => Typedef::Task,
354 ("Task", true) => Typedef::TaskArray,
355 ("Text", false) => Typedef::Text,
356 ("Text", true) => Typedef::TextArray,
357
358 ("Collection", false) => Typedef::Collection,
359
360 ("Branch", false) => Typedef::Branch,
361 ("Closure", false) => Typedef::Closure,
362 ("Eval", false) => Typedef::Eval,
363 ("Format", false) => Typedef::Format,
364 ("Instance", false) => Typedef::Instance,
365 ("Node", false) => Typedef::Node,
366 ("Retry", false) => Typedef::Retry,
367 _ => {
368 return Err(NomErr::Failure(Error::new(
369 input,
370 nom::error::ErrorKind::Fail,
371 )));
372 }
373 };
374
375 Ok((input, typedef))
376}
377
378pub fn parse_literal_type(input: &str) -> IResult<&str, Typedef> {
381 let (input, type_marker) = alt((
383 tag("Bool"),
384 tag("Date"),
385 tag("Number"),
386 tag("Task"),
387 tag("Text"),
388 ))
389 .parse(input)?;
390 let typedef = match type_marker {
391 "Bool" => Typedef::Bool,
392 "Date" => Typedef::Date,
393 "Number" => Typedef::Number,
394 "Task" => Typedef::Task,
395 "Text" => Typedef::Text,
396 _ => unreachable!(),
397 };
398 Ok((input, typedef))
399}