1#![cfg(feature = "ast-parent")]
2
3use crate::{
4 ast::*,
5 token::{ByteValue, ControlOperator, Value},
6 visitor::{self, *},
7};
8
9use std::{borrow::Cow, fmt};
10
11pub type Result<T> = std::result::Result<T, Error>;
13
14#[derive(Debug)]
16pub enum Error {
17 Overwrite,
19}
20
21impl fmt::Display for Error {
22 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
23 match self {
24 Error::Overwrite => write!(f, "attempt to overwrite existing tree node"),
25 }
26 }
27}
28
29impl std::error::Error for Error {
30 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
31 None
32 }
33}
34
35pub trait Parent<'a, 'b: 'a, T> {
37 fn parent(&'a self, parent_visitor: &'b ParentVisitor<'a, 'b>) -> Option<&'a T>;
39}
40
41macro_rules! impl_parent {
42 ($($parent:ty => ([$($child:ty),+], $p:path)),* $(,)?) => {
43 $(
44 $(
45 impl<'a, 'b: 'a> Parent<'a, 'b, $parent> for $child {
46 fn parent(&'a self, parent_visitor: &'b ParentVisitor<'a, 'b>) -> Option<&'a $parent> {
47 if let Some($p(value)) = CDDLType::from(self).parent(parent_visitor) {
48 return Some(value);
49 }
50 None
51 }
52 }
53 )*
54 )*
55 };
56}
57
58impl_parent! {
59 CDDL<'a> => ([Rule<'a>], CDDLType::CDDL),
60 Rule<'a> => ([GroupRule<'a>, TypeRule<'a>], CDDLType::Rule),
61 TypeRule<'a> => ([Identifier<'a>, GenericParams<'a>, Type<'a>], CDDLType::TypeRule),
62 GroupRule<'a> => ([Identifier<'a>, GenericParams<'a>, GroupEntry<'a>], CDDLType::GroupRule),
63 Type<'a> => ([TypeChoice<'a>], CDDLType::Type),
64 TypeChoice<'a> => ([Type1<'a>], CDDLType::TypeChoice),
65 Type1<'a> => ([Operator<'a>, Type2<'a>], CDDLType::Type1),
66 Operator<'a> => ([Type2<'a>], CDDLType::Operator),
67 RangeCtlOp => ([ControlOperator], CDDLType::RangeCtlOp),
68 Type2<'a> => ([Identifier<'a>, GenericArgs<'a>, Type<'a>, Group<'a>], CDDLType::Type2),
69 Group<'a> => ([GroupChoice<'a>, Occurrence<'a>], CDDLType::Group),
70 GroupChoice<'a> => ([GroupEntry<'a>], CDDLType::GroupChoice),
71 GroupEntry<'a> => ([ValueMemberKeyEntry<'a>, TypeGroupnameEntry<'a>, Occurrence<'a>, Group<'a>], CDDLType::GroupEntry),
72 ValueMemberKeyEntry<'a> => ([Occurrence<'a>, MemberKey<'a>, Type<'a>], CDDLType::ValueMemberKeyEntry),
73 TypeGroupnameEntry<'a> => ([Occurrence<'a>, GenericArgs<'a>, Identifier<'a>], CDDLType::TypeGroupnameEntry),
74 MemberKey<'a> => ([Type1<'a>, Identifier<'a>, NonMemberKey<'a>], CDDLType::MemberKey),
75 GenericArgs<'a> => ([GenericArg<'a>], CDDLType::GenericArgs),
76 GenericArg<'a> => ([Type1<'a>], CDDLType::GenericArg),
77 GenericParams<'a> => ([GenericParam<'a>], CDDLType::GenericParams),
78 GenericParam<'a> => ([Identifier<'a>], CDDLType::GenericParam),
79 NonMemberKey<'a> => ([Group<'a>, Type<'a>], CDDLType::NonMemberKey),
80}
81
82impl<'a, 'b: 'a> Parent<'a, 'b, ()> for CDDL<'a> {
83 fn parent(&'a self, _parent_visitor: &'b ParentVisitor<'a, 'b>) -> Option<&'a ()> {
84 None
85 }
86}
87
88impl<'a, 'b: 'a> Parent<'a, 'b, Type2<'a>> for Value<'a> {
89 fn parent(&'a self, parent_visitor: &'b ParentVisitor<'a, 'b>) -> Option<&'a Type2<'a>> {
90 if let Some(CDDLType::Type2(value)) = CDDLType::from(self.to_owned()).parent(parent_visitor) {
91 return Some(value);
92 }
93
94 None
95 }
96}
97
98impl<'a, 'b: 'a> Parent<'a, 'b, MemberKey<'a>> for Value<'a> {
99 fn parent(&'a self, parent_visitor: &'b ParentVisitor<'a, 'b>) -> Option<&'a MemberKey<'a>> {
100 if let Some(CDDLType::MemberKey(value)) = CDDLType::from(self.to_owned()).parent(parent_visitor)
101 {
102 return Some(value);
103 }
104
105 None
106 }
107}
108
109impl<'a, 'b: 'a> Parent<'a, 'b, Occurrence<'a>> for Occur {
110 fn parent(&self, parent_visitor: &'b ParentVisitor<'a, 'b>) -> Option<&Occurrence<'a>> {
111 if let Some(CDDLType::Occurrence(value)) = CDDLType::from(*self).parent(parent_visitor) {
112 return Some(value);
113 }
114
115 None
116 }
117}
118
119#[derive(Debug, Default, Clone)]
120struct ArenaTree<'a, 'b: 'a> {
121 arena: Vec<Node<'a, 'b>>,
122}
123
124impl<'a, 'b: 'a> ArenaTree<'a, 'b> {
125 fn node(&mut self, val: CDDLType<'a, 'b>) -> usize {
126 for node in self.arena.iter() {
127 if node.val == val {
128 return node.idx;
129 }
130 }
131
132 let idx = self.arena.len();
133 self.arena.push(Node::new(idx, val));
134 idx
135 }
136}
137
138#[derive(Debug, Clone)]
139struct Node<'a, 'b: 'a> {
140 idx: usize,
141 val: CDDLType<'a, 'b>,
142 parent: Option<usize>,
143 children: Vec<usize>,
144}
145
146impl<'a, 'b: 'a> Node<'a, 'b> {
147 fn new(idx: usize, val: CDDLType<'a, 'b>) -> Self {
148 Self {
149 idx,
150 val,
151 parent: None,
152 children: vec![],
153 }
154 }
155}
156
157pub struct ParentVisitor<'a, 'b: 'a> {
160 arena_tree: ArenaTree<'a, 'b>,
161}
162
163impl<'a, 'b: 'a> ParentVisitor<'a, 'b> {
164 pub fn new(cddl: &'a CDDL<'a>) -> Result<Self> {
166 let mut p = ParentVisitor {
167 arena_tree: ArenaTree {
168 arena: Vec::default(),
169 },
170 };
171
172 p.visit_cddl(cddl)?;
173
174 Ok(p)
175 }
176}
177
178impl<'a, 'b: 'a> ParentVisitor<'a, 'b> {
179 fn insert(&mut self, parent: usize, child: usize) -> Result<()> {
180 if self.arena_tree.arena[child].parent.is_none() {
181 self.arena_tree.arena[child].parent = Some(parent);
182 }
183
184 self.arena_tree.arena[parent].children.push(child);
185
186 Ok(())
187 }
188}
189
190impl<'a, 'b: 'a> CDDLType<'a, 'b> {
191 pub fn parent(&self, visitor: &'b ParentVisitor<'a, 'b>) -> Option<&'b CDDLType<'a, 'b>> {
192 for node in visitor.arena_tree.arena.iter() {
193 if self == &node.val {
194 if let Some(parent_idx) = node.parent {
195 if let Some(parent) = visitor.arena_tree.arena.get(parent_idx) {
196 return Some(&parent.val);
197 }
198 }
199 }
200 }
201
202 None
203 }
204}
205
206impl<'a, 'b: 'a> Visitor<'a, 'b, Error> for ParentVisitor<'a, 'b> {
207 fn visit_cddl(&mut self, cddl: &'b CDDL<'a>) -> visitor::Result<Error> {
208 let parent = self.arena_tree.node(CDDLType::CDDL(cddl));
209 for rule in cddl.rules.iter() {
210 let child = self.arena_tree.node(CDDLType::Rule(rule));
211
212 self.insert(parent, child)?;
213
214 self.visit_rule(rule)?;
215 }
216
217 Ok(())
218 }
219
220 fn visit_rule(&mut self, rule: &'b Rule<'a>) -> visitor::Result<Error> {
221 let parent = self.arena_tree.node(CDDLType::Rule(rule));
222
223 match rule {
224 Rule::Group { rule, .. } => {
225 let child = self.arena_tree.node(CDDLType::GroupRule(rule));
226
227 self.insert(parent, child)?;
228
229 self.visit_group_rule(rule)?;
230 }
231 Rule::Type { rule, .. } => {
232 let child = self.arena_tree.node(CDDLType::TypeRule(rule));
233
234 self.insert(parent, child)?;
235
236 self.visit_type_rule(rule)?;
237 }
238 }
239
240 Ok(())
241 }
242
243 fn visit_type_rule(&mut self, tr: &'b TypeRule<'a>) -> visitor::Result<Error> {
244 let parent = self.arena_tree.node(CDDLType::TypeRule(tr));
245
246 let child = self.arena_tree.node(CDDLType::Identifier(&tr.name));
247 self.insert(parent, child)?;
248
249 if let Some(params) = &tr.generic_params {
250 let child = self.arena_tree.node(CDDLType::GenericParams(params));
251 self.insert(parent, child)?;
252
253 self.visit_generic_params(params)?;
254 }
255
256 let child = self.arena_tree.node(CDDLType::Type(&tr.value));
257 self.insert(parent, child)?;
258
259 self.visit_type(&tr.value)
260 }
261
262 fn visit_group_rule(&mut self, gr: &'b GroupRule<'a>) -> visitor::Result<Error> {
263 let parent = self.arena_tree.node(CDDLType::GroupRule(gr));
264
265 let child = self.arena_tree.node(CDDLType::Identifier(&gr.name));
266 self.insert(parent, child)?;
267 self.visit_identifier(&gr.name)?;
268
269 if let Some(params) = &gr.generic_params {
270 let child = self.arena_tree.node(CDDLType::GenericParams(params));
271 self.insert(parent, child)?;
272
273 self.visit_generic_params(params)?;
274 }
275
276 let child = self.arena_tree.node(CDDLType::GroupEntry(&gr.entry));
277 self.insert(parent, child)?;
278
279 self.visit_group_entry(&gr.entry)
280 }
281
282 fn visit_type(&mut self, t: &'b Type<'a>) -> visitor::Result<Error> {
283 let parent = self.arena_tree.node(CDDLType::Type(t));
284
285 for tc in t.type_choices.iter() {
286 let child = self.arena_tree.node(CDDLType::TypeChoice(tc));
287 self.insert(parent, child)?;
288
289 self.visit_type_choice(tc)?;
290 }
291
292 Ok(())
293 }
294
295 fn visit_type_choice(&mut self, tc: &'a TypeChoice<'a>) -> visitor::Result<Error> {
296 let parent = self.arena_tree.node(CDDLType::TypeChoice(tc));
297
298 let child = self.arena_tree.node(CDDLType::Type1(&tc.type1));
299 self.insert(parent, child)?;
300
301 self.visit_type1(&tc.type1)
302 }
303
304 fn visit_type1(&mut self, t1: &'b Type1<'a>) -> visitor::Result<Error> {
305 let parent = self.arena_tree.node(CDDLType::Type1(t1));
306
307 if let Some(operator) = &t1.operator {
308 let child = self.arena_tree.node(CDDLType::Operator(operator));
309 self.insert(parent, child)?;
310
311 self.visit_operator(t1, operator)?;
312 }
313
314 let child = self.arena_tree.node(CDDLType::Type2(&t1.type2));
315 self.insert(parent, child)?;
316
317 self.visit_type2(&t1.type2)
318 }
319
320 fn visit_operator(
321 &mut self,
322 target: &'b Type1<'a>,
323 o: &'b Operator<'a>,
324 ) -> visitor::Result<Error> {
325 let parent = self.arena_tree.node(CDDLType::Operator(o));
326 let child = self.arena_tree.node(CDDLType::Type2(&o.type2));
327 self.insert(parent, child)?;
328
329 let child = self.arena_tree.node(CDDLType::RangeCtlOp(&o.operator));
330 self.insert(parent, child)?;
331
332 self.visit_rangectlop(&o.operator, target, &o.type2)
333 }
334
335 fn visit_rangectlop(
336 &mut self,
337 op: &'b RangeCtlOp,
338 target: &'b Type1<'a>,
339 controller: &'b Type2<'a>,
340 ) -> visitor::Result<Error> {
341 match op {
342 RangeCtlOp::RangeOp { is_inclusive, .. } => {
343 self.visit_range(&target.type2, controller, *is_inclusive)
344 }
345 RangeCtlOp::CtlOp { ctrl, .. } => {
346 let parent = self.arena_tree.node(CDDLType::RangeCtlOp(op));
347 let child = self.arena_tree.node(CDDLType::ControlOperator(ctrl));
348 self.insert(parent, child)?;
349
350 self.visit_control_operator(&target.type2, *ctrl, controller)
351 }
352 }
353 }
354
355 fn visit_type2(&mut self, t2: &'b Type2<'a>) -> visitor::Result<Error> {
356 let parent = self.arena_tree.node(CDDLType::Type2(t2));
357
358 match t2 {
359 Type2::IntValue { value, .. } => {
360 let child = self.arena_tree.node(CDDLType::Value(Value::INT(*value)));
361 self.insert(parent, child)?;
362 }
363 Type2::UintValue { value, .. } => {
364 let child = self.arena_tree.node(CDDLType::Value(Value::UINT(*value)));
365 self.insert(parent, child)?;
366 }
367 Type2::FloatValue { value, .. } => {
368 let child = self.arena_tree.node(CDDLType::Value(Value::FLOAT(*value)));
369 self.insert(parent, child)?;
370 }
371 Type2::TextValue { value, .. } => {
372 let child = self
373 .arena_tree
374 .node(CDDLType::Value(Value::TEXT(Cow::Borrowed(value))));
375 self.insert(parent, child)?;
376 }
377 Type2::UTF8ByteString { value, .. } => {
378 let child = self
379 .arena_tree
380 .node(CDDLType::Value(Value::BYTE(ByteValue::UTF8(
381 Cow::Borrowed(value),
382 ))));
383 self.insert(parent, child)?;
384 }
385 Type2::B16ByteString { value, .. } => {
386 let child = self
387 .arena_tree
388 .node(CDDLType::Value(Value::BYTE(ByteValue::B16(Cow::Borrowed(
389 value,
390 )))));
391 self.insert(parent, child)?;
392 }
393 Type2::B64ByteString { value, .. } => {
394 let child = self
395 .arena_tree
396 .node(CDDLType::Value(Value::BYTE(ByteValue::B64(Cow::Borrowed(
397 value,
398 )))));
399 self.insert(parent, child)?;
400 }
401 Type2::Typename {
402 ident,
403 generic_args,
404 ..
405 } => {
406 let child = self.arena_tree.node(CDDLType::Identifier(ident));
407 self.insert(parent, child)?;
408
409 if let Some(generic_args) = generic_args {
410 let child = self.arena_tree.node(CDDLType::GenericArgs(generic_args));
411 self.insert(parent, child)?;
412
413 self.visit_generic_args(generic_args)?;
414 }
415 }
416 Type2::ParenthesizedType { pt, .. } => {
417 let child = self.arena_tree.node(CDDLType::Type(pt));
418 self.insert(parent, child)?;
419
420 self.visit_type(pt)?;
421 }
422 Type2::Map { group, .. } => {
423 let child = self.arena_tree.node(CDDLType::Group(group));
424 self.insert(parent, child)?;
425
426 self.visit_group(group)?;
427 }
428 Type2::Array { group, .. } => {
429 let child = self.arena_tree.node(CDDLType::Group(group));
430 self.insert(parent, child)?;
431
432 self.visit_group(group)?;
433 }
434 Type2::Unwrap { ident, .. } => {
435 let child = self.arena_tree.node(CDDLType::Identifier(ident));
436 self.insert(parent, child)?;
437
438 self.visit_identifier(ident)?;
439 }
440 Type2::ChoiceFromInlineGroup { group, .. } => {
441 let child = self.arena_tree.node(CDDLType::Group(group));
442 self.insert(parent, child)?;
443
444 self.visit_group(group)?;
445 }
446 Type2::ChoiceFromGroup {
447 ident,
448 generic_args,
449 ..
450 } => {
451 let child = self.arena_tree.node(CDDLType::Identifier(ident));
452 self.insert(parent, child)?;
453
454 if let Some(generic_args) = generic_args {
455 let child = self.arena_tree.node(CDDLType::GenericArgs(generic_args));
456 self.insert(parent, child)?;
457
458 self.visit_generic_args(generic_args)?;
459 }
460 }
461 Type2::TaggedData { t, .. } => {
462 let child = self.arena_tree.node(CDDLType::Type(t));
463 self.insert(parent, child)?;
464
465 self.visit_type(t)?;
466 }
467 _ => (),
468 }
469
470 Ok(())
471 }
472
473 fn visit_group(&mut self, g: &'b Group<'a>) -> visitor::Result<Error> {
474 let parent = self.arena_tree.node(CDDLType::Group(g));
475
476 for gc in g.group_choices.iter() {
477 let child = self.arena_tree.node(CDDLType::GroupChoice(gc));
478 self.insert(parent, child)?;
479
480 self.visit_group_choice(gc)?;
481 }
482
483 Ok(())
484 }
485
486 fn visit_group_choice(&mut self, gc: &'b GroupChoice<'a>) -> visitor::Result<Error> {
487 let parent = self.arena_tree.node(CDDLType::GroupChoice(gc));
488
489 for (ge, _) in gc.group_entries.iter() {
490 let child = self.arena_tree.node(CDDLType::GroupEntry(ge));
491 self.insert(parent, child)?;
492
493 self.visit_group_entry(ge)?;
494 }
495
496 Ok(())
497 }
498
499 fn visit_group_entry(&mut self, entry: &'b GroupEntry<'a>) -> visitor::Result<Error> {
500 let parent = self.arena_tree.node(CDDLType::GroupEntry(entry));
501
502 match entry {
503 GroupEntry::ValueMemberKey { ge, .. } => {
504 let child = self.arena_tree.node(CDDLType::ValueMemberKeyEntry(ge));
505 self.insert(parent, child)?;
506
507 self.visit_value_member_key_entry(ge)?;
508 }
509 GroupEntry::TypeGroupname { ge, .. } => {
510 let child = self.arena_tree.node(CDDLType::TypeGroupnameEntry(ge));
511 self.insert(parent, child)?;
512
513 self.visit_type_groupname_entry(ge)?;
514 }
515 GroupEntry::InlineGroup { occur, group, .. } => {
516 if let Some(occur) = occur {
517 let child = self.arena_tree.node(CDDLType::Occurrence(occur));
518 self.insert(parent, child)?;
519
520 self.visit_occurrence(occur)?;
521 }
522
523 let child = self.arena_tree.node(CDDLType::Group(group));
524 self.insert(parent, child)?;
525
526 self.visit_group(group)?;
527 }
528 }
529
530 Ok(())
531 }
532
533 fn visit_value_member_key_entry(
534 &mut self,
535 entry: &'b ValueMemberKeyEntry<'a>,
536 ) -> visitor::Result<Error> {
537 let parent = self.arena_tree.node(CDDLType::ValueMemberKeyEntry(entry));
538
539 if let Some(occur) = &entry.occur {
540 let child = self.arena_tree.node(CDDLType::Occurrence(occur));
541 self.insert(parent, child)?;
542
543 self.visit_occurrence(occur)?;
544 }
545
546 if let Some(mk) = &entry.member_key {
547 let child = self.arena_tree.node(CDDLType::MemberKey(mk));
548 self.insert(parent, child)?;
549
550 self.visit_memberkey(mk)?;
551 }
552
553 let child = self.arena_tree.node(CDDLType::Type(&entry.entry_type));
554 self.insert(parent, child)?;
555
556 self.visit_type(&entry.entry_type)
557 }
558
559 fn visit_type_groupname_entry(
560 &mut self,
561 entry: &'b TypeGroupnameEntry<'a>,
562 ) -> visitor::Result<Error> {
563 let parent = self.arena_tree.node(CDDLType::TypeGroupnameEntry(entry));
564
565 if let Some(o) = &entry.occur {
566 let child = self.arena_tree.node(CDDLType::Occurrence(o));
567 self.insert(parent, child)?;
568
569 self.visit_occurrence(o)?;
570 }
571
572 if let Some(ga) = &entry.generic_args {
573 let child = self.arena_tree.node(CDDLType::GenericArgs(ga));
574 self.insert(parent, child)?;
575
576 self.visit_generic_args(ga)?;
577 }
578
579 let child = self.arena_tree.node(CDDLType::Identifier(&entry.name));
580 self.insert(parent, child)?;
581
582 self.visit_identifier(&entry.name)
583 }
584
585 fn visit_inline_group_entry(
586 &mut self,
587 occur: Option<&'b Occurrence<'a>>,
588 g: &'b Group<'a>,
589 ) -> visitor::Result<Error> {
590 let parent = self.arena_tree.node(CDDLType::Group(g));
591
592 if let Some(o) = occur {
593 self.visit_occurrence(o)?;
594 }
595
596 for gc in g.group_choices.iter() {
597 let child = self.arena_tree.node(CDDLType::GroupChoice(gc));
598 self.insert(parent, child)?;
599 }
600
601 self.visit_group(g)
602 }
603
604 fn visit_occurrence(&mut self, o: &'b Occurrence<'a>) -> visitor::Result<Error> {
605 let parent = self.arena_tree.node(CDDLType::Occurrence(o));
606 let child = self.arena_tree.node(CDDLType::Occur(o.occur));
607 self.insert(parent, child)?;
608
609 Ok(())
610 }
611
612 fn visit_memberkey(&mut self, mk: &'b MemberKey<'a>) -> visitor::Result<Error> {
613 let parent = self.arena_tree.node(CDDLType::MemberKey(mk));
614
615 match mk {
616 MemberKey::Type1 { t1, .. } => {
617 let child = self.arena_tree.node(CDDLType::Type1(t1));
618 self.insert(parent, child)?;
619
620 self.visit_type1(t1)
621 }
622 MemberKey::Bareword { ident, .. } => {
623 let child = self.arena_tree.node(CDDLType::Identifier(ident));
624 self.insert(parent, child)?;
625
626 self.visit_identifier(ident)
627 }
628 MemberKey::Value { value, .. } => {
629 let child = self.arena_tree.node(CDDLType::Value(value.to_owned()));
630 self.insert(parent, child)?;
631
632 self.visit_value(value)
633 }
634 MemberKey::NonMemberKey { non_member_key, .. } => {
635 let child = self.arena_tree.node(CDDLType::NonMemberKey(non_member_key));
636 self.insert(parent, child)?;
637
638 self.visit_nonmemberkey(non_member_key)
639 }
640 }
641 }
642
643 fn visit_generic_args(&mut self, args: &'b GenericArgs<'a>) -> visitor::Result<Error> {
644 let parent = self.arena_tree.node(CDDLType::GenericArgs(args));
645
646 for arg in args.args.iter() {
647 let child = self.arena_tree.node(CDDLType::GenericArg(arg));
648 self.insert(parent, child)?;
649
650 self.visit_generic_arg(arg)?;
651 }
652
653 Ok(())
654 }
655
656 fn visit_generic_arg(&mut self, arg: &'b GenericArg<'a>) -> visitor::Result<Error> {
657 let parent = self.arena_tree.node(CDDLType::GenericArg(arg));
658 let child = self.arena_tree.node(CDDLType::Type1(&arg.arg));
659 self.insert(parent, child)?;
660
661 self.visit_type1(&arg.arg)
662 }
663
664 fn visit_generic_params(&mut self, params: &'b GenericParams<'a>) -> visitor::Result<Error> {
665 let parent = self.arena_tree.node(CDDLType::GenericParams(params));
666
667 for param in params.params.iter() {
668 let child = self.arena_tree.node(CDDLType::GenericParam(param));
669 self.insert(parent, child)?;
670
671 self.visit_generic_param(param)?;
672 }
673
674 Ok(())
675 }
676
677 fn visit_generic_param(&mut self, param: &'b GenericParam<'a>) -> visitor::Result<Error> {
678 let parent = self.arena_tree.node(CDDLType::GenericParam(param));
679 let child = self.arena_tree.node(CDDLType::Identifier(¶m.param));
680 self.insert(parent, child)?;
681
682 self.visit_identifier(¶m.param)
683 }
684
685 fn visit_nonmemberkey(&mut self, nmk: &'b NonMemberKey<'a>) -> visitor::Result<Error> {
686 let parent = self.arena_tree.node(CDDLType::NonMemberKey(nmk));
687
688 match nmk {
689 NonMemberKey::Group(group) => {
690 let child = self.arena_tree.node(CDDLType::Group(group));
691 self.insert(parent, child)?;
692
693 self.visit_group(group)
694 }
695 NonMemberKey::Type(t) => {
696 let child = self.arena_tree.node(CDDLType::Type(t));
697 self.insert(parent, child)?;
698
699 self.visit_type(t)
700 }
701 }
702 }
703}
704
705#[cfg(test)]
706#[cfg(not(target_arch = "wasm32"))]
707mod tests {
708 #![allow(unused_imports)]
709
710 use crate::cddl_from_str;
711 use std::borrow::Borrow;
712
713 use super::*;
714
715 #[test]
716 fn rule_parent_is_cddl() -> Result<()> {
717 let cddl = cddl_from_str(r#"a = "myrule""#, true).unwrap();
718 let pv = ParentVisitor::new(&cddl).unwrap();
719 let rule = cddl.rules.first().unwrap();
720
721 assert_eq!(rule.parent(&pv).unwrap(), &cddl);
722
723 Ok(())
724 }
725
726 #[test]
727 fn type_and_group_rule_parent_is_rule() -> Result<()> {
728 let cddl = cddl_from_str(
729 r#"
730 a = "myrule"
731 b = ( * tstr )
732 "#,
733 true,
734 )
735 .unwrap();
736 let pv = ParentVisitor::new(&cddl).unwrap();
737
738 if let r @ Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
739 assert_eq!(rule.parent(&pv).unwrap(), r);
740 }
741
742 if let r @ Rule::Group { rule, .. } = cddl.rules.get(1).unwrap() {
743 assert_eq!(rule.parent(&pv).unwrap(), r);
744 }
745
746 Ok(())
747 }
748
749 #[test]
750 fn type_parent_is_type_rule() -> Result<()> {
751 let cddl = cddl_from_str(r#"a = "myrule""#, true).unwrap();
752 let pv = ParentVisitor::new(&cddl).unwrap();
753
754 if let Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
755 let parent: &TypeRule = rule.value.parent(&pv).unwrap();
756 assert_eq!(parent, rule);
757 }
758
759 Ok(())
760 }
761
762 #[test]
763 fn type_choice_parent_is_type() -> Result<()> {
764 let cddl = cddl_from_str(r#"a = "myrule""#, true).unwrap();
765 let pv = ParentVisitor::new(&cddl).unwrap();
766
767 if let Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
768 assert_eq!(
769 rule
770 .value
771 .type_choices
772 .first()
773 .unwrap()
774 .parent(&pv)
775 .unwrap(),
776 &rule.value
777 );
778 }
779
780 Ok(())
781 }
782
783 #[test]
784 fn type1_parent_is_type_choice() -> Result<()> {
785 let cddl = cddl_from_str(r#"a = "myrule""#, true).unwrap();
786 let pv = ParentVisitor::new(&cddl).unwrap();
787
788 if let Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
789 let parent: &TypeChoice = rule
790 .value
791 .type_choices
792 .first()
793 .unwrap()
794 .type1
795 .parent(&pv)
796 .unwrap();
797
798 assert_eq!(parent, rule.value.type_choices.first().unwrap());
799 }
800
801 Ok(())
802 }
803
804 #[test]
805 fn type2_parent_is_type1() -> Result<()> {
806 let cddl = cddl_from_str(r#"a = "myrule""#, true).unwrap();
807 let pv = ParentVisitor::new(&cddl).unwrap();
808
809 if let Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
810 let parent: &Type1 = rule
811 .value
812 .type_choices
813 .first()
814 .unwrap()
815 .type1
816 .type2
817 .parent(&pv)
818 .unwrap();
819
820 assert_eq!(parent, &rule.value.type_choices.first().unwrap().type1);
821 }
822
823 Ok(())
824 }
825
826 #[test]
827 fn text_value_parent_is_type2() -> Result<()> {
828 let cddl = cddl_from_str(r#"a = "myrule""#, true).unwrap();
829 let pv = ParentVisitor::new(&cddl).unwrap();
830
831 if let Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
832 if let t2 @ Type2::TextValue { value, .. } =
833 &rule.value.type_choices.first().unwrap().type1.type2
834 {
835 let value = Value::from(value.borrow());
836
837 let parent: &Type2 = value.parent(&pv).unwrap();
838 assert_eq!(parent, t2);
839 }
840 }
841
842 Ok(())
843 }
844
845 #[test]
846 fn group_entry_parent_is_group_rule() -> Result<()> {
847 let cddl = cddl_from_str(r#"a = ( * tstr )"#, true).unwrap();
848 let pv = ParentVisitor::new(&cddl).unwrap();
849
850 if let Rule::Group { rule, .. } = cddl.rules.first().unwrap() {
851 let parent: &GroupRule = rule.entry.parent(&pv).unwrap();
852
853 assert_eq!(parent, rule.as_ref());
854 }
855
856 Ok(())
857 }
858
859 #[test]
860 fn type_rule_name_ident_parent_is_type_rule() -> Result<()> {
861 let cddl = cddl_from_str(r#"a = "myrule""#, true).unwrap();
862 let pv = ParentVisitor::new(&cddl).unwrap();
863
864 if let Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
865 let parent: &TypeRule = rule.name.parent(&pv).unwrap();
866 assert_eq!(parent, rule);
867 }
868
869 Ok(())
870 }
871
872 #[test]
873 fn generic_params_parent_is_type_rule() -> Result<()> {
874 let cddl = cddl_from_str(r#"a<t> = { type: t }"#, true).unwrap();
875 let pv = ParentVisitor::new(&cddl).unwrap();
876
877 if let Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
878 let parent: &TypeRule = rule.generic_params.as_ref().unwrap().parent(&pv).unwrap();
879
880 assert_eq!(parent, rule);
881 }
882
883 Ok(())
884 }
885
886 #[test]
887 fn generic_param_parent_is_generic_params() -> Result<()> {
888 let cddl = cddl_from_str(r#"a<t> = { type: t }"#, true).unwrap();
889 let pv = ParentVisitor::new(&cddl).unwrap();
890
891 if let Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
892 assert_eq!(
893 rule
894 .generic_params
895 .as_ref()
896 .unwrap()
897 .params
898 .first()
899 .unwrap()
900 .parent(&pv)
901 .unwrap(),
902 rule.generic_params.as_ref().unwrap()
903 );
904 }
905
906 Ok(())
907 }
908
909 #[test]
910 fn generic_args_parent_is_type2() -> Result<()> {
911 let cddl = cddl_from_str(
912 r#"
913 message<name, value> = {}
914 messages = message<"reboot", "now"> / message<"sleep", 1..100>
915 "#,
916 true,
917 )
918 .unwrap();
919 let pv = ParentVisitor::new(&cddl).unwrap();
920
921 if let Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
922 if let t2 @ Type2::Typename {
923 generic_args: Some(ga),
924 ..
925 } = &rule.value.type_choices.first().unwrap().type1.type2
926 {
927 let parent: &Type2 = ga.parent(&pv).unwrap();
928
929 assert_eq!(parent, t2);
930 }
931 }
932
933 Ok(())
934 }
935
936 #[test]
937 fn generic_arg_parent_is_generic_args() -> Result<()> {
938 let cddl = cddl_from_str(
939 r#"
940 message<name, value> = {}
941 messages = message<"reboot", "now"> / message<"sleep", 1..100>
942 "#,
943 true,
944 )
945 .unwrap();
946 let pv = ParentVisitor::new(&cddl).unwrap();
947
948 if let Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
949 if let Type2::Typename {
950 generic_args: Some(ga),
951 ..
952 } = &rule.value.type_choices.first().unwrap().type1.type2
953 {
954 assert_eq!(ga.args.first().unwrap().parent(&pv).unwrap(), ga);
955 }
956 }
957
958 Ok(())
959 }
960
961 #[test]
962 fn group_parent_is_type2() -> Result<()> {
963 let cddl = cddl_from_str(
964 r#"
965 a = { b }
966 b = ( * tstr => int )
967 "#,
968 true,
969 )
970 .unwrap();
971 let pv = ParentVisitor::new(&cddl).unwrap();
972
973 if let Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
974 if let t2 @ Type2::Map { group, .. } = &rule.value.type_choices.first().unwrap().type1.type2 {
975 let parent: &Type2 = group.parent(&pv).unwrap();
976
977 assert_eq!(parent, t2);
978 }
979 }
980
981 Ok(())
982 }
983
984 #[test]
985 fn identifier_parent_is_type2() -> Result<()> {
986 let cddl = cddl_from_str(
987 r#"
988 terminal-color = &basecolors
989 basecolors = (
990 black: 0, red: 1, green: 2, yellow: 3,
991 blue: 4, magenta: 5, cyan: 6, white: 7,
992 )
993 "#,
994 true,
995 )
996 .unwrap();
997 let pv = ParentVisitor::new(&cddl).unwrap();
998
999 if let Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
1000 if let t2 @ Type2::ChoiceFromGroup { ident, .. } =
1001 &rule.value.type_choices.first().unwrap().type1.type2
1002 {
1003 let parent: &Type2 = ident.parent(&pv).unwrap();
1004 assert_eq!(parent, t2);
1005 }
1006 }
1007
1008 Ok(())
1009 }
1010
1011 #[test]
1012 fn ctrl_parent_is_rangectlop() -> Result<()> {
1013 let cddl = cddl_from_str(r#"ip4 = bstr .size 4"#, true).unwrap();
1014 let pv = ParentVisitor::new(&cddl).unwrap();
1015
1016 if let Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
1017 if let op @ RangeCtlOp::CtlOp { ctrl, .. } = &rule
1018 .value
1019 .type_choices
1020 .first()
1021 .unwrap()
1022 .type1
1023 .operator
1024 .as_ref()
1025 .unwrap()
1026 .operator
1027 {
1028 assert_eq!(ctrl.parent(&pv).unwrap(), op)
1029 }
1030 }
1031
1032 Ok(())
1033 }
1034}