Skip to main content

rd_ast/view/
encoding.rs

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    /// Encoding-dependent Latex-mode markup; encoding-side selection is consumer policy.
15    pub fn encoded(&self) -> &'a [RdNode] {
16        self.encoded
17    }
18    /// Encoding-dependent Latex-mode markup; encoding-side selection is consumer policy.
19    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}