1use super::*;
2
3#[derive(Debug, Clone, PartialEq)]
4pub struct RdEnc<'a> {
5 path: RdPath,
6 encoded: &'a [RdNode],
7 ascii: &'a [RdNode],
8}
9
10impl<'a> RdEnc<'a> {
11 pub fn path(&self) -> &RdPath {
12 &self.path
13 }
14 pub fn encoded(&self) -> &'a [RdNode] {
16 self.encoded
17 }
18 pub fn ascii(&self) -> &'a [RdNode] {
20 self.ascii
21 }
22}
23
24impl RdNode {
25 pub fn enc(&self, base_path: &RdPath) -> Option<RdEnc<'_>> {
26 self.inspect_enc(base_path).ok().flatten()
27 }
28
29 pub fn inspect_enc(&self, base_path: &RdPath) -> Result<Option<RdEnc<'_>>, RdShapeError> {
30 let tagged = match self {
31 RdNode::Tagged(tagged) => tagged,
32 RdNode::Raw(raw) => {
33 let Some(tag) = raw.tag().map(RdTag::from_rd_tag) else {
34 return Ok(None);
35 };
36 if tag != RdTag::Enc {
37 return Ok(None);
38 }
39 return Err(shape(
40 base_path.clone(),
41 Some(tag),
42 RdShapeErrorKind::UnexpectedNode {
43 expected: RdExpectedNode::Tagged,
44 actual: RdNodeKind::Raw,
45 },
46 ));
47 }
48 _ => return Ok(None),
49 };
50 if tagged.tag() != &RdTag::Enc {
51 return Ok(None);
52 }
53 if tagged.option().is_some() {
54 return Err(shape(
55 base_path.clone(),
56 Some(tagged.tag().clone()),
57 RdShapeErrorKind::UnexpectedOption,
58 ));
59 }
60 let children = tagged.children();
61 if children.len() != 2 {
62 return Err(shape(
63 base_path.clone(),
64 Some(tagged.tag().clone()),
65 RdShapeErrorKind::WrongArity {
66 expected: RdArity::Exactly(2),
67 actual: children.len(),
68 },
69 ));
70 }
71 for (index, child) in children.iter().enumerate() {
72 if child.as_group().is_none() {
73 return Err(shape(
74 base_path.with_child(index),
75 Some(tagged.tag().clone()),
76 RdShapeErrorKind::UnexpectedNode {
77 expected: RdExpectedNode::Group,
78 actual: RdNodeKind::of(child),
79 },
80 ));
81 }
82 }
83 Ok(Some(RdEnc {
84 path: base_path.clone(),
85 encoded: children[0].as_group().unwrap().children(),
86 ascii: children[1].as_group().unwrap().children(),
87 }))
88 }
89}