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 parser_iterator = iterator(input, parse_fragment);
89 let tokens = parser_iterator.collect::<Vec<Token>>();
90 let result: Result<_, _> = parser_iterator.finish();
91
92 match result {
93 Ok((unparsed, ())) => {
94 if !unparsed.is_empty() {
95 return Err(JqlParserError::ParsingError {
96 tokens: tokens.stringify(),
97 unparsed: unparsed.to_string(),
98 });
99 }
100
101 let truncate_count = tokens
102 .iter()
103 .filter(|&token| *token == Token::TruncateOperator)
104 .count();
105
106 if truncate_count > 1
107 || (truncate_count == 1 && tokens.last() != Some(&Token::TruncateOperator))
108 {
109 return Err(JqlParserError::TruncateError(tokens.stringify()));
110 }
111
112 Ok(tokens)
113 }
114 Err(_) => Err(JqlParserError::UnknownError),
115 }
116}
117
118#[cfg(test)]
119mod tests {
120 use super::{
121 parse,
122 parse_fragment,
123 };
124 use crate::{
125 errors::JqlParserError,
126 tokens::{
127 Index,
128 Lens,
129 LensValue,
130 Range,
131 Token,
132 View,
133 },
134 };
135
136 #[test]
137 fn check_array_index_selector() {
138 assert_eq!(
139 parse_fragment(&mut "[0,1,2]"),
140 Ok(Token::ArrayIndexSelector(vec![
141 Index(0),
142 Index(1),
143 Index(2)
144 ]))
145 );
146 assert_eq!(
147 parse_fragment(&mut " [ 0 , 1 , 2 ] "),
148 Ok(Token::ArrayIndexSelector(vec![
149 Index(0),
150 Index(1),
151 Index(2)
152 ]))
153 );
154 }
155
156 #[test]
157 fn check_array_range_selector() {
158 assert_eq!(
159 parse_fragment(&mut "[0:2]"),
160 Ok(Token::ArrayRangeSelector(Range(
161 Some(Index(0)),
162 Some(Index(2))
163 )))
164 );
165 assert_eq!(
166 parse_fragment(&mut "[:2]"),
167 Ok(Token::ArrayRangeSelector(Range(None, Some(Index(2)))))
168 );
169 assert_eq!(
170 parse_fragment(&mut "[0:]"),
171 Ok(Token::ArrayRangeSelector(Range(Some(Index(0)), None)))
172 );
173 assert_eq!(
174 parse_fragment(&mut "[:]"),
175 Ok(Token::ArrayRangeSelector(Range(None, None)))
176 );
177 }
178
179 #[test]
180 fn check_key_selector() {
181 assert_eq!(
182 parse_fragment(&mut r#""one""#),
183 Ok(Token::KeySelector("one"))
184 );
185 assert_eq!(
186 parse_fragment(&mut r#" "one" "#),
187 Ok(Token::KeySelector("one"))
188 );
189 }
190
191 #[test]
192 fn check_multi_key_selector() {
193 assert_eq!(
194 parse_fragment(&mut r#"{"one","two","three"}"#),
195 Ok(Token::MultiKeySelector(vec!["one", "two", "three"]))
196 );
197 assert_eq!(
198 parse_fragment(&mut r#" { "one", "two" , "three" } "#),
199 Ok(Token::MultiKeySelector(vec!["one", "two", "three"]))
200 );
201 }
202
203 #[test]
204 fn check_object_index_selector() {
205 assert_eq!(
206 parse_fragment(&mut "{0,1,2}"),
207 Ok(Token::ObjectIndexSelector(vec![
208 Index(0),
209 Index(1),
210 Index(2)
211 ]))
212 );
213 assert_eq!(
214 parse_fragment(&mut " { 0 , 1 , 2 } "),
215 Ok(Token::ObjectIndexSelector(vec![
216 Index(0),
217 Index(1),
218 Index(2)
219 ]))
220 );
221 }
222
223 #[test]
224 fn check_object_range_selector() {
225 assert_eq!(
226 parse_fragment(&mut "{0:2}"),
227 Ok(Token::ObjectRangeSelector(Range(
228 Some(Index(0)),
229 Some(Index(2))
230 )))
231 );
232 assert_eq!(
233 parse_fragment(&mut "{:2}"),
234 Ok(Token::ObjectRangeSelector(Range(None, Some(Index(2)))))
235 );
236 assert_eq!(
237 parse_fragment(&mut "{0:}"),
238 Ok(Token::ObjectRangeSelector(Range(Some(Index(0)), None)))
239 );
240 assert_eq!(
241 parse_fragment(&mut "{:}"),
242 Ok(Token::ObjectRangeSelector(Range(None, None)))
243 );
244 }
245
246 #[test]
247 fn check_lens_selector() {
248 assert_eq!(
249 parse_fragment(&mut r#"|={"abc""c","bcd""d"=123,"efg"=null,"hij"="test"}"#),
250 Ok(Token::LensSelector(vec![
251 Lens(
252 vec![Token::KeySelector("abc"), Token::KeySelector("c")],
253 None
254 ),
255 Lens(
256 vec![Token::KeySelector("bcd"), Token::KeySelector("d")],
257 Some(LensValue::Number(123))
258 ),
259 Lens(vec![Token::KeySelector("efg")], Some(LensValue::Null)),
260 Lens(
261 vec![Token::KeySelector("hij")],
262 Some(LensValue::String("test"))
263 ),
264 ]))
265 );
266 }
267
268 #[test]
269 fn check_flatten_operator() {
270 assert_eq!(parse_fragment(&mut ".."), Ok(Token::FlattenOperator));
271 assert_eq!(parse_fragment(&mut " .. "), Ok(Token::FlattenOperator));
272 }
273
274 #[test]
275 fn check_pipe_in_operator() {
276 assert_eq!(parse_fragment(&mut "|>"), Ok(Token::PipeInOperator));
277 assert_eq!(parse_fragment(&mut " |> "), Ok(Token::PipeInOperator));
278 }
279
280 #[test]
281 fn check_pipe_out_operator() {
282 assert_eq!(parse_fragment(&mut "<|"), Ok(Token::PipeOutOperator));
283 assert_eq!(parse_fragment(&mut " <| "), Ok(Token::PipeOutOperator));
284 }
285
286 #[test]
287 fn check_truncate_operator() {
288 assert_eq!(parse_fragment(&mut "!"), Ok(Token::TruncateOperator));
289 assert_eq!(parse_fragment(&mut " ! "), Ok(Token::TruncateOperator));
290 }
291
292 #[test]
293 fn check_group_separator() {
294 assert_eq!(parse_fragment(&mut ","), Ok(Token::GroupSeparator));
295 assert_eq!(parse_fragment(&mut " , "), Ok(Token::GroupSeparator));
296 }
297
298 #[test]
299 fn check_full_parser() {
300 assert_eq!(
301 parse(r#""this"[9,0]"#),
302 Ok(vec![
303 Token::KeySelector("this"),
304 Token::ArrayIndexSelector(vec![Index(9), Index(0)])
305 ]),
306 );
307 assert_eq!(
308 parse("[9,0]nope"),
309 Err(JqlParserError::ParsingError {
310 tokens: [Token::ArrayIndexSelector(vec![Index(9), Index(0)])].stringify(),
311 unparsed: "nope".to_string(),
312 })
313 );
314 assert_eq!(
315 parse(r#""this"[9,0]|>"some"<|"ok"..!"#),
316 Ok(vec![
317 Token::KeySelector("this"),
318 Token::ArrayIndexSelector(vec![Index(9), Index(0)]),
319 Token::PipeInOperator,
320 Token::KeySelector("some"),
321 Token::PipeOutOperator,
322 Token::KeySelector("ok"),
323 Token::FlattenOperator,
324 Token::TruncateOperator
325 ]),
326 );
327 assert_eq!(
328 parse(r#""a"!"b""#),
329 Err(JqlParserError::TruncateError(
330 [
331 Token::KeySelector("a"),
332 Token::TruncateOperator,
333 Token::KeySelector("b")
334 ]
335 .stringify()
336 ))
337 );
338 }
339}