1use super::*;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10#[non_exhaustive]
11pub enum RdExampleControlKind {
12 DontRun,
13 DontTest,
14 DontShow,
15 DontDiff,
16 TestOnly,
17}
18
19#[derive(Debug, Clone, PartialEq)]
21pub struct RdExampleControl<'a> {
22 path: RdPath,
23 kind: RdExampleControlKind,
24 body: &'a [RdNode],
25}
26
27impl<'a> RdExampleControl<'a> {
28 pub fn path(&self) -> &RdPath {
29 &self.path
30 }
31
32 pub fn kind(&self) -> RdExampleControlKind {
33 self.kind
34 }
35
36 pub fn body(&self) -> &'a [RdNode] {
40 self.body
41 }
42}
43
44fn example_control_kind(tag: &RdTag) -> Option<RdExampleControlKind> {
45 match tag {
46 RdTag::DontRun => Some(RdExampleControlKind::DontRun),
47 RdTag::DontTest => Some(RdExampleControlKind::DontTest),
48 RdTag::DontShow => Some(RdExampleControlKind::DontShow),
49 RdTag::DontDiff => Some(RdExampleControlKind::DontDiff),
50 RdTag::TestOnly => Some(RdExampleControlKind::TestOnly),
51 _ => None,
52 }
53}
54
55impl RdNode {
56 pub fn example_control(&self, base_path: &RdPath) -> Option<RdExampleControl<'_>> {
58 let tagged = self.as_tagged()?;
59 let kind = example_control_kind(tagged.tag())?;
60 tagged.option().is_none().then(|| RdExampleControl {
61 path: base_path.clone(),
62 kind,
63 body: tagged.children(),
64 })
65 }
66
67 pub fn inspect_example_control(
70 &self,
71 base_path: &RdPath,
72 ) -> Result<Option<RdExampleControl<'_>>, RdShapeError> {
73 match self {
74 RdNode::Tagged(tagged) => {
75 let Some(kind) = example_control_kind(tagged.tag()) else {
76 return Ok(None);
77 };
78 if tagged.option().is_some() {
79 return Err(shape(
80 base_path.clone(),
81 Some(tagged.tag().clone()),
82 RdShapeErrorKind::UnexpectedOption,
83 ));
84 }
85 Ok(Some(RdExampleControl {
86 path: base_path.clone(),
87 kind,
88 body: tagged.children(),
89 }))
90 }
91 RdNode::Raw(raw) => {
92 let Some(tag) = raw.tag().map(RdTag::from_rd_tag) else {
93 return Ok(None);
94 };
95 if example_control_kind(&tag).is_none() {
96 return Ok(None);
97 }
98 Err(shape(
99 base_path.clone(),
100 Some(tag),
101 RdShapeErrorKind::UnexpectedNode {
102 expected: RdExpectedNode::Tagged,
103 actual: RdNodeKind::Raw,
104 },
105 ))
106 }
107 _ => Ok(None),
108 }
109 }
110}