xrust/parser/combinators/
tag.rs1use crate::item::Node;
2use crate::parser::{ParseError, ParseInput, StaticState};
3use qualname::{NamespacePrefix, NamespaceUri};
4
5pub fn tag<'a, N: Node, L>(
6 expected: &str,
7) -> impl Fn(ParseInput<'a, N>, &mut StaticState<L>) -> Result<(ParseInput<'a, N>, ()), ParseError> + '_
8where
9 L: FnMut(&NamespacePrefix) -> Result<NamespaceUri, ParseError>,
10{
11 move |(input, state), _ss| match input.get(0..expected.len()) {
12 None => Err(ParseError::Combinator(format!(
13 "expected \"{}\" but didn't find it",
14 expected
15 ))),
16 Some(chars) => {
17 if chars == expected {
18 Ok(((&input[expected.len()..], state), ()))
19 } else {
20 Err(ParseError::Combinator(format!(
21 "expected \"{}\", found \"{}\"",
22 expected, chars
23 )))
24 }
25 }
26 }
27}
28
29pub(crate) fn anytag<'a, N: Node, L>(
32 s: Vec<&str>,
33) -> impl Fn(ParseInput<'a, N>, &mut StaticState<L>) -> Result<(ParseInput<'a, N>, String), ParseError>
34+ '_
35where
36 L: FnMut(&NamespacePrefix) -> Result<NamespaceUri, ParseError>,
37{
38 move |(input, state), _ss| {
39 let u = s.iter().fold("", |result, t| {
41 if t.len() > result.len() {
42 match input.get(0..t.len()) {
44 None => result,
45 Some(chars) => {
46 if chars == *t {
47 t
48 } else {
49 result
50 }
51 }
52 }
53 } else {
54 result
55 }
56 });
57 if u.is_empty() {
58 Err(ParseError::Combinator(String::from("anytag: no input")))
59 } else {
60 Ok(((&input[u.len()..], state), u.to_string()))
61 }
62 }
63}
64
65pub(crate) fn anychar<'a, N: Node, L>(
66 expected: char,
67) -> impl Fn(ParseInput<'a, N>, &mut StaticState<L>) -> Result<(ParseInput<'a, N>, ()), ParseError>
68where
69 L: FnMut(&NamespacePrefix) -> Result<NamespaceUri, ParseError>,
70{
71 move |(input, state), _ss| {
72 if input.starts_with(expected) {
73 Ok(((&input[1..], state), ()))
74 } else {
75 Err(ParseError::Combinator(String::from(
76 "anychar: unexpected characters",
77 )))
78 }
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use crate::parser::combinators::tag::{anychar, anytag, tag};
85 use crate::parser::{ParseError, ParserState, StaticStateBuilder};
86 use crate::trees::nullo::Nullo;
87 use qualname::NamespaceUri;
88
89 #[test]
90 fn parser_tag_test1() {
91 let testdoc = "<doc>";
92 let teststate: ParserState<Nullo> = ParserState::new();
93 let mut static_state = StaticStateBuilder::new()
94 .namespace(|_| {
95 NamespaceUri::try_from("urn:xrust").map_err(|_| ParseError::MissingNameSpace)
96 })
97 .build();
98 let parse_doc = tag("<");
99 assert_eq!(
100 Ok((("doc>", ParserState::new()), ())),
101 parse_doc((testdoc, teststate), &mut static_state)
102 );
103 }
104
105 #[test]
106 fn parser_tag_test2() {
107 let testdoc = "<doc>";
108 let teststate: ParserState<Nullo> = ParserState::new();
109 let mut static_state = StaticStateBuilder::new()
110 .namespace(|_| {
111 NamespaceUri::try_from("urn:xrust").map_err(|_| ParseError::MissingNameSpace)
112 })
113 .build();
114 let parse_doc = tag(">");
115 assert_eq!(
116 Err(ParseError::Combinator(String::from(
117 "expected \">\", found \"<\""
118 ))),
119 parse_doc((testdoc, teststate), &mut static_state)
120 );
121 }
122
123 #[test]
124 fn parser_tag_test3() {
125 let testdoc = "<?ProcessingInstruction?>";
126 let teststate: ParserState<Nullo> = ParserState::new();
127 let mut static_state = StaticStateBuilder::new()
128 .namespace(|_| {
129 NamespaceUri::try_from("urn:xrust").map_err(|_| ParseError::MissingNameSpace)
130 })
131 .build();
132 let parse_doc = tag("<?");
133 assert_eq!(
134 Ok((("ProcessingInstruction?>", ParserState::new()), ())),
135 parse_doc((testdoc, teststate), &mut static_state)
136 );
137 }
138
139 #[test]
140 fn parser_char_test1() {
141 let testdoc = "<doc>";
142 let teststate: ParserState<Nullo> = ParserState::new();
143 let mut static_state = StaticStateBuilder::new()
144 .namespace(|_| {
145 NamespaceUri::try_from("urn:xrust").map_err(|_| ParseError::MissingNameSpace)
146 })
147 .build();
148 let parse_doc = anychar('<');
149 assert_eq!(
150 Ok((("doc>", ParserState::new()), ())),
151 parse_doc((testdoc, teststate), &mut static_state)
152 )
153 }
154 #[test]
155 fn parser_char_test2() {
156 let testdoc = "<doc>";
157 let teststate: ParserState<Nullo> = ParserState::new();
158 let mut static_state = StaticStateBuilder::new()
159 .namespace(|_| {
160 NamespaceUri::try_from("urn:xrust").map_err(|_| ParseError::MissingNameSpace)
161 })
162 .build();
163 let parse_doc = anychar('>');
164 assert_eq!(
165 Err(ParseError::Combinator(String::from(
166 "anychar: unexpected characters"
167 ))),
168 parse_doc((testdoc, teststate), &mut static_state)
169 )
170 }
171 #[test]
172 fn parser_anytag_test1() {
173 let testdoc = "<doc>";
174 let teststate: ParserState<Nullo> = ParserState::new();
175 let mut static_state = StaticStateBuilder::new()
176 .namespace(|_| {
177 NamespaceUri::try_from("urn:xrust").map_err(|_| ParseError::MissingNameSpace)
178 })
179 .build();
180 let parse_doc = anytag(vec![">", ">=", "<=", "<"]);
181 assert_eq!(
182 Ok((("doc>", ParserState::new()), "<".to_string())),
183 parse_doc((testdoc, teststate), &mut static_state)
184 )
185 }
186 #[test]
187 fn parser_anytag_test2() {
188 let testdoc = "<=>";
189 let teststate: ParserState<Nullo> = ParserState::new();
190 let mut static_state = StaticStateBuilder::new()
191 .namespace(|_| {
192 NamespaceUri::try_from("urn:xrust").map_err(|_| ParseError::MissingNameSpace)
193 })
194 .build();
195 let parse_doc = anytag(vec![">", ">=", "<=", "<"]);
196 assert_eq!(
197 Ok(((">", ParserState::new()), "<=".to_string())),
198 parse_doc((testdoc, teststate), &mut static_state)
199 )
200 }
201}