aldrin_parser/ast/
struct_def.rs1use super::{Attribute, Ident, LitPosInt, TypeName};
2use crate::error::{
3 DuplicateStructField, DuplicateStructFieldId, InvalidStructFieldId, RecursiveStruct,
4};
5use crate::grammar::Rule;
6use crate::validate::Validate;
7use crate::warning::{NonCamelCaseStruct, NonSnakeCaseStructField};
8use crate::Span;
9use pest::iterators::Pair;
10
11#[derive(Debug, Clone)]
12pub struct StructDef {
13 span: Span,
14 attrs: Vec<Attribute>,
15 name: Ident,
16 fields: Vec<StructField>,
17 fallback: Option<Ident>,
18}
19
20impl StructDef {
21 pub(crate) fn parse(pair: Pair<Rule>) -> Self {
22 assert_eq!(pair.as_rule(), Rule::struct_def);
23
24 let span = Span::from_pair(&pair);
25
26 let mut pairs = pair.into_inner();
27
28 let mut attrs = Vec::new();
29 for pair in &mut pairs {
30 match pair.as_rule() {
31 Rule::attribute => attrs.push(Attribute::parse(pair)),
32 Rule::kw_struct => break,
33 _ => unreachable!(),
34 }
35 }
36
37 let pair = pairs.next().unwrap();
38 let name = Ident::parse(pair);
39
40 pairs.next().unwrap(); let mut fields = Vec::new();
43 let mut fallback = None;
44
45 for pair in pairs {
46 match pair.as_rule() {
47 Rule::struct_field => fields.push(StructField::parse(pair)),
48
49 Rule::struct_fallback => {
50 let mut pairs = pair.into_inner();
51 let pair = pairs.next().unwrap();
52 fallback = Some(Ident::parse(pair));
53 }
54
55 Rule::tok_cur_close => break,
56 _ => unreachable!(),
57 }
58 }
59
60 Self {
61 span,
62 attrs,
63 name,
64 fields,
65 fallback,
66 }
67 }
68
69 pub(crate) fn validate(&self, validate: &mut Validate) {
70 DuplicateStructField::validate(
71 &self.fields,
72 self.fallback.as_ref(),
73 self.name.span(),
74 Some(&self.name),
75 validate,
76 );
77
78 DuplicateStructFieldId::validate(
79 &self.fields,
80 self.name.span(),
81 Some(&self.name),
82 validate,
83 );
84
85 NonCamelCaseStruct::validate(self, validate);
86 RecursiveStruct::validate(self, validate);
87
88 self.name.validate(validate);
89
90 for field in &self.fields {
91 field.validate(validate);
92 }
93
94 if let Some(ref fallback) = self.fallback {
95 fallback.validate(validate);
96 NonSnakeCaseStructField::validate(fallback, validate);
97 }
98 }
99
100 pub fn span(&self) -> Span {
101 self.span
102 }
103
104 pub fn attributes(&self) -> &[Attribute] {
105 &self.attrs
106 }
107
108 pub fn name(&self) -> &Ident {
109 &self.name
110 }
111
112 pub fn fields(&self) -> &[StructField] {
113 &self.fields
114 }
115
116 pub fn fallback(&self) -> Option<&Ident> {
117 self.fallback.as_ref()
118 }
119}
120
121#[derive(Debug, Clone)]
122pub struct InlineStruct {
123 span: Span,
124 kw_span: Span,
125 fields: Vec<StructField>,
126 fallback: Option<Ident>,
127}
128
129impl InlineStruct {
130 pub(crate) fn parse(pair: Pair<Rule>) -> Self {
131 assert_eq!(pair.as_rule(), Rule::struct_inline);
132
133 let span = Span::from_pair(&pair);
134
135 let mut pairs = pair.into_inner();
136
137 let pair = pairs.next().unwrap();
138 let kw_span = Span::from_pair(&pair);
139
140 pairs.next().unwrap(); let mut fields = Vec::new();
143 let mut fallback = None;
144
145 for pair in pairs {
146 match pair.as_rule() {
147 Rule::struct_field => fields.push(StructField::parse(pair)),
148
149 Rule::struct_fallback => {
150 let mut pairs = pair.into_inner();
151 let pair = pairs.next().unwrap();
152 fallback = Some(Ident::parse(pair));
153 }
154
155 Rule::tok_cur_close => break,
156 _ => unreachable!(),
157 }
158 }
159
160 Self {
161 span,
162 kw_span,
163 fields,
164 fallback,
165 }
166 }
167
168 pub(crate) fn validate(&self, validate: &mut Validate) {
169 DuplicateStructField::validate(
170 &self.fields,
171 self.fallback.as_ref(),
172 self.kw_span,
173 None,
174 validate,
175 );
176
177 DuplicateStructFieldId::validate(&self.fields, self.kw_span, None, validate);
178
179 for field in &self.fields {
180 field.validate(validate);
181 }
182
183 if let Some(ref fallback) = self.fallback {
184 fallback.validate(validate);
185 NonSnakeCaseStructField::validate(fallback, validate);
186 }
187 }
188
189 pub fn span(&self) -> Span {
190 self.span
191 }
192
193 pub fn keyword_span(&self) -> Span {
194 self.kw_span
195 }
196
197 pub fn fields(&self) -> &[StructField] {
198 &self.fields
199 }
200
201 pub fn fallback(&self) -> Option<&Ident> {
202 self.fallback.as_ref()
203 }
204}
205
206#[derive(Debug, Clone)]
207pub struct StructField {
208 span: Span,
209 req: bool,
210 name: Ident,
211 id: LitPosInt,
212 field_type: TypeName,
213}
214
215impl StructField {
216 fn parse(pair: Pair<Rule>) -> Self {
217 assert_eq!(pair.as_rule(), Rule::struct_field);
218
219 let span = Span::from_pair(&pair);
220
221 let mut pairs = pair.into_inner();
222
223 let pair = pairs.next().unwrap();
224 let req;
225 let name;
226 match pair.as_rule() {
227 Rule::kw_required => {
228 req = true;
229 let pair = pairs.next().unwrap();
230 name = Ident::parse(pair);
231 }
232 Rule::ident => {
233 req = false;
234 name = Ident::parse(pair);
235 }
236 _ => unreachable!(),
237 }
238
239 pairs.next().unwrap(); let pair = pairs.next().unwrap();
242 let id = LitPosInt::parse(pair);
243
244 pairs.next().unwrap(); let pair = pairs.next().unwrap();
247 let field_type = TypeName::parse(pair);
248
249 Self {
250 span,
251 req,
252 name,
253 id,
254 field_type,
255 }
256 }
257
258 fn validate(&self, validate: &mut Validate) {
259 InvalidStructFieldId::validate(self, validate);
260 NonSnakeCaseStructField::validate(&self.name, validate);
261
262 self.name.validate(validate);
263 self.field_type.validate(validate);
264 }
265
266 pub fn span(&self) -> Span {
267 self.span
268 }
269
270 pub fn required(&self) -> bool {
271 self.req
272 }
273
274 pub fn name(&self) -> &Ident {
275 &self.name
276 }
277
278 pub fn id(&self) -> &LitPosInt {
279 &self.id
280 }
281
282 pub fn field_type(&self) -> &TypeName {
283 &self.field_type
284 }
285}