1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
use pest::iterators::Pair;
use crate::models::{
function::{Arg, Function, FunctionType},
types::{PathType, Primitive, Type, Vector},
};
use super::{error::ParsingError, FromPest, Rule};
impl FromPest for Function {
fn from_pest(element: Pair<'_, Rule>) -> Result<Self, ParsingError>
where
Self: Sized
{
match element.as_rule() {
Rule::FUNCTION => {
let mut docs = None;
let mut name = String::new();
let mut args = vec![];
let mut return_ty = None;
for function_element in element.into_inner() {
match function_element.as_rule() {
Rule::DOCS => {
for docs_element in function_element.into_inner() {
if docs.is_none() {
docs = Some(String::new());
}
if let Some(docs) = &mut docs {
if !docs.is_empty() {
docs.push('\n');
}
docs.push_str(docs_element.as_span().as_str());
}
docs = docs.filter(|s| !s.is_empty());
}
},
Rule::IDENT => {
name = function_element.as_span().as_str().to_owned();
},
Rule::ARGS => {
for args_element in function_element.into_inner() {
if let Rule::ARG = args_element.as_rule() {
let arg = Arg::from_pest(args_element)?;
if args.contains(&arg) {
log::warn!("Argument with name `{}` already exists in function `{name}`!", arg.name())
} else {
args.push(arg);
}
}
}
},
Rule::RETURN => {
return_ty = Some(Type::from_pest(function_element.into_inner().next().unwrap())?)
}
_ => {},
}
}
Ok(Function::new(docs, name, args, return_ty))
},
_ => Err(
ParsingError::InvalidPestRule {
expected: Rule::FUNCTION,
found: element.as_rule(),
}
)
}
}
}
impl FromPest for Arg {
fn from_pest(element: Pair<'_, Rule>) -> Result<Self, ParsingError>
where
Self: Sized
{
match element.as_rule() {
Rule::ARG => {
let mut docs = None;
let mut name = String::new();
let mut ty = FunctionType::default();
for arg_element in element.into_inner() {
match arg_element.as_rule() {
Rule::DOCS => {
for docs_element in arg_element.into_inner() {
docs = Some(docs_element.as_span().as_str().to_owned())
.filter(|s| !s.is_empty());
}
},
Rule::IDENT => {
name = arg_element.as_span().as_str().to_owned();
},
Rule::FUNCTION_TYPE => {
ty = FunctionType::from_pest(arg_element)?;
}
_ => {},
}
}
Ok(Arg::new(docs, name, ty))
},
_ => Err(
ParsingError::InvalidPestRule {
expected: Rule::ARG,
found: element.as_rule(),
}
)
}
}
}
impl FromPest for FunctionType {
fn from_pest(element: Pair<'_, Rule>) -> Result<Self, ParsingError>
where
Self: Sized
{
match element.as_rule() {
Rule::FUNCTION_TYPE => {
let mut ty = FunctionType::default();
for type_element in element.into_inner() {
match type_element.as_rule() {
Rule::PRIMITIVE => {
ty = FunctionType::Primitive(Primitive::from_pest(type_element)?);
},
Rule::VECTOR => {
ty = FunctionType::Vector(Vector::from_pest(type_element)?);
},
Rule::PATH_TYPE => {
ty = FunctionType::Path(PathType::from_pest(type_element)?);
},
Rule::FUNCTION_POINTER => {
ty = FunctionType::FunctionPointer(
Type::from_pest(type_element.into_inner().next().unwrap())?
);
}
_ => {}
}
}
Ok(ty)
},
_ => Err(
ParsingError::InvalidPestRule {
expected: Rule::FUNCTION_TYPE,
found: element.as_rule(),
}
)
}
}
}