asn1rs_model/model/
parse.rs

1use std::iter::Peekable;
2
3use crate::model::err::ErrorKind;
4use crate::parser::Token;
5
6pub trait PeekableTokens {
7    fn peek_or_err(&mut self) -> Result<&Token, ErrorKind>;
8
9    fn peek_is_text_eq(&mut self, text: &str) -> bool;
10
11    fn peek_is_text_eq_ignore_case(&mut self, text: &str) -> bool;
12
13    fn peek_is_separator_eq(&mut self, separator: char) -> bool;
14
15    #[inline]
16    fn peek_is_text_and_satisfies<F: FnOnce(&str) -> bool>(&mut self, probe: F) -> bool {
17        self.peek_or_err()
18            .ok()
19            .and_then(Token::text)
20            .map(probe)
21            .unwrap_or(false)
22    }
23
24    fn next_or_err(&mut self) -> Result<Token, ErrorKind>;
25
26    fn next_text_or_err(&mut self) -> Result<String, ErrorKind>;
27
28    fn next_text_eq_ignore_case_or_err(&mut self, text: &str) -> Result<Token, ErrorKind>;
29
30    fn next_text_eq_any_ignore_case_or_err(&mut self, texts: &[&str]) -> Result<Token, ErrorKind>;
31
32    #[inline]
33    fn next_is_text_and_eq_ignore_case(&mut self, text: &str) -> bool {
34        self.next_text_eq_ignore_case_or_err(text).is_ok()
35    }
36
37    fn next_if_separator_and_eq(&mut self, separator: char) -> Result<Token, ErrorKind>;
38
39    #[inline]
40    fn next_separator_eq_or_err(&mut self, separator: char) -> Result<(), ErrorKind> {
41        self.next_if_separator_and_eq(separator).map(drop)
42    }
43
44    #[inline]
45    fn next_is_separator_and_eq(&mut self, separator: char) -> bool {
46        self.next_separator_eq_or_err(separator).is_ok()
47    }
48}
49
50impl<T: Iterator<Item = Token>> PeekableTokens for Peekable<T> {
51    #[inline]
52    fn peek_or_err(&mut self) -> Result<&Token, ErrorKind> {
53        self.peek().ok_or(ErrorKind::UnexpectedEndOfStream)
54    }
55
56    #[inline]
57    fn peek_is_text_eq(&mut self, text: &str) -> bool {
58        self.peek()
59            .and_then(Token::text)
60            .map(|t| t.eq(text))
61            .unwrap_or(false)
62    }
63
64    #[inline]
65    fn peek_is_text_eq_ignore_case(&mut self, text: &str) -> bool {
66        self.peek()
67            .and_then(Token::text)
68            .map(|t| text.eq_ignore_ascii_case(t))
69            .unwrap_or(false)
70    }
71
72    #[inline]
73    fn peek_is_separator_eq(&mut self, separator: char) -> bool {
74        self.peek()
75            .map(|t| t.eq_separator(separator))
76            .unwrap_or(false)
77    }
78
79    #[inline]
80    fn next_or_err(&mut self) -> Result<Token, ErrorKind> {
81        self.next().ok_or(ErrorKind::UnexpectedEndOfStream)
82    }
83
84    #[inline]
85    fn next_text_or_err(&mut self) -> Result<String, ErrorKind> {
86        let peeked = self.peek_or_err()?;
87        if peeked.text().is_some() {
88            let token = self.next_or_err()?;
89            debug_assert!(token.text().is_some());
90            match token {
91                Token::Separator(..) => unreachable!(),
92                Token::Text(_, text) => Ok(text),
93            }
94        } else {
95            Err(ErrorKind::ExpectedText(peeked.clone()))
96        }
97    }
98
99    #[inline]
100    fn next_text_eq_ignore_case_or_err(&mut self, text: &str) -> Result<Token, ErrorKind> {
101        let peeked = self.peek_or_err()?;
102        if peeked.eq_text_ignore_ascii_case(text) {
103            let token = self.next_or_err()?;
104            debug_assert!(token.eq_text_ignore_ascii_case(text));
105            Ok(token)
106        } else {
107            Err(ErrorKind::ExpectedTextGot(text.to_string(), peeked.clone()))
108        }
109    }
110
111    #[inline]
112    fn next_text_eq_any_ignore_case_or_err(&mut self, texts: &[&str]) -> Result<Token, ErrorKind> {
113        let peeked = self.peek_or_err()?;
114        if matches!(peeked, Token::Text(_, token) if texts.iter().any(|text| token.eq_ignore_ascii_case(text)))
115        {
116            let token = self.next_or_err()?;
117            debug_assert!(
118                matches!(&token, Token::Text(_, token) if texts.iter().any(|text| token.eq_ignore_ascii_case(text)))
119            );
120            Ok(token)
121        } else {
122            Err(ErrorKind::UnexpectedToken(peeked.clone()))
123        }
124    }
125
126    #[inline]
127    fn next_if_separator_and_eq(&mut self, separator: char) -> Result<Token, ErrorKind> {
128        let peeked = self.peek_or_err()?;
129        if peeked.eq_separator(separator) {
130            let token = self.next_or_err()?;
131            debug_assert!(token.eq_separator(separator));
132            Ok(token)
133        } else {
134            Err(ErrorKind::ExpectedSeparatorGot(separator, peeked.clone()))
135        }
136    }
137}