1use pest::iterators::Pair;
2
3use super::{Integer, Rule};
4
5#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
6pub enum Type {
7 Literal(String),
8 Function {
9 params: Vec<Type>,
10 return_type: Box<Type>,
11 },
12 ArraySlice(Box<Type>),
13 TupleArray {
14 item_type: Box<Type>,
15 size: Integer<()>,
16 },
17}
18
19impl Type {
20 pub fn from_pair(pair: Pair<Rule>) -> Type {
21 match pair.as_rule() {
22 Rule::fnType => {
23 let mut inner = pair.into_inner().peekable();
24
25 let mut params = vec![];
26
27 while let Some(param) = inner.next() {
28 if inner.peek().is_some() {
29 params.push(Type::from_pair(param));
30 } else {
31 return Type::Function {
32 params,
33 return_type: Box::new(Type::from_pair(param)),
34 };
35 }
36 }
37 unreachable!();
38 }
39 Rule::typeName => {
40 let type_name = pair.as_str();
41 Self::Literal(type_name.to_owned())
42 }
43 Rule::arraySlice => {
44 let mut inner = pair.into_inner();
45
46 let type_name = inner.next().unwrap();
47 let type_name = Type::from_pair(type_name);
48 Self::ArraySlice(Box::new(type_name))
49 }
50 Rule::tupleArray => {
51 let mut inner = pair.into_inner();
52
53 let item_type = inner.next().unwrap();
54 let item_type = Type::from_pair(item_type);
55
56 let size = inner.next().unwrap();
57 let size = Integer::from_pair(size, "");
58
59 Self::TupleArray {
60 item_type: Box::new(item_type),
61 size,
62 }
63 }
64 _ => unreachable!(),
65 }
66 }
67}