1 //! Parsers and helper functions operating on strings, especially useful when writing parsers for
2 //! text-based formats.
3 
4 /// `tag_s!(&str) => &str -> IResult<&str, &str>`
5 /// declares a string as a suite to recognize
6 ///
7 /// consumes the recognized characters
8 ///
9 /// ```
10 /// # #[macro_use] extern crate nom;
11 /// # use nom::IResult;
12 /// # fn main() {
13 ///  fn test(input: &str) -> IResult<&str, &str> {
14 ///    tag_s!(input, "abcd")
15 ///  }
16 ///  let r = test("abcdefgh");
17 ///  assert_eq!(r,Ok(("efgh", "abcd")));
18 /// # }
19 /// ```
20 #[macro_export(local_inner_macros)]
21 #[deprecated(since = "4.0.0", note = "Please use `tag` instead")]
22 macro_rules! tag_s (
23   ($i:expr, $tag: expr) => (
24     {
25       tag!($i, $tag)
26     }
27   );
28 );
29 
30 /// `tag_no_case_s!(&str) => &str -> IResult<&str, &str>`
31 /// declares a case-insensitive string as a suite to recognize
32 ///
33 /// consumes the recognized characters
34 ///
35 /// ```
36 /// # #[macro_use] extern crate nom;
37 /// # use nom::IResult;
38 /// # use nom::InputLength;
39 /// #[cfg(feature = "alloc")]
40 /// # fn main() {
41 ///  fn test(input: &str) -> IResult<&str, &str> {
42 ///    tag_no_case_s!(input, "ABcd")
43 ///  }
44 ///  let r = test("aBCdefgh");
45 ///  assert_eq!(r,Ok(("efgh", "aBCd")));
46 /// # }
47 /// # #[cfg(not(feature = "alloc"))]
48 /// # fn main() {}
49 /// ```
50 #[macro_export(local_inner_macros)]
51 #[deprecated(since = "4.0.0", note = "Please use `tag_no_case` instead")]
52 macro_rules! tag_no_case_s (
53   ($i:expr, $tag: expr) => (
54     {
55       tag_no_case!($i, $tag)
56     }
57   );
58 );
59 
60 /// `take_s!(nb) => &str -> IResult<&str, &str>`
61 /// generates a parser consuming the specified number of characters
62 ///
63 /// ```
64 /// # #[macro_use] extern crate nom;
65 /// # fn main() {
66 ///  // Desmond parser
67 ///  named!(take5<&str,&str>, take_s!( 5 ) );
68 ///
69 ///  let a = "abcdefgh";
70 ///
71 ///  assert_eq!(take5(a),Ok(("fgh", "abcde")));
72 ///
73 ///  let b = "12345";
74 ///
75 ///  assert_eq!(take5(b),Ok(("", "12345")));
76 /// # }
77 /// ```
78 #[macro_export(local_inner_macros)]
79 #[deprecated(since = "4.0.0", note = "Please use `take` instead")]
80 macro_rules! take_s (
81   ($i:expr, $count:expr) => (
82     {
83       let input = $i;
84       let cnt = $count as usize;
85       take!(input, cnt)
86     }
87   );
88 );
89 
90 /// `is_not_s!(&str) => &str -> IResult<&str, &str>`
91 /// returns the longest list of characters that do not appear in the provided array
92 ///
93 /// ```
94 /// # #[macro_use] extern crate nom;
95 /// # fn main() {
96 ///  named!( not_space<&str,&str>, is_not_s!( " \t\r\n" ) );
97 ///
98 ///  let r = not_space("abcdefgh\nijkl");
99 ///  assert_eq!(r,Ok(("\nijkl", "abcdefgh")));
100 ///  # }
101 /// ```
102 #[macro_export(local_inner_macros)]
103 #[deprecated(since = "4.0.0", note = "Please use `is_not` instead")]
104 macro_rules! is_not_s (
105   ($input:expr, $arr:expr) => (
106     {
107       is_not!($input, $arr)
108     }
109   );
110 );
111 
112 /// `is_a_s!(&str) => &str -> IResult<&str, &str>`
113 /// returns the longest list of characters that appear in the provided array
114 ///
115 /// ```
116 /// # #[macro_use] extern crate nom;
117 /// # fn main() {
118 ///  named!(abcd<&str, &str>, is_a_s!( "abcd" ));
119 ///
120 ///  let r1 = abcd("aaaaefgh");
121 ///  assert_eq!(r1,Ok(("efgh", "aaaa")));
122 ///
123 ///  let r2 = abcd("dcbaefgh");
124 ///  assert_eq!(r2,Ok(("efgh", "dcba")));
125 /// # }
126 /// ```
127 #[macro_export(local_inner_macros)]
128 #[deprecated(since = "4.0.0", note = "Please use `is_a` instead")]
129 macro_rules! is_a_s (
130   ($input:expr, $arr:expr) => (
131     {
132       is_a!($input, $arr)
133     }
134   );
135 );
136 
137 /// `take_while_s!(char -> bool) => &str -> IResult<&str, &str>`
138 /// returns the longest list of characters until the provided function fails.
139 ///
140 /// The argument is either a function `char -> bool` or a macro returning a `bool
141 ///
142 /// ```
143 /// # #[macro_use] extern crate nom;
144 /// # fn main() {
145 ///  fn alphabetic(chr: char) -> bool { (chr >= 0x41 as char && chr <= 0x5A as char) || (chr >= 0x61 as char && chr <= 0x7A as char) }
146 ///  named!( alpha<&str,&str>, take_while_s!( alphabetic ) );
147 ///
148 ///  let r = alpha("abcd\nefgh");
149 ///  assert_eq!(r,Ok(("\nefgh", "abcd")));
150 /// # }
151 /// ```
152 #[macro_export(local_inner_macros)]
153 #[deprecated(since = "4.0.0", note = "Please use `take_while` instead")]
154 macro_rules! take_while_s (
155   ($input:expr, $submac:ident!( $($args:tt)* )) => (
156     {
157       take_while!($input, $submac!($($args)*))
158     }
159   );
160   ($input:expr, $f:expr) => (
161     take_while_s!($input, call!($f));
162   );
163 );
164 
165 /// `take_while1_s!(char -> bool) => &str -> IResult<&str, &str>`
166 /// returns the longest (non empty) list of characters until the provided function fails.
167 ///
168 /// The argument is either a function `char -> bool` or a macro returning a `bool`
169 ///
170 /// ```
171 /// # #[macro_use] extern crate nom;
172 /// # use nom::is_alphanumeric;
173 /// # fn main() {
174 ///  fn alphabetic(chr: char) -> bool { (chr >= 0x41 as char && chr <= 0x5A as char) || (chr >= 0x61 as char && chr <= 0x7A as char) }
175 ///  named!( alpha<&str,&str>, take_while1_s!( alphabetic ) );
176 ///
177 ///  let r = alpha("abcd\nefgh");
178 ///  assert_eq!(r, Ok(("\nefgh", "abcd")));
179 /// # }
180 /// ```
181 #[macro_export(local_inner_macros)]
182 #[deprecated(since = "4.0.0", note = "Please use `take_while1` instead")]
183 macro_rules! take_while1_s (
184   ($input:expr, $submac:ident!( $($args:tt)* )) => (
185     take_while1!($input, $submac!($($args)*))
186   );
187   ($input:expr, $f:expr) => (
188     take_while1_s!($input, call!($f));
189   );
190 );
191 
192 /// `take_till_s!(char -> bool) => &str -> IResult<&str, &str>`
193 /// returns the longest list of characters until the provided function succeeds
194 ///
195 /// The argument is either a function `char -> bool` or a macro returning a `bool
196 #[macro_export(local_inner_macros)]
197 #[deprecated(since = "4.0.0", note = "Please use `take_till` instead")]
198 macro_rules! take_till_s (
199   ($input:expr, $submac:ident!( $($args:tt)* )) => (
200     {
201       take_till!($input, $submac!($($args)*))
202     }
203   );
204   ($input:expr, $f:expr) => (
205     take_till_s!($input, call!($f));
206   );
207 );
208 
209 /// `take_till1_s!(char -> bool) => &str -> IResult<&str, &str>`
210 /// returns the longest non empty list of characters until the provided function succeeds
211 ///
212 /// The argument is either a function `char -> bool` or a macro returning a `bool
213 #[macro_export(local_inner_macros)]
214 #[deprecated(since = "4.0.0", note = "Please use `take_till1` instead")]
215 macro_rules! take_till1_s (
216   ($input:expr, $submac:ident!( $($args:tt)* )) => (
217     {
218       take_till1!($input, $submac!($($args)*))
219     }
220   );
221   ($input:expr, $f:expr) => (
222     take_till1_s!($input, call!($f));
223   );
224 );
225 
226 /// `take_until_and_consume_s!(&str) => &str -> IResult<&str, &str>`
227 /// generates a parser consuming all chars until the specified string is found and consumes it
228 #[macro_export(local_inner_macros)]
229 #[deprecated(since = "4.0.0", note = "Please use `take_until_and_consume` instead")]
230 macro_rules! take_until_and_consume_s (
231   ($input:expr, $substr:expr) => (
232     {
233       take_until_and_consume!($input, $substr)
234     }
235   );
236 );
237 
238 /// `take_until_s!(&str) => &str -> IResult<&str, &str>`
239 /// generates a parser consuming all chars until the specified string is found and leaves it in the remaining input
240 #[macro_export(local_inner_macros)]
241 #[deprecated(since = "4.0.0", note = "Please use `take_until` instead")]
242 macro_rules! take_until_s (
243   ($input:expr, $substr:expr) => (
244     {
245       take_until!($input, $substr)
246     }
247   );
248 );
249 
250 #[cfg(test)]
251 mod test {
252   use {Err, ErrorKind, IResult};
253 
254   #[test]
tag_str_succeed()255   fn tag_str_succeed() {
256     const INPUT: &str = "Hello World!";
257     const TAG: &str = "Hello";
258     fn test(input: &str) -> IResult<&str, &str> {
259       tag_s!(input, TAG)
260     }
261 
262     match test(INPUT) {
263       Ok((extra, output)) => {
264         assert!(
265           extra == " World!",
266           "Parser `tag_s` consumed leftover input."
267         );
268         assert!(
269           output == TAG,
270           "Parser `tag_s` doesn't return the tag it matched on success. \
271            Expected `{}`, got `{}`.",
272           TAG,
273           output
274         );
275       }
276       other => panic!(
277         "Parser `tag_s` didn't succeed when it should have. \
278          Got `{:?}`.",
279         other
280       ),
281     };
282   }
283 
284   #[test]
tag_str_incomplete()285   fn tag_str_incomplete() {
286     const INPUT: &str = "Hello";
287     const TAG: &str = "Hello World!";
288 
289     match tag_s!(INPUT, TAG) {
290       Err(Err::Incomplete(_)) => (),
291       other => {
292         panic!(
293           "Parser `tag_s` didn't require more input when it should have. \
294            Got `{:?}`.",
295           other
296         );
297       }
298     };
299   }
300 
301   #[test]
tag_str_error()302   fn tag_str_error() {
303     const INPUT: &str = "Hello World!";
304     const TAG: &str = "Random"; // TAG must be closer than INPUT.
305 
306     match tag_s!(INPUT, TAG) {
307       Err(Err::Error(_)) => (),
308       other => {
309         panic!(
310           "Parser `tag_s` didn't fail when it should have. Got `{:?}`.`",
311           other
312         );
313       }
314     };
315   }
316 
317   #[test]
take_s_succeed()318   fn take_s_succeed() {
319     const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
320     const CONSUMED: &str = "βèƒôřèÂßÇ";
321     const LEFTOVER: &str = "áƒƭèř";
322 
323     match take_s!(INPUT, 9) {
324       Ok((extra, output)) => {
325         assert!(
326           extra == LEFTOVER,
327           "Parser `take_s` consumed leftover input. Leftover `{}`.",
328           extra
329         );
330         assert!(
331           output == CONSUMED,
332           "Parser `take_s` doens't return the string it consumed on success. Expected `{}`, got `{}`.",
333           CONSUMED,
334           output
335         );
336       }
337       other => panic!(
338         "Parser `take_s` didn't succeed when it should have. \
339          Got `{:?}`.",
340         other
341       ),
342     };
343   }
344 
345   #[test]
take_until_s_succeed()346   fn take_until_s_succeed() {
347     const INPUT: &str = "βèƒôřèÂßÇ∂áƒƭèř";
348     const FIND: &str = "ÂßÇ∂";
349     const CONSUMED: &str = "βèƒôřè";
350     const LEFTOVER: &str = "ÂßÇ∂áƒƭèř";
351 
352     match take_until_s!(INPUT, FIND) {
353       Ok((extra, output)) => {
354         assert!(
355           extra == LEFTOVER,
356           "Parser `take_until_s`\
357            consumed leftover input. Leftover `{}`.",
358           extra
359         );
360         assert!(
361           output == CONSUMED,
362           "Parser `take_until_s`\
363            doens't return the string it consumed on success. Expected `{}`, got `{}`.",
364           CONSUMED,
365           output
366         );
367       }
368       other => panic!(
369         "Parser `take_until_s` didn't succeed when it should have. \
370          Got `{:?}`.",
371         other
372       ),
373     };
374   }
375 
376   #[test]
take_s_incomplete()377   fn take_s_incomplete() {
378     const INPUT: &str = "βèƒôřèÂßÇá";
379 
380     match take_s!(INPUT, 13) {
381       Err(Err::Incomplete(_)) => (),
382       other => panic!(
383         "Parser `take_s` didn't require more input when it should have. \
384          Got `{:?}`.",
385         other
386       ),
387     }
388   }
389 
390   use internal::Needed;
391 
is_alphabetic(c: char) -> bool392   pub fn is_alphabetic(c: char) -> bool {
393     (c as u8 >= 0x41 && c as u8 <= 0x5A) || (c as u8 >= 0x61 && c as u8 <= 0x7A)
394   }
395   #[test]
take_while_s()396   fn take_while_s() {
397     named!(f<&str,&str>, take_while_s!(is_alphabetic));
398     let a = "";
399     let b = "abcd";
400     let c = "abcd123";
401     let d = "123";
402 
403     assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::Size(1))));
404     assert_eq!(f(&b[..]), Err(Err::Incomplete(Needed::Size(1))));
405     assert_eq!(f(&c[..]), Ok((&d[..], &b[..])));
406     assert_eq!(f(&d[..]), Ok((&d[..], &a[..])));
407   }
408 
409   #[test]
take_while1_s()410   fn take_while1_s() {
411     named!(f<&str,&str>, take_while1_s!(is_alphabetic));
412     let a = "";
413     let b = "abcd";
414     let c = "abcd123";
415     let d = "123";
416 
417     assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::Size(1))));
418     assert_eq!(f(&b[..]), Err(Err::Incomplete(Needed::Size(1))));
419     assert_eq!(f(&c[..]), Ok((&"123"[..], &b[..])));
420     assert_eq!(
421       f(&d[..]),
422       Err(Err::Error(error_position!(&d[..], ErrorKind::TakeWhile1)))
423     );
424   }
425 
426   #[test]
take_till_s_succeed()427   fn take_till_s_succeed() {
428     const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
429     const CONSUMED: &str = "βèƒôřèÂßÇ";
430     const LEFTOVER: &str = "áƒƭèř";
431     fn till_s(c: char) -> bool {
432       c == 'á'
433     }
434     fn test(input: &str) -> IResult<&str, &str> {
435       take_till_s!(input, till_s)
436     }
437     match test(INPUT) {
438       Ok((extra, output)) => {
439         assert!(
440           extra == LEFTOVER,
441           "Parser `take_till_s` consumed leftover input."
442         );
443         assert!(
444           output == CONSUMED,
445           "Parser `take_till_s` doesn't return the string it consumed on success. \
446            Expected `{}`, got `{}`.",
447           CONSUMED,
448           output
449         );
450       }
451       other => panic!(
452         "Parser `take_till_s` didn't succeed when it should have. \
453          Got `{:?}`.",
454         other
455       ),
456     };
457   }
458 
459   #[test]
take_while_s_succeed_none()460   fn take_while_s_succeed_none() {
461     const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
462     const CONSUMED: &str = "";
463     const LEFTOVER: &str = "βèƒôřèÂßÇáƒƭèř";
464     fn while_s(c: char) -> bool {
465       c == '9'
466     }
467     fn test(input: &str) -> IResult<&str, &str> {
468       take_while_s!(input, while_s)
469     }
470     match test(INPUT) {
471       Ok((extra, output)) => {
472         assert!(
473           extra == LEFTOVER,
474           "Parser `take_while_s` consumed leftover input."
475         );
476         assert!(
477           output == CONSUMED,
478           "Parser `take_while_s` doesn't return the string it consumed on success. \
479            Expected `{}`, got `{}`.",
480           CONSUMED,
481           output
482         );
483       }
484       other => panic!(
485         "Parser `take_while_s` didn't succeed when it should have. \
486          Got `{:?}`.",
487         other
488       ),
489     };
490   }
491 
492   #[test]
is_not_s_succeed()493   fn is_not_s_succeed() {
494     const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
495     const AVOID: &str = "£úçƙ¥á";
496     const CONSUMED: &str = "βèƒôřèÂßÇ";
497     const LEFTOVER: &str = "áƒƭèř";
498     fn test(input: &str) -> IResult<&str, &str> {
499       is_not_s!(input, AVOID)
500     }
501     match test(INPUT) {
502       Ok((extra, output)) => {
503         assert!(
504           extra == LEFTOVER,
505           "Parser `is_not_s` consumed leftover input. Leftover `{}`.",
506           extra
507         );
508         assert!(
509           output == CONSUMED,
510           "Parser `is_not_s` doens't return the string it consumed on success. Expected `{}`, got `{}`.",
511           CONSUMED,
512           output
513         );
514       }
515       other => panic!(
516         "Parser `is_not_s` didn't succeed when it should have. \
517          Got `{:?}`.",
518         other
519       ),
520     };
521   }
522 
523   #[test]
take_until_and_consume_s_succeed()524   fn take_until_and_consume_s_succeed() {
525     const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
526     const FIND: &str = "ÂßÇ";
527     const OUTPUT: &str = "βèƒôřè";
528     const LEFTOVER: &str = "áƒƭèř";
529 
530     match take_until_and_consume_s!(INPUT, FIND) {
531       Ok((extra, output)) => {
532         assert!(
533           extra == LEFTOVER,
534           "Parser `take_until_and_consume_s`\
535            consumed leftover input. Leftover `{}`.",
536           extra
537         );
538         assert!(
539           output == OUTPUT,
540           "Parser `take_until_and_consume_s`\
541            doens't return the string it selected on success. Expected `{}`, got `{}`.",
542           OUTPUT,
543           output
544         );
545       }
546       other => panic!(
547         "Parser `take_until_and_consume_s` didn't succeed when it should have. \
548          Got `{:?}`.",
549         other
550       ),
551     };
552   }
553 
554   #[test]
take_while_s_succeed_some()555   fn take_while_s_succeed_some() {
556     const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
557     const CONSUMED: &str = "βèƒôřèÂßÇ";
558     const LEFTOVER: &str = "áƒƭèř";
559     fn while_s(c: char) -> bool {
560       c == 'β' || c == 'è' || c == 'ƒ' || c == 'ô' || c == 'ř' || c == 'è' || c == 'Â' || c == 'ß' || c == 'Ç'
561     }
562     fn test(input: &str) -> IResult<&str, &str> {
563       take_while_s!(input, while_s)
564     }
565     match test(INPUT) {
566       Ok((extra, output)) => {
567         assert!(
568           extra == LEFTOVER,
569           "Parser `take_while_s` consumed leftover input."
570         );
571         assert!(
572           output == CONSUMED,
573           "Parser `take_while_s` doesn't return the string it consumed on success. \
574            Expected `{}`, got `{}`.",
575           CONSUMED,
576           output
577         );
578       }
579       other => panic!(
580         "Parser `take_while_s` didn't succeed when it should have. \
581          Got `{:?}`.",
582         other
583       ),
584     };
585   }
586 
587   #[test]
is_not_s_fail()588   fn is_not_s_fail() {
589     const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
590     const AVOID: &str = "βúçƙ¥";
591     fn test(input: &str) -> IResult<&str, &str> {
592       is_not_s!(input, AVOID)
593     }
594     match test(INPUT) {
595       Err(Err::Error(_)) => (),
596       other => panic!(
597         "Parser `is_not_s` didn't fail when it should have. Got `{:?}`.",
598         other
599       ),
600     };
601   }
602 
603   #[test]
take_while1_s_succeed()604   fn take_while1_s_succeed() {
605     const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
606     const CONSUMED: &str = "βèƒôřèÂßÇ";
607     const LEFTOVER: &str = "áƒƭèř";
608     fn while1_s(c: char) -> bool {
609       c == 'β' || c == 'è' || c == 'ƒ' || c == 'ô' || c == 'ř' || c == 'è' || c == 'Â' || c == 'ß' || c == 'Ç'
610     }
611     fn test(input: &str) -> IResult<&str, &str> {
612       take_while1_s!(input, while1_s)
613     }
614     match test(INPUT) {
615       Ok((extra, output)) => {
616         assert!(
617           extra == LEFTOVER,
618           "Parser `take_while1_s` consumed leftover input."
619         );
620         assert!(
621           output == CONSUMED,
622           "Parser `take_while1_s` doesn't return the string it consumed on success. \
623            Expected `{}`, got `{}`.",
624           CONSUMED,
625           output
626         );
627       }
628       other => panic!(
629         "Parser `take_while1_s` didn't succeed when it should have. \
630          Got `{:?}`.",
631         other
632       ),
633     };
634   }
635 
636   #[test]
take_until_and_consume_s_incomplete()637   fn take_until_and_consume_s_incomplete() {
638     const INPUT: &str = "βèƒôřè";
639     const FIND: &str = "βèƒôřèÂßÇ";
640 
641     match take_until_and_consume_s!(INPUT, FIND) {
642       Err(Err::Incomplete(_)) => (),
643       other => panic!(
644         "Parser `take_until_and_consume_s` didn't require more input when it should have. \
645          Got `{:?}`.",
646         other
647       ),
648     };
649   }
650 
651   #[test]
take_until_s_incomplete()652   fn take_until_s_incomplete() {
653     const INPUT: &str = "βèƒôřè";
654     const FIND: &str = "βèƒôřèÂßÇ";
655 
656     match take_until_s!(INPUT, FIND) {
657       Err(Err::Incomplete(_)) => (),
658       other => panic!(
659         "Parser `take_until_s` didn't require more input when it should have. \
660          Got `{:?}`.",
661         other
662       ),
663     };
664   }
665 
666   #[test]
is_a_s_succeed()667   fn is_a_s_succeed() {
668     const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
669     const MATCH: &str = "βèƒôřèÂßÇ";
670     const CONSUMED: &str = "βèƒôřèÂßÇ";
671     const LEFTOVER: &str = "áƒƭèř";
672     fn test(input: &str) -> IResult<&str, &str> {
673       is_a_s!(input, MATCH)
674     }
675     match test(INPUT) {
676       Ok((extra, output)) => {
677         assert!(
678           extra == LEFTOVER,
679           "Parser `is_a_s` consumed leftover input. Leftover `{}`.",
680           extra
681         );
682         assert!(
683           output == CONSUMED,
684           "Parser `is_a_s` doens't return the string it consumed on success. Expected `{}`, got `{}`.",
685           CONSUMED,
686           output
687         );
688       }
689       other => panic!(
690         "Parser `is_a_s` didn't succeed when it should have. \
691          Got `{:?}`.",
692         other
693       ),
694     };
695   }
696 
697   #[test]
take_while1_s_fail()698   fn take_while1_s_fail() {
699     const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
700     fn while1_s(c: char) -> bool {
701       c == '9'
702     }
703     fn test(input: &str) -> IResult<&str, &str> {
704       take_while1_s!(input, while1_s)
705     }
706     match test(INPUT) {
707       Err(Err::Error(_)) => (),
708       other => panic!(
709         "Parser `take_while1_s` didn't fail when it should have. \
710          Got `{:?}`.",
711         other
712       ),
713     };
714   }
715 
716   #[test]
is_a_s_fail()717   fn is_a_s_fail() {
718     const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
719     const MATCH: &str = "Ûñℓúçƙ¥";
720     fn test(input: &str) -> IResult<&str, &str> {
721       is_a_s!(input, MATCH)
722     }
723     match test(INPUT) {
724       Err(Err::Error(_)) => (),
725       other => panic!(
726         "Parser `is_a_s` didn't fail when it should have. Got `{:?}`.",
727         other
728       ),
729     };
730   }
731 
732   #[test]
take_until_and_consume_s_error()733   fn take_until_and_consume_s_error() {
734     const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
735     const FIND: &str = "Ráñδô₥";
736 
737     match take_until_and_consume_s!(INPUT, FIND) {
738       Err(Err::Incomplete(_)) => (),
739       other => panic!(
740         "Parser `take_until_and_consume_s` didn't fail when it should have. \
741          Got `{:?}`.",
742         other
743       ),
744     };
745   }
746 
747   #[test]
take_until_s_error()748   fn take_until_s_error() {
749     const INPUT: &str = "βèƒôřèÂßÇáƒƭèř";
750     const FIND: &str = "Ráñδô₥";
751 
752     match take_until_s!(INPUT, FIND) {
753       Err(Err::Incomplete(_)) => (),
754       other => panic!(
755         "Parser `take_until_and_consume_s` didn't fail when it should have. \
756          Got `{:?}`.",
757         other
758       ),
759     };
760   }
761 
762   #[test]
763   #[cfg(feature = "alloc")]
recognize_is_a_s()764   fn recognize_is_a_s() {
765     let a = "aabbab";
766     let b = "ababcd";
767 
768     named!(f <&str,&str>, recognize!(many1!(complete!(alt!( tag_s!("a") | tag_s!("b") )))));
769 
770     assert_eq!(f(&a[..]), Ok((&a[6..], &a[..])));
771     assert_eq!(f(&b[..]), Ok((&b[4..], &b[..4])));
772   }
773 
774   #[test]
utf8_indexing()775   fn utf8_indexing() {
776     named!(dot(&str) -> &str,
777         tag_s!(".")
778       );
779 
780     let _ = dot("點");
781   }
782 
783   #[cfg(feature = "alloc")]
784   #[test]
case_insensitive()785   fn case_insensitive() {
786     named!(test<&str,&str>, tag_no_case!("ABcd"));
787     assert_eq!(test("aBCdefgh"), Ok(("efgh", "aBCd")));
788     assert_eq!(test("abcdefgh"), Ok(("efgh", "abcd")));
789     assert_eq!(test("ABCDefgh"), Ok(("efgh", "ABCD")));
790 
791     named!(test2<&str,&str>, tag_no_case!("ABcd"));
792     assert_eq!(test2("aBCdefgh"), Ok(("efgh", "aBCd")));
793     assert_eq!(test2("abcdefgh"), Ok(("efgh", "abcd")));
794     assert_eq!(test2("ABCDefgh"), Ok(("efgh", "ABCD")));
795   }
796 }
797