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
use pest::iterators::Pair;
use crate::models::{structure::{Field, Structure}, types::Type};
use super::{error::ParsingError, FromPest, Rule};
impl FromPest for Structure {
fn from_pest(element: Pair<'_, Rule>) -> Result<Self, ParsingError>
where
Self: Sized
{
match element.as_rule() {
Rule::STRUCTURE => {
let mut docs = None;
let mut name = String::new();
let mut fields = vec![];
for struct_element in element.into_inner() {
match struct_element.as_rule() {
Rule::DOCS => {
for docs_element in struct_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 = struct_element.as_span().as_str().to_owned();
},
Rule::FIELDS => {
for fields_element in struct_element.into_inner() {
if let Rule::FIELD = fields_element.as_rule() {
let field = Field::from_pest(fields_element)?;
if fields.contains(&field) {
log::warn!("Field with name `{}` already exists in structure `{name}`!", field.name())
} else {
fields.push(field);
}
}
}
}
_ => {},
}
}
Ok(Structure::new(docs, name, fields))
},
_ => Err(
ParsingError::InvalidPestRule {
expected: Rule::STRUCTURE,
found: element.as_rule(),
}
)
}
}
}
impl FromPest for Field {
fn from_pest(element: Pair<'_, Rule>) -> Result<Self, ParsingError>
where
Self: Sized
{
match element.as_rule() {
Rule::FIELD => {
let mut docs = None;
let mut name = String::new();
let mut ty = Type::default();
for field_element in element.into_inner() {
match field_element.as_rule() {
Rule::DOCS => {
for docs_element in field_element.into_inner() {
docs = Some(docs_element.as_span().as_str().to_owned())
.filter(|s| !s.is_empty());
}
},
Rule::IDENT => {
name = field_element.as_span().as_str().to_owned();
},
Rule::TYPE => {
ty = Type::from_pest(field_element)?;
},
_ => {},
}
}
Ok(Field::new(docs, name, ty))
},
_ => Err(
ParsingError::InvalidPestRule {
expected: Rule::FIELD,
found: element.as_rule(),
}
)
}
}
}