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