1use winnow::{
2 Parser,
3 Result,
4 combinator::{
5 alt,
6 dispatch,
7 fail,
8 iterator,
9 peek,
10 },
11 token::any,
12};
13
14use crate::{
15 combinators::{
16 parse_array_index,
17 parse_array_range,
18 parse_flatten_operator,
19 parse_group_separator,
20 parse_key,
21 parse_keys_operator,
22 parse_lenses,
23 parse_multi_key,
24 parse_object_index,
25 parse_object_range,
26 parse_pipe_in_operator,
27 parse_pipe_out_operator,
28 parse_truncate_operator,
29 trim,
30 },
31 errors::JqlParserError,
32 tokens::{
33 Lens,
34 Range,
35 Token,
36 View,
37 },
38};
39
40fn parse_fragment<'a>(input: &mut &'a str) -> Result<Token<'a>> {
42 trim(
43 dispatch! {peek(any);
44 '[' => {
45 alt((
46 parse_array_index.map(Token::ArrayIndexSelector),
47 parse_array_range.map(|(start, end)| Token::ArrayRangeSelector(Range(start, end))),
48 ))
49 },
50 '"' => parse_key.map(Token::KeySelector),
51 '{' => {
52 alt((
53 parse_multi_key.map(Token::MultiKeySelector),
54 parse_object_index.map(Token::ObjectIndexSelector),
55 parse_object_range.map(|(start, end)| Token::ObjectRangeSelector(Range(start, end))),
56 ))
57 },
58 '|' => {
59 alt((
60 parse_lenses.map(|lenses| {
61 Token::LensSelector(
62 lenses
63 .into_iter()
64 .map(|(tokens, value)| Lens(tokens, value))
65 .collect(),
66 )
67 }),
68 parse_pipe_in_operator.value(Token::PipeInOperator),
69 ))
70 },
71 '@' => parse_keys_operator.value(Token::KeyOperator),
72 '.' => parse_flatten_operator.value(Token::FlattenOperator),
73 '<' => parse_pipe_out_operator.value(Token::PipeOutOperator),
74 ',' => parse_group_separator.value(Token::GroupSeparator),
75 '!' => parse_truncate_operator.value(Token::TruncateOperator),
76 _ => fail
77 }
78 )
79 .parse_next(input)
80}
81
82pub fn parse(input: &str) -> Result<Vec<Token<'_>>, JqlParserError> {
88 let mut input = input;
89 let mut parser_iterator = iterator(&mut input, parse_fragment);
90 let tokens = parser_iterator.collect::<Vec<Token>>();
91 let result: Result<_, _> = parser_iterator.finish();
92
93 match result {
94 Ok(()) => {
95 if !input.is_empty() {
96 return Err(JqlParserError::ParsingError {
97 tokens: tokens.stringify(),
98 unparsed: input.to_string(),
99 });
100 }
101
102 let truncate_count = tokens
103 .iter()
104 .filter(|&token| *token == Token::TruncateOperator)
105 .count();
106
107 if truncate_count > 1
108 || (truncate_count == 1 && tokens.last() != Some(&Token::TruncateOperator))
109 {
110 return Err(JqlParserError::TruncateError(tokens.stringify()));
111 }
112
113 Ok(tokens)
114 }
115 Err(_) => Err(JqlParserError::UnknownError),
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use super::{
122 parse,
123 parse_fragment,
124 };
125 use crate::{
126 errors::JqlParserError,
127 tokens::{
128 Index,
129 Lens,
130 LensValue,
131 Range,
132 Token,
133 View,
134 },
135 };
136
137 #[test]
138 fn check_array_index_selector() {
139 assert_eq!(
140 parse_fragment(&mut "[0,1,2]"),
141 Ok(Token::ArrayIndexSelector(vec![
142 Index(0),
143 Index(1),
144 Index(2)
145 ]))
146 );
147 assert_eq!(
148 parse_fragment(&mut " [ 0 , 1 , 2 ] "),
149 Ok(Token::ArrayIndexSelector(vec![
150 Index(0),
151 Index(1),
152 Index(2)
153 ]))
154 );
155 }
156
157 #[test]
158 fn check_array_range_selector() {
159 assert_eq!(
160 parse_fragment(&mut "[0:2]"),
161 Ok(Token::ArrayRangeSelector(Range(
162 Some(Index(0)),
163 Some(Index(2))
164 )))
165 );
166 assert_eq!(
167 parse_fragment(&mut "[:2]"),
168 Ok(Token::ArrayRangeSelector(Range(None, Some(Index(2)))))
169 );
170 assert_eq!(
171 parse_fragment(&mut "[0:]"),
172 Ok(Token::ArrayRangeSelector(Range(Some(Index(0)), None)))
173 );
174 assert_eq!(
175 parse_fragment(&mut "[:]"),
176 Ok(Token::ArrayRangeSelector(Range(None, None)))
177 );
178 }
179
180 #[test]
181 fn check_key_selector() {
182 assert_eq!(
183 parse_fragment(&mut r#""one""#),
184 Ok(Token::KeySelector("one"))
185 );
186 assert_eq!(
187 parse_fragment(&mut r#" "one" "#),
188 Ok(Token::KeySelector("one"))
189 );
190 }
191
192 #[test]
193 fn check_multi_key_selector() {
194 assert_eq!(
195 parse_fragment(&mut r#"{"one","two","three"}"#),
196 Ok(Token::MultiKeySelector(vec!["one", "two", "three"]))
197 );
198 assert_eq!(
199 parse_fragment(&mut r#" { "one", "two" , "three" } "#),
200 Ok(Token::MultiKeySelector(vec!["one", "two", "three"]))
201 );
202 }
203
204 #[test]
205 fn check_object_index_selector() {
206 assert_eq!(
207 parse_fragment(&mut "{0,1,2}"),
208 Ok(Token::ObjectIndexSelector(vec![
209 Index(0),
210 Index(1),
211 Index(2)
212 ]))
213 );
214 assert_eq!(
215 parse_fragment(&mut " { 0 , 1 , 2 } "),
216 Ok(Token::ObjectIndexSelector(vec![
217 Index(0),
218 Index(1),
219 Index(2)
220 ]))
221 );
222 }
223
224 #[test]
225 fn check_object_range_selector() {
226 assert_eq!(
227 parse_fragment(&mut "{0:2}"),
228 Ok(Token::ObjectRangeSelector(Range(
229 Some(Index(0)),
230 Some(Index(2))
231 )))
232 );
233 assert_eq!(
234 parse_fragment(&mut "{:2}"),
235 Ok(Token::ObjectRangeSelector(Range(None, Some(Index(2)))))
236 );
237 assert_eq!(
238 parse_fragment(&mut "{0:}"),
239 Ok(Token::ObjectRangeSelector(Range(Some(Index(0)), None)))
240 );
241 assert_eq!(
242 parse_fragment(&mut "{:}"),
243 Ok(Token::ObjectRangeSelector(Range(None, None)))
244 );
245 }
246
247 #[test]
248 fn check_lens_selector() {
249 assert_eq!(
250 parse_fragment(&mut r#"|={"abc""c","bcd""d"=123,"efg"=null,"hij"="test"}"#),
251 Ok(Token::LensSelector(vec![
252 Lens(
253 vec![Token::KeySelector("abc"), Token::KeySelector("c")],
254 None
255 ),
256 Lens(
257 vec![Token::KeySelector("bcd"), Token::KeySelector("d")],
258 Some(LensValue::Number(123))
259 ),
260 Lens(vec![Token::KeySelector("efg")], Some(LensValue::Null)),
261 Lens(
262 vec![Token::KeySelector("hij")],
263 Some(LensValue::String("test"))
264 ),
265 ]))
266 );
267 }
268
269 #[test]
270 fn check_flatten_operator() {
271 assert_eq!(parse_fragment(&mut ".."), Ok(Token::FlattenOperator));
272 assert_eq!(parse_fragment(&mut " .. "), Ok(Token::FlattenOperator));
273 }
274
275 #[test]
276 fn check_pipe_in_operator() {
277 assert_eq!(parse_fragment(&mut "|>"), Ok(Token::PipeInOperator));
278 assert_eq!(parse_fragment(&mut " |> "), Ok(Token::PipeInOperator));
279 }
280
281 #[test]
282 fn check_pipe_out_operator() {
283 assert_eq!(parse_fragment(&mut "<|"), Ok(Token::PipeOutOperator));
284 assert_eq!(parse_fragment(&mut " <| "), Ok(Token::PipeOutOperator));
285 }
286
287 #[test]
288 fn check_truncate_operator() {
289 assert_eq!(parse_fragment(&mut "!"), Ok(Token::TruncateOperator));
290 assert_eq!(parse_fragment(&mut " ! "), Ok(Token::TruncateOperator));
291 }
292
293 #[test]
294 fn check_group_separator() {
295 assert_eq!(parse_fragment(&mut ","), Ok(Token::GroupSeparator));
296 assert_eq!(parse_fragment(&mut " , "), Ok(Token::GroupSeparator));
297 }
298
299 #[test]
300 fn check_full_parser() {
301 assert_eq!(
302 parse(r#""this"[9,0]"#),
303 Ok(vec![
304 Token::KeySelector("this"),
305 Token::ArrayIndexSelector(vec![Index(9), Index(0)])
306 ]),
307 );
308 assert_eq!(
309 parse("[9,0]nope"),
310 Err(JqlParserError::ParsingError {
311 tokens: [Token::ArrayIndexSelector(vec![Index(9), Index(0)])].stringify(),
312 unparsed: "nope".to_string(),
313 })
314 );
315 assert_eq!(
316 parse(r#""this"[9,0]|>"some"<|"ok"..!"#),
317 Ok(vec![
318 Token::KeySelector("this"),
319 Token::ArrayIndexSelector(vec![Index(9), Index(0)]),
320 Token::PipeInOperator,
321 Token::KeySelector("some"),
322 Token::PipeOutOperator,
323 Token::KeySelector("ok"),
324 Token::FlattenOperator,
325 Token::TruncateOperator
326 ]),
327 );
328 assert_eq!(
329 parse(r#""a"!"b""#),
330 Err(JqlParserError::TruncateError(
331 [
332 Token::KeySelector("a"),
333 Token::TruncateOperator,
334 Token::KeySelector("b")
335 ]
336 .stringify()
337 ))
338 );
339 }
340}