asn1rs_model/model/
parse.rs1use 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}