1 use combine::{
2 parser::{
3 char::{digit, letter},
4 choice::choice,
5 combinator::not_followed_by,
6 range::range,
7 token::{any, eof, token, Token},
8 },
9 Parser,
10 };
11
12 #[test]
choice_empty()13 fn choice_empty() {
14 let mut parser = choice::<_, &mut [Token<&str>]>(&mut []);
15 let result_err = parser.parse("a");
16 assert!(result_err.is_err());
17 }
18
19 #[test]
tuple()20 fn tuple() {
21 let mut parser = (digit(), token(','), digit(), token(','), letter());
22 assert_eq!(parser.parse("1,2,z"), Ok((('1', ',', '2', ',', 'z'), "")));
23 }
24
25 #[test]
issue_99()26 fn issue_99() {
27 let result = any().map(|_| ()).or(eof()).parse("");
28 assert!(result.is_ok(), "{:?}", result);
29 }
30
31 #[test]
not_followed_by_does_not_consume_any_input()32 fn not_followed_by_does_not_consume_any_input() {
33 let mut parser = not_followed_by(range("a")).map(|_| "").or(range("a"));
34
35 assert_eq!(parser.parse("a"), Ok(("a", "")));
36
37 let mut parser = range("a").skip(not_followed_by(range("aa")));
38
39 assert_eq!(parser.parse("aa"), Ok(("a", "a")));
40 assert!(parser.parse("aaa").is_err());
41 }
42
43 #[cfg(feature = "std")]
44 mod tests_std {
45 use super::*;
46
47 use combine::easy::{Error, Errors};
48 use combine::parser::byte::alpha_num;
49 use combine::parser::byte::bytes;
50 use combine::parser::byte::bytes_cmp;
51 use combine::parser::byte::num::be_u32;
52 use combine::parser::char::char;
53 use combine::parser::char::{string, string_cmp};
54 use combine::parser::combinator::no_partial;
55 use combine::parser::range;
56 use combine::parser::repeat::{skip_until, take_until};
57 use combine::stream::position;
58 use combine::stream::position::SourcePosition;
59 use combine::{
60 attempt, count, count_min_max, easy, many, optional, position, sep_by, sep_end_by1,
61 unexpected, value, EasyParser,
62 };
63
64 #[derive(Clone, PartialEq, Debug)]
65 struct CloneOnly {
66 s: String,
67 }
68
69 #[test]
token_clone_but_not_copy()70 fn token_clone_but_not_copy() {
71 // Verify we can use token() with a StreamSlice with an token type that is Clone but not
72 // Copy.
73 let input = &[
74 CloneOnly { s: "x".to_string() },
75 CloneOnly { s: "y".to_string() },
76 ][..];
77 let result = token(CloneOnly { s: "x".to_string() }).easy_parse(input);
78 assert_eq!(
79 result,
80 Ok((
81 CloneOnly { s: "x".to_string() },
82 &[CloneOnly { s: "y".to_string() }][..]
83 ))
84 );
85 }
86
87 #[test]
sep_by_committed_error()88 fn sep_by_committed_error() {
89 type TwoLettersList = Vec<(char, char)>;
90
91 let mut parser2 = sep_by((letter(), letter()), token(','));
92 let result_err: Result<(TwoLettersList, &str), easy::ParseError<&str>> =
93 parser2.easy_parse("a,bc");
94 assert!(result_err.is_err());
95 }
96
97 /// The expected combinator should retain only errors that are not `Expected`
98 #[test]
expected_retain_errors()99 fn expected_retain_errors() {
100 let mut parser = digit()
101 .message("message")
102 .expected("N/A")
103 .expected("my expected digit");
104 assert_eq!(
105 parser.easy_parse(position::Stream::new("a")),
106 Err(Errors {
107 position: SourcePosition::default(),
108 errors: vec![
109 Error::Unexpected('a'.into()),
110 Error::Message("message".into()),
111 Error::Expected("my expected digit".into()),
112 ],
113 })
114 );
115 }
116
117 #[test]
tuple_parse_error()118 fn tuple_parse_error() {
119 let mut parser = (digit(), digit());
120 let result = parser.easy_parse(position::Stream::new("a"));
121 assert_eq!(
122 result,
123 Err(Errors {
124 position: SourcePosition::default(),
125 errors: vec![
126 Error::Unexpected('a'.into()),
127 Error::Expected("digit".into()),
128 ],
129 })
130 );
131 }
132
133 #[test]
message_tests()134 fn message_tests() {
135 // Ensure message adds to both committed and empty errors, interacting with parse_lazy and
136 // parse_stream correctly on either side
137 let input = "hi";
138
139 let mut ok = char('h').message("not expected");
140 let mut empty0 = char('o').message("expected message");
141 let mut empty1 = char('o').message("expected message").map(|x| x);
142 let mut empty2 = char('o').map(|x| x).message("expected message");
143 let mut committed0 = char('h').with(char('o')).message("expected message");
144 let mut committed1 = char('h')
145 .with(char('o'))
146 .message("expected message")
147 .map(|x| x);
148 let mut committed2 = char('h')
149 .with(char('o'))
150 .map(|x| x)
151 .message("expected message");
152
153 assert!(ok.easy_parse(position::Stream::new(input)).is_ok());
154
155 let empty_expected = Err(Errors {
156 position: SourcePosition { line: 1, column: 1 },
157 errors: vec![
158 Error::Unexpected('h'.into()),
159 Error::Expected('o'.into()),
160 Error::Message("expected message".into()),
161 ],
162 });
163
164 let committed_expected = Err(Errors {
165 position: SourcePosition { line: 1, column: 2 },
166 errors: vec![
167 Error::Unexpected('i'.into()),
168 Error::Expected('o'.into()),
169 Error::Message("expected message".into()),
170 ],
171 });
172
173 assert_eq!(
174 empty0.easy_parse(position::Stream::new(input)),
175 empty_expected
176 );
177 assert_eq!(
178 empty1.easy_parse(position::Stream::new(input)),
179 empty_expected
180 );
181 assert_eq!(
182 empty2.easy_parse(position::Stream::new(input)),
183 empty_expected
184 );
185
186 assert_eq!(
187 committed0.easy_parse(position::Stream::new(input)),
188 committed_expected
189 );
190 assert_eq!(
191 committed1.easy_parse(position::Stream::new(input)),
192 committed_expected
193 );
194 assert_eq!(
195 committed2.easy_parse(position::Stream::new(input)),
196 committed_expected
197 );
198 }
199
200 #[test]
expected_tests()201 fn expected_tests() {
202 // Ensure `expected` replaces only empty errors, interacting with parse_lazy and
203 // parse_stream correctly on either side
204 let input = "hi";
205
206 let mut ok = char('h').expected("not expected");
207 let mut empty0 = char('o').expected("expected message");
208 let mut empty1 = char('o').expected("expected message").map(|x| x);
209 let mut empty2 = char('o').map(|x| x).expected("expected message");
210 let mut committed0 = char('h').with(char('o')).expected("expected message");
211 let mut committed1 = char('h')
212 .with(char('o'))
213 .expected("expected message")
214 .map(|x| x);
215 let mut committed2 = char('h')
216 .with(char('o'))
217 .map(|x| x)
218 .expected("expected message");
219
220 assert!(ok.easy_parse(position::Stream::new(input)).is_ok());
221
222 let empty_expected = Err(Errors {
223 position: SourcePosition { line: 1, column: 1 },
224 errors: vec![
225 Error::Unexpected('h'.into()),
226 Error::Expected("expected message".into()),
227 ],
228 });
229
230 let committed_expected = Err(Errors {
231 position: SourcePosition { line: 1, column: 2 },
232 errors: vec![Error::Unexpected('i'.into()), Error::Expected('o'.into())],
233 });
234
235 assert_eq!(
236 empty0.easy_parse(position::Stream::new(input)),
237 empty_expected
238 );
239 assert_eq!(
240 empty1.easy_parse(position::Stream::new(input)),
241 empty_expected
242 );
243 assert_eq!(
244 empty2.easy_parse(position::Stream::new(input)),
245 empty_expected
246 );
247
248 assert_eq!(
249 committed0.easy_parse(position::Stream::new(input)),
250 committed_expected
251 );
252 assert_eq!(
253 committed1.easy_parse(position::Stream::new(input)),
254 committed_expected
255 );
256 assert_eq!(
257 committed2.easy_parse(position::Stream::new(input)),
258 committed_expected
259 );
260 }
261
262 #[test]
try_tests()263 fn try_tests() {
264 // Ensure attempt adds error messages exactly once
265 assert_eq!(
266 attempt(unexpected("test")).easy_parse(position::Stream::new("hi")),
267 Err(Errors {
268 position: SourcePosition { line: 1, column: 1 },
269 errors: vec![
270 Error::Unexpected('h'.into()),
271 Error::Unexpected("test".into()),
272 ],
273 })
274 );
275 assert_eq!(
276 attempt(char('h').with(unexpected("test"))).easy_parse(position::Stream::new("hi")),
277 Err(Errors {
278 position: SourcePosition { line: 1, column: 2 },
279 errors: vec![
280 Error::Unexpected('i'.into()),
281 Error::Unexpected("test".into()),
282 ],
283 })
284 );
285 }
286
287 #[test]
sequence_error()288 fn sequence_error() {
289 let mut parser = (char('a'), char('b'), char('c'));
290
291 assert_eq!(
292 parser.easy_parse(position::Stream::new("c")),
293 Err(Errors {
294 position: SourcePosition { line: 1, column: 1 },
295 errors: vec![Error::Unexpected('c'.into()), Error::Expected('a'.into())],
296 })
297 );
298
299 assert_eq!(
300 parser.easy_parse(position::Stream::new("ac")),
301 Err(Errors {
302 position: SourcePosition { line: 1, column: 2 },
303 errors: vec![Error::Unexpected('c'.into()), Error::Expected('b'.into())],
304 })
305 );
306 }
307
308 #[test]
optional_empty_ok_then_error()309 fn optional_empty_ok_then_error() {
310 let mut parser = (optional(char('a')), char('b'));
311
312 assert_eq!(
313 parser.easy_parse(position::Stream::new("c")),
314 Err(Errors {
315 position: SourcePosition { line: 1, column: 1 },
316 errors: vec![
317 Error::Unexpected('c'.into()),
318 Error::Expected('a'.into()),
319 Error::Expected('b'.into()),
320 ],
321 })
322 );
323 }
324
325 #[test]
nested_optional_empty_ok_then_error()326 fn nested_optional_empty_ok_then_error() {
327 let mut parser = ((optional(char('a')), char('b')), char('c'));
328
329 assert_eq!(
330 parser.easy_parse(position::Stream::new("c")),
331 Err(Errors {
332 position: SourcePosition { line: 1, column: 1 },
333 errors: vec![
334 Error::Unexpected('c'.into()),
335 Error::Expected('a'.into()),
336 Error::Expected('b'.into()),
337 ],
338 })
339 );
340 }
341
342 #[test]
committed_then_optional_empty_ok_then_error()343 fn committed_then_optional_empty_ok_then_error() {
344 let mut parser = (char('b'), optional(char('a')), char('b'));
345
346 assert_eq!(
347 parser.easy_parse(position::Stream::new("bc")),
348 Err(Errors {
349 position: SourcePosition { line: 1, column: 2 },
350 errors: vec![
351 Error::Unexpected('c'.into()),
352 Error::Expected('a'.into()),
353 Error::Expected('b'.into()),
354 ],
355 })
356 );
357 }
358
359 #[test]
sequence_in_choice_parser_empty_err()360 fn sequence_in_choice_parser_empty_err() {
361 let mut parser = choice((
362 (optional(char('a')), char('1')),
363 (optional(char('b')), char('2')).skip(char('d')),
364 ));
365
366 assert_eq!(
367 parser.easy_parse(position::Stream::new("c")),
368 Err(Errors {
369 position: SourcePosition { line: 1, column: 1 },
370 errors: vec![
371 Error::Expected('a'.into()),
372 Error::Expected('1'.into()),
373 Error::Expected('b'.into()),
374 Error::Expected('2'.into()),
375 Error::Unexpected('c'.into()),
376 ],
377 })
378 );
379 }
380
381 #[test]
sequence_in_choice_array_parser_empty_err()382 fn sequence_in_choice_array_parser_empty_err() {
383 let mut parser = choice([
384 (optional(char('a')), char('1')),
385 (optional(char('b')), char('2')),
386 ]);
387
388 assert_eq!(
389 parser.easy_parse(position::Stream::new("c")),
390 Err(Errors {
391 position: SourcePosition { line: 1, column: 1 },
392 errors: vec![
393 Error::Expected('a'.into()),
394 Error::Expected('1'.into()),
395 Error::Expected('b'.into()),
396 Error::Expected('2'.into()),
397 Error::Unexpected('c'.into()),
398 ],
399 })
400 );
401 }
402
403 #[test]
sequence_in_choice_array_parser_empty_err_where_first_parser_delay_errors()404 fn sequence_in_choice_array_parser_empty_err_where_first_parser_delay_errors() {
405 let mut p1 = char('1');
406 let mut p2 = no_partial((optional(char('b')), char('2')).map(|t| t.1));
407 let mut parser =
408 choice::<_, [&mut dyn Parser<_, Output = _, PartialState = _>; 2]>([&mut p1, &mut p2]);
409
410 assert_eq!(
411 parser.easy_parse(position::Stream::new("c")),
412 Err(Errors {
413 position: SourcePosition { line: 1, column: 1 },
414 errors: vec![
415 Error::Expected('1'.into()),
416 Error::Expected('b'.into()),
417 Error::Expected('2'.into()),
418 Error::Unexpected('c'.into()),
419 ],
420 })
421 );
422 }
423
424 #[test]
sep_end_by1_dont_eat_separator_twice()425 fn sep_end_by1_dont_eat_separator_twice() {
426 let mut parser = sep_end_by1(digit(), token(';'));
427 assert_eq!(parser.parse("1;;"), Ok((vec!['1'], ";")));
428 }
429
430 #[test]
count_min_max_empty_error()431 fn count_min_max_empty_error() {
432 assert_eq!(
433 count_min_max(1, 1, char('a')).or(value(vec![])).parse("b"),
434 Ok((vec![], "b"))
435 );
436 }
437
438 #[test]
sequence_parser_resets_partial_state_issue_168()439 fn sequence_parser_resets_partial_state_issue_168() {
440 assert_eq!(
441 take_until::<String, _, _>(attempt((char('a'), char('b')))).parse("aaab"),
442 Ok((String::from("aa"), "ab"))
443 );
444 }
445
446 #[test]
parser_macro_must_impl_parse_mode_issue_168()447 fn parser_macro_must_impl_parse_mode_issue_168() {
448 assert_eq!(
449 skip_until(attempt((char('a'), char('b')))).parse("aaab"),
450 Ok(((), "ab"))
451 );
452 }
453
454 #[test]
recognize_parser_issue_168()455 fn recognize_parser_issue_168() {
456 assert_eq!(
457 range::recognize(skip_until(attempt((char('a'), char('b'))))).parse("aaab"),
458 Ok(("aa", "ab"))
459 );
460 }
461
462 #[test]
sequence_in_optional_report_delayed_error()463 fn sequence_in_optional_report_delayed_error() {
464 assert_eq!(
465 optional(position().with(char('a')))
466 .skip(char('}'))
467 .easy_parse("b")
468 .map_err(|e| e.errors),
469 Err(vec![
470 Error::Unexpected('b'.into()),
471 Error::Expected('a'.into()),
472 Error::Expected('}'.into()),
473 ]),
474 );
475 }
476
477 #[test]
sequence_in_optional_nested_report_delayed_error()478 fn sequence_in_optional_nested_report_delayed_error() {
479 assert_eq!(
480 optional(position().with(char('a')))
481 .skip(optional(position().with(char('c'))))
482 .skip(char('}'))
483 .easy_parse("b")
484 .map_err(|e| e.errors),
485 Err(vec![
486 Error::Unexpected('b'.into()),
487 Error::Expected('a'.into()),
488 Error::Expected('c'.into()),
489 Error::Expected('}'.into()),
490 ]),
491 );
492 }
493
494 #[test]
sequence_in_optional_nested_2_report_delayed_error()495 fn sequence_in_optional_nested_2_report_delayed_error() {
496 assert_eq!(
497 (
498 char('{'),
499 optional(position().with(char('a')))
500 .skip(optional(position().with(char('c'))))
501 .skip(char('}'))
502 )
503 .easy_parse("{b")
504 .map_err(|e| e.errors),
505 Err(vec![
506 Error::Unexpected('b'.into()),
507 Error::Expected('a'.into()),
508 Error::Expected('c'.into()),
509 Error::Expected('}'.into()),
510 ]),
511 );
512 }
513
514 macro_rules! sequence_many_test {
515 ($many:expr, $seq:expr) => {
516 let mut parser = $seq($many(position().with(char('a'))), char('}'));
517 let expected_error = Err(vec![
518 Error::Unexpected('b'.into()),
519 Error::Expected('a'.into()),
520 Error::Expected('}'.into()),
521 ]);
522 assert_eq!(
523 parser.easy_parse("ab").map_err(|e| e.errors),
524 expected_error,
525 );
526 };
527 }
528
529 #[test]
sequence_in_many_report_delayed_error()530 fn sequence_in_many_report_delayed_error() {
531 use combine::parser::{repeat, sequence};
532
533 sequence_many_test!(repeat::many::<Vec<_>, _, _>, sequence::skip);
534 sequence_many_test!(repeat::many1::<Vec<_>, _, _>, sequence::skip);
535 sequence_many_test!(repeat::many::<Vec<_>, _, _>, sequence::with);
536 sequence_many_test!(repeat::many1::<Vec<_>, _, _>, sequence::with);
537 sequence_many_test!(repeat::many::<Vec<_>, _, _>, |l, x| sequence::between(
538 l,
539 char('|'),
540 x,
541 ));
542 sequence_many_test!(repeat::many1::<Vec<_>, _, _>, |l, x| sequence::between(
543 l,
544 char('|'),
545 x,
546 ));
547 }
548
549 macro_rules! sequence_sep_by_test {
550 ($many:expr, $seq:expr) => {
551 let mut parser = $seq($many(position().with(char('a')), char(',')), char('}'));
552 let expected_error = Err(vec![
553 Error::Unexpected('b'.into()),
554 Error::Expected(','.into()),
555 Error::Expected('}'.into()),
556 ]);
557 assert_eq!(
558 parser.easy_parse("a,ab").map_err(|e| e.errors),
559 expected_error,
560 );
561 };
562 }
563
564 #[test]
sequence_in_sep_by_report_delayed_error()565 fn sequence_in_sep_by_report_delayed_error() {
566 use combine::parser::{repeat, sequence};
567
568 sequence_sep_by_test!(repeat::sep_by::<Vec<_>, _, _, _>, sequence::skip);
569 sequence_sep_by_test!(repeat::sep_by1::<Vec<_>, _, _, _>, sequence::skip);
570 sequence_sep_by_test!(repeat::sep_by::<Vec<_>, _, _, _>, sequence::with);
571 sequence_sep_by_test!(repeat::sep_by1::<Vec<_>, _, _, _>, sequence::with);
572 }
573
574 #[test]
choice_compose_on_error()575 fn choice_compose_on_error() {
576 let ident = |s| attempt(string(s));
577 let mut parser = choice((ident("aa").skip(string(";")), choice((ident("cc"),))));
578
579 assert_eq!(
580 parser.easy_parse("c").map_err(|err| err.errors),
581 Err(vec![
582 Error::Unexpected('c'.into()),
583 Error::Expected("aa".into()),
584 Error::Unexpected("end of input".into()),
585 Error::Expected("cc".into()),
586 ]),
587 );
588 }
589
590 #[test]
choice_compose_issue_175()591 fn choice_compose_issue_175() {
592 let ident = |s| attempt(string(s));
593 let mut parser = many::<Vec<_>, _, _>(position().and(choice((
594 ident("aa").skip(string(";")),
595 choice((ident("bb"), ident("cc"))),
596 ))))
597 .skip(string("."));
598
599 assert_eq!(
600 parser.easy_parse("c").map_err(|err| err.errors),
601 Err(vec![
602 Error::Unexpected('c'.into()),
603 Error::Expected("aa".into()),
604 Error::Expected("bb".into()),
605 Error::Expected("cc".into()),
606 ]),
607 );
608 }
609
610 #[test]
test()611 fn test() {
612 let mut parser = (digit(), letter());
613
614 assert_eq!(
615 parser.easy_parse("11").map_err(|err| err.errors),
616 Err(vec![
617 Error::Unexpected('1'.into()),
618 Error::Expected("letter".into()),
619 ]),
620 );
621 }
622
623 #[test]
lifetime_inference()624 fn lifetime_inference() {
625 fn _string(source: &str) {
626 range::take(1).or(string("a")).parse(source).ok();
627 range::take(1)
628 .or(string_cmp("a", |x, y| x == y))
629 .parse(source)
630 .ok();
631 let _: &'static str = string("a").parse(source).unwrap().0;
632 let _: &'static str = string_cmp("a", |x, y| x == y).parse(source).unwrap().0;
633 }
634 fn _bytes(source: &[u8]) {
635 range::take(1).or(bytes(&[0u8])).parse(source).ok();
636 range::take(1)
637 .or(bytes_cmp(&[0u8], |x, y| x == y))
638 .parse(source)
639 .ok();
640 let _: &'static [u8] = bytes(&[0u8]).parse(source).unwrap().0;
641 let _: &'static [u8] = bytes_cmp(&[0u8], |x, y| x == y).parse(source).unwrap().0;
642 }
643 }
644
645 #[test]
test_nested_count_overflow()646 fn test_nested_count_overflow() {
647 let key = || count::<Vec<_>, _, _>(64, alpha_num());
648 let value_bytes =
649 || be_u32().then_partial(|&mut size| count::<Vec<_>, _, _>(size as usize, any()));
650 let value_messages =
651 (be_u32(), be_u32()).then_partial(|&mut (_body_size, message_count)| {
652 count::<Vec<_>, _, _>(message_count as usize, value_bytes())
653 });
654 let put = (bytes(b"PUT"), key())
655 .map(|(_, key)| key)
656 .and(value_messages);
657
658 let parser = || put.map(|(_, messages)| messages);
659
660 let command = &b"PUTkey\x00\x00\x00\x12\x00\x00\x00\x02\x00\x00\x00\x04\xDE\xAD\xBE\xEF\x00\x00\x00\x02\xBE\xEF"[..];
661 let result = parser().parse(command).unwrap();
662 assert_eq!(2, result.0.len());
663 }
664
665 #[test]
not_followed_by_empty_error_issue_220()666 fn not_followed_by_empty_error_issue_220() {
667 let mut parser = string("let").skip(not_followed_by(eof().map(|_| "EOF")));
668 assert_eq!(
669 parser.easy_parse("let").map_err(|err| err.errors),
670 Err(vec![]),
671 );
672 }
673 }
674