• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use super::*;
2 
3 #[cfg(feature = "std")]
4 use proptest::prelude::*;
5 
6 use crate::ascii::Caseless;
7 use crate::combinator::delimited;
8 use crate::error::ErrMode;
9 use crate::error::ErrorKind;
10 use crate::error::InputError;
11 use crate::error::Needed;
12 use crate::stream::AsChar;
13 use crate::token::literal;
14 use crate::unpeek;
15 use crate::IResult;
16 use crate::Parser;
17 use crate::Partial;
18 
19 macro_rules! assert_parse(
20   ($left: expr, $right: expr) => {
21     let res: $crate::IResult<_, _, InputError<_>> = $left;
22     assert_eq!(res, $right);
23   };
24 );
25 
26 #[test]
complete_take_while_m_n_utf8_all_matching()27 fn complete_take_while_m_n_utf8_all_matching() {
28     let result: IResult<&str, &str> =
29         take_while(1..=4, |c: char| c.is_alphabetic()).parse_peek("øn");
30     assert_eq!(result, Ok(("", "øn")));
31 }
32 
33 #[test]
complete_take_while_m_n_utf8_all_matching_substring()34 fn complete_take_while_m_n_utf8_all_matching_substring() {
35     let result: IResult<&str, &str> = take_while(1, |c: char| c.is_alphabetic()).parse_peek("øn");
36     assert_eq!(result, Ok(("n", "ø")));
37 }
38 
39 #[cfg(feature = "std")]
model_complete_take_while_m_n( m: usize, n: usize, valid: usize, input: &str, ) -> IResult<&str, &str>40 fn model_complete_take_while_m_n(
41     m: usize,
42     n: usize,
43     valid: usize,
44     input: &str,
45 ) -> IResult<&str, &str> {
46     if n < m {
47         Err(crate::error::ErrMode::from_error_kind(
48             &input,
49             crate::error::ErrorKind::Slice,
50         ))
51     } else if m <= valid {
52         let offset = n.min(valid);
53         Ok((&input[offset..], &input[0..offset]))
54     } else {
55         Err(crate::error::ErrMode::from_error_kind(
56             &input,
57             crate::error::ErrorKind::Slice,
58         ))
59     }
60 }
61 
62 #[cfg(feature = "std")]
63 proptest! {
64   #[test]
65   #[cfg_attr(miri, ignore)]  // See https://github.com/AltSysrq/proptest/issues/253
66   fn complete_take_while_m_n_bounds(m in 0..20usize, n in 0..20usize, valid in 0..20usize, invalid in 0..20usize) {
67       let input = format!("{:a<valid$}{:b<invalid$}", "", "", valid=valid, invalid=invalid);
68       let expected = model_complete_take_while_m_n(m, n, valid, &input);
69       if m <= n {
70           let actual = take_while(m..=n, |c: char| c == 'a').parse_peek(input.as_str());
71           assert_eq!(expected, actual);
72       }
73   }
74 }
75 
76 #[test]
complete_take_until()77 fn complete_take_until() {
78     fn take_until_5_10(i: &str) -> IResult<&str, &str> {
79         take_until(5..=8, "end").parse_peek(i)
80     }
81     assert_eq!(
82         take_until_5_10("end"),
83         Err(ErrMode::Backtrack(error_position!(
84             &"end",
85             ErrorKind::Slice
86         )))
87     );
88     assert_eq!(
89         take_until_5_10("1234end"),
90         Err(ErrMode::Backtrack(error_position!(
91             &"1234end",
92             ErrorKind::Slice
93         )))
94     );
95     assert_eq!(take_until_5_10("12345end"), Ok(("end", "12345")));
96     assert_eq!(take_until_5_10("123456end"), Ok(("end", "123456")));
97     assert_eq!(take_until_5_10("12345678end"), Ok(("end", "12345678")));
98     assert_eq!(
99         take_until_5_10("123456789end"),
100         Err(ErrMode::Backtrack(error_position!(
101             &"123456789end",
102             ErrorKind::Slice
103         )))
104     );
105 }
106 
107 #[test]
complete_take_until_empty()108 fn complete_take_until_empty() {
109     fn take_until_empty(i: &str) -> IResult<&str, &str> {
110         take_until(0, "").parse_peek(i)
111     }
112     assert_eq!(take_until_empty(""), Ok(("", "")));
113     assert_eq!(take_until_empty("end"), Ok(("end", "")));
114 }
115 
116 #[test]
complete_literal_case_insensitive()117 fn complete_literal_case_insensitive() {
118     fn caseless_bytes(i: &[u8]) -> IResult<&[u8], &[u8]> {
119         literal(Caseless("ABcd")).parse_peek(i)
120     }
121     assert_eq!(
122         caseless_bytes(&b"aBCdefgh"[..]),
123         Ok((&b"efgh"[..], &b"aBCd"[..]))
124     );
125     assert_eq!(
126         caseless_bytes(&b"abcdefgh"[..]),
127         Ok((&b"efgh"[..], &b"abcd"[..]))
128     );
129     assert_eq!(
130         caseless_bytes(&b"ABCDefgh"[..]),
131         Ok((&b"efgh"[..], &b"ABCD"[..]))
132     );
133     assert_eq!(
134         caseless_bytes(&b"ab"[..]),
135         Err(ErrMode::Backtrack(error_position!(
136             &&b"ab"[..],
137             ErrorKind::Tag
138         )))
139     );
140     assert_eq!(
141         caseless_bytes(&b"Hello"[..]),
142         Err(ErrMode::Backtrack(error_position!(
143             &&b"Hello"[..],
144             ErrorKind::Tag
145         )))
146     );
147     assert_eq!(
148         caseless_bytes(&b"Hel"[..]),
149         Err(ErrMode::Backtrack(error_position!(
150             &&b"Hel"[..],
151             ErrorKind::Tag
152         )))
153     );
154 
155     fn caseless_str(i: &str) -> IResult<&str, &str> {
156         literal(Caseless("ABcd")).parse_peek(i)
157     }
158     assert_eq!(caseless_str("aBCdefgh"), Ok(("efgh", "aBCd")));
159     assert_eq!(caseless_str("abcdefgh"), Ok(("efgh", "abcd")));
160     assert_eq!(caseless_str("ABCDefgh"), Ok(("efgh", "ABCD")));
161     assert_eq!(
162         caseless_str("ab"),
163         Err(ErrMode::Backtrack(error_position!(&"ab", ErrorKind::Tag)))
164     );
165     assert_eq!(
166         caseless_str("Hello"),
167         Err(ErrMode::Backtrack(error_position!(
168             &"Hello",
169             ErrorKind::Tag
170         )))
171     );
172     assert_eq!(
173         caseless_str("Hel"),
174         Err(ErrMode::Backtrack(error_position!(&"Hel", ErrorKind::Tag)))
175     );
176 
177     fn matches_kelvin(i: &str) -> IResult<&str, &str> {
178         literal(Caseless("k")).parse_peek(i)
179     }
180     assert_eq!(
181         matches_kelvin("K"),
182         Err(ErrMode::Backtrack(error_position!(&"K", ErrorKind::Tag)))
183     );
184 
185     fn is_kelvin(i: &str) -> IResult<&str, &str> {
186         literal(Caseless("K")).parse_peek(i)
187     }
188     assert_eq!(
189         is_kelvin("k"),
190         Err(ErrMode::Backtrack(error_position!(&"k", ErrorKind::Tag)))
191     );
192 }
193 
194 #[test]
complete_literal_fixed_size_array()195 fn complete_literal_fixed_size_array() {
196     fn test(i: &[u8]) -> IResult<&[u8], &[u8]> {
197         literal([0x42]).parse_peek(i)
198     }
199     fn test2(i: &[u8]) -> IResult<&[u8], &[u8]> {
200         literal(&[0x42]).parse_peek(i)
201     }
202 
203     let input = &[0x42, 0x00][..];
204     assert_eq!(test(input), Ok((&b"\x00"[..], &b"\x42"[..])));
205     assert_eq!(test2(input), Ok((&b"\x00"[..], &b"\x42"[..])));
206 }
207 
208 #[test]
complete_literal_char()209 fn complete_literal_char() {
210     fn test(i: &[u8]) -> IResult<&[u8], &[u8]> {
211         literal('B').parse_peek(i)
212     }
213     assert_eq!(test(&[0x42, 0x00][..]), Ok((&b"\x00"[..], &b"\x42"[..])));
214     assert_eq!(
215         test(&[b'A', b'\0'][..]),
216         Err(ErrMode::Backtrack(error_position!(
217             &&b"A\0"[..],
218             ErrorKind::Tag
219         )))
220     );
221 }
222 
223 #[test]
complete_literal_byte()224 fn complete_literal_byte() {
225     fn test(i: &[u8]) -> IResult<&[u8], &[u8]> {
226         literal(b'B').parse_peek(i)
227     }
228     assert_eq!(test(&[0x42, 0x00][..]), Ok((&b"\x00"[..], &b"\x42"[..])));
229     assert_eq!(
230         test(&[b'A', b'\0'][..]),
231         Err(ErrMode::Backtrack(error_position!(
232             &&b"A\0"[..],
233             ErrorKind::Tag
234         )))
235     );
236 }
237 
238 #[test]
partial_any_str()239 fn partial_any_str() {
240     use super::any;
241     assert_eq!(
242         any::<_, InputError<Partial<&str>>>.parse_peek(Partial::new("Ә")),
243         Ok((Partial::new(""), 'Ә'))
244     );
245 }
246 
247 #[test]
partial_one_of_test()248 fn partial_one_of_test() {
249     fn f(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u8> {
250         one_of(['a', 'b']).parse_peek(i)
251     }
252 
253     let a = &b"abcd"[..];
254     assert_eq!(f(Partial::new(a)), Ok((Partial::new(&b"bcd"[..]), b'a')));
255 
256     let b = &b"cde"[..];
257     assert_eq!(
258         f(Partial::new(b)),
259         Err(ErrMode::Backtrack(error_position!(
260             &Partial::new(b),
261             ErrorKind::Verify
262         )))
263     );
264 
265     fn utf8(i: Partial<&str>) -> IResult<Partial<&str>, char> {
266         one_of(['+', '\u{FF0B}']).parse_peek(i)
267     }
268 
269     assert!(utf8(Partial::new("+")).is_ok());
270     assert!(utf8(Partial::new("\u{FF0B}")).is_ok());
271 }
272 
273 #[test]
char_byteslice()274 fn char_byteslice() {
275     fn f(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, char> {
276         'c'.parse_peek(i)
277     }
278 
279     let a = &b"abcd"[..];
280     assert_eq!(
281         f(Partial::new(a)),
282         Err(ErrMode::Backtrack(error_position!(
283             &Partial::new(a),
284             ErrorKind::Tag
285         )))
286     );
287 
288     let b = &b"cde"[..];
289     assert_eq!(f(Partial::new(b)), Ok((Partial::new(&b"de"[..]), 'c')));
290 }
291 
292 #[test]
char_str()293 fn char_str() {
294     fn f(i: Partial<&str>) -> IResult<Partial<&str>, char> {
295         'c'.parse_peek(i)
296     }
297 
298     let a = "abcd";
299     assert_eq!(
300         f(Partial::new(a)),
301         Err(ErrMode::Backtrack(error_position!(
302             &Partial::new(a),
303             ErrorKind::Tag
304         )))
305     );
306 
307     let b = "cde";
308     assert_eq!(f(Partial::new(b)), Ok((Partial::new("de"), 'c')));
309 }
310 
311 #[test]
partial_none_of_test()312 fn partial_none_of_test() {
313     fn f(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u8> {
314         none_of(['a', 'b']).parse_peek(i)
315     }
316 
317     let a = &b"abcd"[..];
318     assert_eq!(
319         f(Partial::new(a)),
320         Err(ErrMode::Backtrack(error_position!(
321             &Partial::new(a),
322             ErrorKind::Verify
323         )))
324     );
325 
326     let b = &b"cde"[..];
327     assert_eq!(f(Partial::new(b)), Ok((Partial::new(&b"de"[..]), b'c')));
328 }
329 
330 #[test]
partial_is_a()331 fn partial_is_a() {
332     fn a_or_b(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
333         take_while(1.., ['a', 'b']).parse_peek(i)
334     }
335 
336     let a = Partial::new(&b"abcd"[..]);
337     assert_eq!(a_or_b(a), Ok((Partial::new(&b"cd"[..]), &b"ab"[..])));
338 
339     let b = Partial::new(&b"bcde"[..]);
340     assert_eq!(a_or_b(b), Ok((Partial::new(&b"cde"[..]), &b"b"[..])));
341 
342     let c = Partial::new(&b"cdef"[..]);
343     assert_eq!(
344         a_or_b(c),
345         Err(ErrMode::Backtrack(error_position!(&c, ErrorKind::Slice)))
346     );
347 
348     let d = Partial::new(&b"bacdef"[..]);
349     assert_eq!(a_or_b(d), Ok((Partial::new(&b"cdef"[..]), &b"ba"[..])));
350 }
351 
352 #[test]
partial_is_not()353 fn partial_is_not() {
354     fn a_or_b(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
355         take_till(1.., ['a', 'b']).parse_peek(i)
356     }
357 
358     let a = Partial::new(&b"cdab"[..]);
359     assert_eq!(a_or_b(a), Ok((Partial::new(&b"ab"[..]), &b"cd"[..])));
360 
361     let b = Partial::new(&b"cbde"[..]);
362     assert_eq!(a_or_b(b), Ok((Partial::new(&b"bde"[..]), &b"c"[..])));
363 
364     let c = Partial::new(&b"abab"[..]);
365     assert_eq!(
366         a_or_b(c),
367         Err(ErrMode::Backtrack(error_position!(&c, ErrorKind::Slice)))
368     );
369 
370     let d = Partial::new(&b"cdefba"[..]);
371     assert_eq!(a_or_b(d), Ok((Partial::new(&b"ba"[..]), &b"cdef"[..])));
372 
373     let e = Partial::new(&b"e"[..]);
374     assert_eq!(a_or_b(e), Err(ErrMode::Incomplete(Needed::new(1))));
375 }
376 
377 #[test]
partial_take_until_incomplete()378 fn partial_take_until_incomplete() {
379     fn y(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
380         take_until(0.., "end").parse_peek(i)
381     }
382     assert_eq!(
383         y(Partial::new(&b"nd"[..])),
384         Err(ErrMode::Incomplete(Needed::Unknown))
385     );
386     assert_eq!(
387         y(Partial::new(&b"123"[..])),
388         Err(ErrMode::Incomplete(Needed::Unknown))
389     );
390     assert_eq!(
391         y(Partial::new(&b"123en"[..])),
392         Err(ErrMode::Incomplete(Needed::Unknown))
393     );
394 }
395 
396 #[test]
partial_take_until_incomplete_s()397 fn partial_take_until_incomplete_s() {
398     fn ys(i: Partial<&str>) -> IResult<Partial<&str>, &str> {
399         take_until(0.., "end").parse_peek(i)
400     }
401     assert_eq!(
402         ys(Partial::new("123en")),
403         Err(ErrMode::Incomplete(Needed::Unknown))
404     );
405 }
406 
407 #[test]
partial_take()408 fn partial_take() {
409     use crate::ascii::{
410         alpha1 as alpha, alphanumeric1 as alphanumeric, digit1 as digit, hex_digit1 as hex_digit,
411         multispace1 as multispace, oct_digit1 as oct_digit, space1 as space,
412     };
413 
414     fn x(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
415         delimited("<!--", take(5_usize), "-->").take().parse_peek(i)
416     }
417     let r = x(Partial::new(&b"<!-- abc --> aaa"[..]));
418     assert_eq!(r, Ok((Partial::new(&b" aaa"[..]), &b"<!-- abc -->"[..])));
419 
420     let semicolon = &b";"[..];
421 
422     fn ya(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
423         alpha.take().parse_peek(i)
424     }
425     let ra = ya(Partial::new(&b"abc;"[..]));
426     assert_eq!(ra, Ok((Partial::new(semicolon), &b"abc"[..])));
427 
428     fn yd(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
429         digit.take().parse_peek(i)
430     }
431     let rd = yd(Partial::new(&b"123;"[..]));
432     assert_eq!(rd, Ok((Partial::new(semicolon), &b"123"[..])));
433 
434     fn yhd(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
435         hex_digit.take().parse_peek(i)
436     }
437     let rhd = yhd(Partial::new(&b"123abcDEF;"[..]));
438     assert_eq!(rhd, Ok((Partial::new(semicolon), &b"123abcDEF"[..])));
439 
440     fn yod(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
441         oct_digit.take().parse_peek(i)
442     }
443     let rod = yod(Partial::new(&b"1234567;"[..]));
444     assert_eq!(rod, Ok((Partial::new(semicolon), &b"1234567"[..])));
445 
446     fn yan(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
447         alphanumeric.take().parse_peek(i)
448     }
449     let ran = yan(Partial::new(&b"123abc;"[..]));
450     assert_eq!(ran, Ok((Partial::new(semicolon), &b"123abc"[..])));
451 
452     fn ys(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
453         space.take().parse_peek(i)
454     }
455     let rs = ys(Partial::new(&b" \t;"[..]));
456     assert_eq!(rs, Ok((Partial::new(semicolon), &b" \t"[..])));
457 
458     fn yms(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
459         multispace.take().parse_peek(i)
460     }
461     let rms = yms(Partial::new(&b" \t\r\n;"[..]));
462     assert_eq!(rms, Ok((Partial::new(semicolon), &b" \t\r\n"[..])));
463 }
464 
465 #[test]
partial_take_while0()466 fn partial_take_while0() {
467     fn f(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
468         take_while(0.., AsChar::is_alpha).parse_peek(i)
469     }
470     let a = &b""[..];
471     let b = &b"abcd"[..];
472     let c = &b"abcd123"[..];
473     let d = &b"123"[..];
474 
475     assert_eq!(f(Partial::new(a)), Err(ErrMode::Incomplete(Needed::new(1))));
476     assert_eq!(f(Partial::new(b)), Err(ErrMode::Incomplete(Needed::new(1))));
477     assert_eq!(f(Partial::new(c)), Ok((Partial::new(d), b)));
478     assert_eq!(f(Partial::new(d)), Ok((Partial::new(d), a)));
479 }
480 
481 #[test]
partial_take_while1()482 fn partial_take_while1() {
483     fn f(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
484         take_while(1.., AsChar::is_alpha).parse_peek(i)
485     }
486     let a = &b""[..];
487     let b = &b"abcd"[..];
488     let c = &b"abcd123"[..];
489     let d = &b"123"[..];
490 
491     assert_eq!(f(Partial::new(a)), Err(ErrMode::Incomplete(Needed::new(1))));
492     assert_eq!(f(Partial::new(b)), Err(ErrMode::Incomplete(Needed::new(1))));
493     assert_eq!(f(Partial::new(c)), Ok((Partial::new(&b"123"[..]), b)));
494     assert_eq!(
495         f(Partial::new(d)),
496         Err(ErrMode::Backtrack(error_position!(
497             &Partial::new(d),
498             ErrorKind::Slice
499         )))
500     );
501 }
502 
503 #[test]
partial_take_while_m_n()504 fn partial_take_while_m_n() {
505     fn x(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
506         take_while(2..=4, AsChar::is_alpha).parse_peek(i)
507     }
508     let a = &b""[..];
509     let b = &b"a"[..];
510     let c = &b"abc"[..];
511     let d = &b"abc123"[..];
512     let e = &b"abcde"[..];
513     let f = &b"123"[..];
514 
515     assert_eq!(x(Partial::new(a)), Err(ErrMode::Incomplete(Needed::new(2))));
516     assert_eq!(x(Partial::new(b)), Err(ErrMode::Incomplete(Needed::new(1))));
517     assert_eq!(x(Partial::new(c)), Err(ErrMode::Incomplete(Needed::new(1))));
518     assert_eq!(x(Partial::new(d)), Ok((Partial::new(&b"123"[..]), c)));
519     assert_eq!(
520         x(Partial::new(e)),
521         Ok((Partial::new(&b"e"[..]), &b"abcd"[..]))
522     );
523     assert_eq!(
524         x(Partial::new(f)),
525         Err(ErrMode::Backtrack(error_position!(
526             &Partial::new(f),
527             ErrorKind::Slice
528         )))
529     );
530 }
531 
532 #[test]
partial_take_till0()533 fn partial_take_till0() {
534     fn f(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
535         take_till(0.., AsChar::is_alpha).parse_peek(i)
536     }
537     let a = &b""[..];
538     let b = &b"abcd"[..];
539     let c = &b"123abcd"[..];
540     let d = &b"123"[..];
541 
542     assert_eq!(f(Partial::new(a)), Err(ErrMode::Incomplete(Needed::new(1))));
543     assert_eq!(
544         f(Partial::new(b)),
545         Ok((Partial::new(&b"abcd"[..]), &b""[..]))
546     );
547     assert_eq!(
548         f(Partial::new(c)),
549         Ok((Partial::new(&b"abcd"[..]), &b"123"[..]))
550     );
551     assert_eq!(f(Partial::new(d)), Err(ErrMode::Incomplete(Needed::new(1))));
552 }
553 
554 #[test]
partial_take_till1()555 fn partial_take_till1() {
556     fn f(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
557         take_till(1.., AsChar::is_alpha).parse_peek(i)
558     }
559     let a = &b""[..];
560     let b = &b"abcd"[..];
561     let c = &b"123abcd"[..];
562     let d = &b"123"[..];
563 
564     assert_eq!(f(Partial::new(a)), Err(ErrMode::Incomplete(Needed::new(1))));
565     assert_eq!(
566         f(Partial::new(b)),
567         Err(ErrMode::Backtrack(error_position!(
568             &Partial::new(b),
569             ErrorKind::Slice
570         )))
571     );
572     assert_eq!(
573         f(Partial::new(c)),
574         Ok((Partial::new(&b"abcd"[..]), &b"123"[..]))
575     );
576     assert_eq!(f(Partial::new(d)), Err(ErrMode::Incomplete(Needed::new(1))));
577 }
578 
579 #[test]
partial_take_while_utf8()580 fn partial_take_while_utf8() {
581     fn f(i: Partial<&str>) -> IResult<Partial<&str>, &str> {
582         take_while(0.., |c| c != '點').parse_peek(i)
583     }
584 
585     assert_eq!(
586         f(Partial::new("")),
587         Err(ErrMode::Incomplete(Needed::new(1)))
588     );
589     assert_eq!(
590         f(Partial::new("abcd")),
591         Err(ErrMode::Incomplete(Needed::new(1)))
592     );
593     assert_eq!(f(Partial::new("abcd點")), Ok((Partial::new("點"), "abcd")));
594     assert_eq!(
595         f(Partial::new("abcd點a")),
596         Ok((Partial::new("點a"), "abcd"))
597     );
598 
599     fn g(i: Partial<&str>) -> IResult<Partial<&str>, &str> {
600         take_while(0.., |c| c == '點').parse_peek(i)
601     }
602 
603     assert_eq!(
604         g(Partial::new("")),
605         Err(ErrMode::Incomplete(Needed::new(1)))
606     );
607     assert_eq!(g(Partial::new("點abcd")), Ok((Partial::new("abcd"), "點")));
608     assert_eq!(
609         g(Partial::new("點點點a")),
610         Ok((Partial::new("a"), "點點點"))
611     );
612 }
613 
614 #[test]
partial_take_till0_utf8()615 fn partial_take_till0_utf8() {
616     fn f(i: Partial<&str>) -> IResult<Partial<&str>, &str> {
617         take_till(0.., |c| c == '點').parse_peek(i)
618     }
619 
620     assert_eq!(
621         f(Partial::new("")),
622         Err(ErrMode::Incomplete(Needed::new(1)))
623     );
624     assert_eq!(
625         f(Partial::new("abcd")),
626         Err(ErrMode::Incomplete(Needed::new(1)))
627     );
628     assert_eq!(f(Partial::new("abcd點")), Ok((Partial::new("點"), "abcd")));
629     assert_eq!(
630         f(Partial::new("abcd點a")),
631         Ok((Partial::new("點a"), "abcd"))
632     );
633 
634     fn g(i: Partial<&str>) -> IResult<Partial<&str>, &str> {
635         take_till(0.., |c| c != '點').parse_peek(i)
636     }
637 
638     assert_eq!(
639         g(Partial::new("")),
640         Err(ErrMode::Incomplete(Needed::new(1)))
641     );
642     assert_eq!(g(Partial::new("點abcd")), Ok((Partial::new("abcd"), "點")));
643     assert_eq!(
644         g(Partial::new("點點點a")),
645         Ok((Partial::new("a"), "點點點"))
646     );
647 }
648 
649 #[test]
partial_take_utf8()650 fn partial_take_utf8() {
651     fn f(i: Partial<&str>) -> IResult<Partial<&str>, &str> {
652         take(3_usize).parse_peek(i)
653     }
654 
655     assert_eq!(
656         f(Partial::new("")),
657         Err(ErrMode::Incomplete(Needed::Unknown))
658     );
659     assert_eq!(
660         f(Partial::new("ab")),
661         Err(ErrMode::Incomplete(Needed::Unknown))
662     );
663     assert_eq!(
664         f(Partial::new("點")),
665         Err(ErrMode::Incomplete(Needed::Unknown))
666     );
667     assert_eq!(f(Partial::new("ab點cd")), Ok((Partial::new("cd"), "ab點")));
668     assert_eq!(f(Partial::new("a點bcd")), Ok((Partial::new("cd"), "a點b")));
669     assert_eq!(f(Partial::new("a點b")), Ok((Partial::new(""), "a點b")));
670 
671     fn g(i: Partial<&str>) -> IResult<Partial<&str>, &str> {
672         take_while(0.., |c| c == '點').parse_peek(i)
673     }
674 
675     assert_eq!(
676         g(Partial::new("")),
677         Err(ErrMode::Incomplete(Needed::new(1)))
678     );
679     assert_eq!(g(Partial::new("點abcd")), Ok((Partial::new("abcd"), "點")));
680     assert_eq!(
681         g(Partial::new("點點點a")),
682         Ok((Partial::new("a"), "點點點"))
683     );
684 }
685 
686 #[test]
partial_take_while_m_n_utf8_fixed()687 fn partial_take_while_m_n_utf8_fixed() {
688     fn parser(i: Partial<&str>) -> IResult<Partial<&str>, &str> {
689         take_while(1, |c| c == 'A' || c == '��').parse_peek(i)
690     }
691     assert_eq!(parser(Partial::new("A!")), Ok((Partial::new("!"), "A")));
692     assert_eq!(parser(Partial::new("��!")), Ok((Partial::new("!"), "��")));
693 }
694 
695 #[test]
partial_take_while_m_n_utf8_range()696 fn partial_take_while_m_n_utf8_range() {
697     fn parser(i: Partial<&str>) -> IResult<Partial<&str>, &str> {
698         take_while(1..=2, |c| c == 'A' || c == '��').parse_peek(i)
699     }
700     assert_eq!(parser(Partial::new("A!")), Ok((Partial::new("!"), "A")));
701     assert_eq!(parser(Partial::new("��!")), Ok((Partial::new("!"), "��")));
702 }
703 
704 #[test]
partial_take_while_m_n_utf8_full_match_fixed()705 fn partial_take_while_m_n_utf8_full_match_fixed() {
706     fn parser(i: Partial<&str>) -> IResult<Partial<&str>, &str> {
707         take_while(1, |c: char| c.is_alphabetic()).parse_peek(i)
708     }
709     assert_eq!(parser(Partial::new("øn")), Ok((Partial::new("n"), "ø")));
710 }
711 
712 #[test]
partial_take_while_m_n_utf8_full_match_range()713 fn partial_take_while_m_n_utf8_full_match_range() {
714     fn parser(i: Partial<&str>) -> IResult<Partial<&str>, &str> {
715         take_while(1..=2, |c: char| c.is_alphabetic()).parse_peek(i)
716     }
717     assert_eq!(parser(Partial::new("øn")), Ok((Partial::new(""), "øn")));
718 }
719 
720 #[test]
721 #[cfg(feature = "std")]
partial_take_take_while0()722 fn partial_take_take_while0() {
723     fn x(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
724         take_while(0.., AsChar::is_alphanum).parse_peek(i)
725     }
726     fn y(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
727         unpeek(x).take().parse_peek(i)
728     }
729     assert_eq!(
730         x(Partial::new(&b"ab."[..])),
731         Ok((Partial::new(&b"."[..]), &b"ab"[..]))
732     );
733     assert_eq!(
734         y(Partial::new(&b"ab."[..])),
735         Ok((Partial::new(&b"."[..]), &b"ab"[..]))
736     );
737 }
738 
739 #[test]
partial_literal_case_insensitive()740 fn partial_literal_case_insensitive() {
741     fn caseless_bytes(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
742         literal(Caseless("ABcd")).parse_peek(i)
743     }
744     assert_eq!(
745         caseless_bytes(Partial::new(&b"aBCdefgh"[..])),
746         Ok((Partial::new(&b"efgh"[..]), &b"aBCd"[..]))
747     );
748     assert_eq!(
749         caseless_bytes(Partial::new(&b"abcdefgh"[..])),
750         Ok((Partial::new(&b"efgh"[..]), &b"abcd"[..]))
751     );
752     assert_eq!(
753         caseless_bytes(Partial::new(&b"ABCDefgh"[..])),
754         Ok((Partial::new(&b"efgh"[..]), &b"ABCD"[..]))
755     );
756     assert_eq!(
757         caseless_bytes(Partial::new(&b"ab"[..])),
758         Err(ErrMode::Incomplete(Needed::new(2)))
759     );
760     assert_eq!(
761         caseless_bytes(Partial::new(&b"Hello"[..])),
762         Err(ErrMode::Backtrack(error_position!(
763             &Partial::new(&b"Hello"[..]),
764             ErrorKind::Tag
765         )))
766     );
767     assert_eq!(
768         caseless_bytes(Partial::new(&b"Hel"[..])),
769         Err(ErrMode::Backtrack(error_position!(
770             &Partial::new(&b"Hel"[..]),
771             ErrorKind::Tag
772         )))
773     );
774 
775     fn caseless_str(i: Partial<&str>) -> IResult<Partial<&str>, &str> {
776         literal(Caseless("ABcd")).parse_peek(i)
777     }
778     assert_eq!(
779         caseless_str(Partial::new("aBCdefgh")),
780         Ok((Partial::new("efgh"), "aBCd"))
781     );
782     assert_eq!(
783         caseless_str(Partial::new("abcdefgh")),
784         Ok((Partial::new("efgh"), "abcd"))
785     );
786     assert_eq!(
787         caseless_str(Partial::new("ABCDefgh")),
788         Ok((Partial::new("efgh"), "ABCD"))
789     );
790     assert_eq!(
791         caseless_str(Partial::new("ab")),
792         Err(ErrMode::Incomplete(Needed::new(2)))
793     );
794     assert_eq!(
795         caseless_str(Partial::new("Hello")),
796         Err(ErrMode::Backtrack(error_position!(
797             &Partial::new("Hello"),
798             ErrorKind::Tag
799         )))
800     );
801     assert_eq!(
802         caseless_str(Partial::new("Hel")),
803         Err(ErrMode::Backtrack(error_position!(
804             &Partial::new("Hel"),
805             ErrorKind::Tag
806         )))
807     );
808 
809     fn matches_kelvin(i: Partial<&str>) -> IResult<Partial<&str>, &str> {
810         literal(Caseless("k")).parse_peek(i)
811     }
812     assert_eq!(
813         matches_kelvin(Partial::new("K")),
814         Err(ErrMode::Backtrack(error_position!(
815             &Partial::new("K"),
816             ErrorKind::Tag
817         )))
818     );
819 
820     fn is_kelvin(i: Partial<&str>) -> IResult<Partial<&str>, &str> {
821         literal(Caseless("K")).parse_peek(i)
822     }
823     assert_eq!(
824         is_kelvin(Partial::new("k")),
825         Err(ErrMode::Backtrack(error_position!(
826             &Partial::new("k"),
827             ErrorKind::Tag
828         )))
829     );
830 }
831 
832 #[test]
partial_literal_fixed_size_array()833 fn partial_literal_fixed_size_array() {
834     fn test(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
835         literal([0x42]).parse_peek(i)
836     }
837     fn test2(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> {
838         literal(&[0x42]).parse_peek(i)
839     }
840     let input = Partial::new(&[0x42, 0x00][..]);
841     assert_eq!(test(input), Ok((Partial::new(&b"\x00"[..]), &b"\x42"[..])));
842     assert_eq!(test2(input), Ok((Partial::new(&b"\x00"[..]), &b"\x42"[..])));
843 }
844 
845 #[test]
rest_on_slices()846 fn rest_on_slices() {
847     let input: &[u8] = &b"Hello, world!"[..];
848     let empty: &[u8] = &b""[..];
849     assert_parse!(rest.parse_peek(input), Ok((empty, input)));
850 }
851 
852 #[test]
rest_on_strs()853 fn rest_on_strs() {
854     let input: &str = "Hello, world!";
855     let empty: &str = "";
856     assert_parse!(rest.parse_peek(input), Ok((empty, input)));
857 }
858 
859 #[test]
rest_len_on_slices()860 fn rest_len_on_slices() {
861     let input: &[u8] = &b"Hello, world!"[..];
862     assert_parse!(rest_len.parse_peek(input), Ok((input, input.len())));
863 }
864