cddl/ast/
parent.rs

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
11/// Parent visitor result
12pub type Result<T> = std::result::Result<T, Error>;
13
14/// Parent visitor error
15#[derive(Debug)]
16pub enum Error {
17  /// Tree overwrite error
18  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
35/// Parent trait retrieving the implemented type's parent
36pub trait Parent<'a, 'b: 'a, T> {
37  /// Returns the parent for the AST type
38  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
157/// Parent visitor type
158// #[derive(Clone)]
159pub struct ParentVisitor<'a, 'b: 'a> {
160  arena_tree: ArenaTree<'a, 'b>,
161}
162
163impl<'a, 'b: 'a> ParentVisitor<'a, 'b> {
164  /// Creates a new parent visitor given a CDDL reference
165  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(&param.param));
680    self.insert(parent, child)?;
681
682    self.visit_identifier(&param.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}