1 //! parsers recognizing bytes streams, complete input version
2 
3 use crate::error::ErrorKind;
4 use crate::error::ParseError;
5 use crate::internal::{Err, IResult};
6 use crate::lib::std::ops::RangeFrom;
7 use crate::lib::std::result::Result::*;
8 use crate::traits::{Compare, CompareResult, FindSubstring, FindToken, InputIter, InputLength, InputTake, InputTakeAtPosition, Slice, ToUsize};
9 
10 /// Recognizes a pattern
11 ///
12 /// The input data will be compared to the tag combinator's argument and will return the part of
13 /// the input that matches the argument
14 ///
15 /// It will return `Err(Err::Error((_, ErrorKind::Tag)))` if the input doesn't match the pattern
16 /// # Example
17 /// ```rust
18 /// # #[macro_use] extern crate nom;
19 /// # use nom::{Err, error::ErrorKind, Needed, IResult};
20 /// use nom::bytes::complete::tag;
21 ///
22 /// fn parser(s: &str) -> IResult<&str, &str> {
23 ///   tag("Hello")(s)
24 /// }
25 ///
26 /// assert_eq!(parser("Hello, World!"), Ok((", World!", "Hello")));
27 /// assert_eq!(parser("Something"), Err(Err::Error(("Something", ErrorKind::Tag))));
28 /// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
29 /// ```
tag<'a, T: 'a, Input: 'a, Error: ParseError<Input>>(tag: T) -> impl Fn(Input) -> IResult<Input, Input, Error> where Input: InputTake + Compare<T>, T: InputLength + Clone,30 pub fn tag<'a, T: 'a, Input: 'a, Error: ParseError<Input>>(tag: T) -> impl Fn(Input) -> IResult<Input, Input, Error>
31 where
32   Input: InputTake + Compare<T>,
33   T: InputLength + Clone,
34 {
35   move |i: Input| {
36     let tag_len = tag.input_len();
37     let t = tag.clone();
38     let res: IResult<_, _, Error> = match i.compare(t) {
39       CompareResult::Ok => Ok(i.take_split(tag_len)),
40       _ => {
41         let e: ErrorKind = ErrorKind::Tag;
42         Err(Err::Error(Error::from_error_kind(i, e)))
43       }
44     };
45     res
46   }
47 }
48 
49 /// Recognizes a case insensitive pattern
50 ///
51 /// The input data will be compared to the tag combinator's argument and will return the part of
52 /// the input that matches the argument with no regard to case
53 ///
54 /// It will return `Err(Err::Error((_, ErrorKind::Tag)))` if the input doesn't match the pattern
55 /// # Example
56 /// ```rust
57 /// # #[macro_use] extern crate nom;
58 /// # use nom::{Err, error::ErrorKind, Needed, IResult};
59 /// use nom::bytes::complete::tag_no_case;
60 ///
61 /// fn parser(s: &str) -> IResult<&str, &str> {
62 ///   tag_no_case("hello")(s)
63 /// }
64 ///
65 /// assert_eq!(parser("Hello, World!"), Ok((", World!", "Hello")));
66 /// assert_eq!(parser("hello, World!"), Ok((", World!", "hello")));
67 /// assert_eq!(parser("HeLlO, World!"), Ok((", World!", "HeLlO")));
68 /// assert_eq!(parser("Something"), Err(Err::Error(("Something", ErrorKind::Tag))));
69 /// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
70 /// ```
tag_no_case<T, Input, Error: ParseError<Input>>(tag: T) -> impl Fn(Input) -> IResult<Input, Input, Error> where Input: InputTake + Compare<T>, T: InputLength + Clone,71 pub fn tag_no_case<T, Input, Error: ParseError<Input>>(tag: T) -> impl Fn(Input) -> IResult<Input, Input, Error>
72 where
73   Input: InputTake + Compare<T>,
74   T: InputLength + Clone,
75 {
76   move |i: Input| {
77     let tag_len = tag.input_len();
78     let t = tag.clone();
79 
80     let res: IResult<_, _, Error> = match (i).compare_no_case(t) {
81       CompareResult::Ok => Ok(i.take_split(tag_len)),
82       _ => {
83         let e: ErrorKind = ErrorKind::Tag;
84         Err(Err::Error(Error::from_error_kind(i, e)))
85       }
86     };
87     res
88   }
89 }
90 
91 /// Parse till certain characters are met
92 ///
93 /// The parser will return the longest slice till one of the characters of the combinator's argument are met.
94 ///
95 /// It doesn't consume the matched character,
96 ///
97 /// It will return a `Err::Error(("", ErrorKind::IsNot))` if the pattern wasn't met
98 /// # Example
99 /// ```rust
100 /// # #[macro_use] extern crate nom;
101 /// # use nom::{Err, error::ErrorKind, Needed, IResult};
102 /// use nom::bytes::complete::is_not;
103 ///
104 /// fn not_space(s: &str) -> IResult<&str, &str> {
105 ///   is_not(" \t\r\n")(s)
106 /// }
107 ///
108 /// assert_eq!(not_space("Hello, World!"), Ok((" World!", "Hello,")));
109 /// assert_eq!(not_space("Sometimes\t"), Ok(("\t", "Sometimes")));
110 /// assert_eq!(not_space("Nospace"), Ok(("", "Nospace")));
111 /// assert_eq!(not_space(""), Err(Err::Error(("", ErrorKind::IsNot))));
112 /// ```
is_not<T, Input, Error: ParseError<Input>>(arr: T) -> impl Fn(Input) -> IResult<Input, Input, Error> where Input: InputTakeAtPosition, T: InputLength + FindToken<<Input as InputTakeAtPosition>::Item>,113 pub fn is_not<T, Input, Error: ParseError<Input>>(arr: T) -> impl Fn(Input) -> IResult<Input, Input, Error>
114 where
115   Input: InputTakeAtPosition,
116   T: InputLength + FindToken<<Input as InputTakeAtPosition>::Item>,
117 {
118   move |i: Input| {
119     let e: ErrorKind = ErrorKind::IsNot;
120     i.split_at_position1_complete(|c| arr.find_token(c), e)
121   }
122 }
123 
124 /// Returns the longest slice of the matches the pattern
125 ///
126 /// The parser will return the longest slice consisting of the characters in provided in the
127 /// combinator's argument
128 ///
129 /// It will return a `Err(Err::Error((_, ErrorKind::IsA)))` if the pattern wasn't met
130 ///
131 /// # Example
132 /// ```rust
133 /// # #[macro_use] extern crate nom;
134 /// # use nom::{Err, error::ErrorKind, Needed, IResult};
135 /// use nom::bytes::complete::is_a;
136 ///
137 /// fn hex(s: &str) -> IResult<&str, &str> {
138 ///   is_a("1234567890ABCDEF")(s)
139 /// }
140 ///
141 /// assert_eq!(hex("123 and voila"), Ok((" and voila", "123")));
142 /// assert_eq!(hex("DEADBEEF and others"), Ok((" and others", "DEADBEEF")));
143 /// assert_eq!(hex("BADBABEsomething"), Ok(("something", "BADBABE")));
144 /// assert_eq!(hex("D15EA5E"), Ok(("", "D15EA5E")));
145 /// assert_eq!(hex(""), Err(Err::Error(("", ErrorKind::IsA))));
146 /// ```
is_a<T, Input, Error: ParseError<Input>>(arr: T) -> impl Fn(Input) -> IResult<Input, Input, Error> where Input: InputTakeAtPosition, T: InputLength + FindToken<<Input as InputTakeAtPosition>::Item>,147 pub fn is_a<T, Input, Error: ParseError<Input>>(arr: T) -> impl Fn(Input) -> IResult<Input, Input, Error>
148 where
149   Input: InputTakeAtPosition,
150   T: InputLength + FindToken<<Input as InputTakeAtPosition>::Item>,
151 {
152   move |i: Input| {
153     let e: ErrorKind = ErrorKind::IsA;
154     i.split_at_position1_complete(|c| !arr.find_token(c), e)
155   }
156 }
157 
158 /// Returns the longest input slice (if any) that matches the predicate
159 ///
160 /// The parser will return the longest slice that matches the given predicate *(a function that
161 /// takes the input and returns a bool)*
162 ///
163 /// # Example
164 /// ```rust
165 /// # #[macro_use] extern crate nom;
166 /// # use nom::{Err, error::ErrorKind, Needed, IResult};
167 /// use nom::bytes::complete::take_while;
168 /// use nom::character::is_alphabetic;
169 ///
170 /// fn alpha(s: &[u8]) -> IResult<&[u8], &[u8]> {
171 ///   take_while(is_alphabetic)(s)
172 /// }
173 ///
174 /// assert_eq!(alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..])));
175 /// assert_eq!(alpha(b"12345"), Ok((&b"12345"[..], &b""[..])));
176 /// assert_eq!(alpha(b"latin"), Ok((&b""[..], &b"latin"[..])));
177 /// assert_eq!(alpha(b""), Ok((&b""[..], &b""[..])));
178 /// ```
take_while<F, Input, Error: ParseError<Input>>(cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error> where Input: InputTakeAtPosition, F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,179 pub fn take_while<F, Input, Error: ParseError<Input>>(cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error>
180 where
181   Input: InputTakeAtPosition,
182   F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
183 {
184   move |i: Input| i.split_at_position_complete(|c| !cond(c))
185 }
186 
187 /// Returns the longest (atleast 1) input slice that matches the predicate
188 ///
189 /// The parser will return the longest slice that matches the given predicate *(a function that
190 /// takes the input and returns a bool)*
191 ///
192 /// It will return an `Err(Err::Error((_, ErrorKind::TakeWhile1)))` if the pattern wasn't met
193 ///
194 /// # Example
195 /// ```rust
196 /// # #[macro_use] extern crate nom;
197 /// # use nom::{Err, error::ErrorKind, Needed, IResult};
198 /// use nom::bytes::complete::take_while1;
199 /// use nom::character::is_alphabetic;
200 ///
201 /// fn alpha(s: &[u8]) -> IResult<&[u8], &[u8]> {
202 ///   take_while1(is_alphabetic)(s)
203 /// }
204 ///
205 /// assert_eq!(alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..])));
206 /// assert_eq!(alpha(b"latin"), Ok((&b""[..], &b"latin"[..])));
207 /// assert_eq!(alpha(b"12345"), Err(Err::Error((&b"12345"[..], ErrorKind::TakeWhile1))));
208 /// ```
take_while1<F, Input, Error: ParseError<Input>>(cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error> where Input: InputTakeAtPosition, F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,209 pub fn take_while1<F, Input, Error: ParseError<Input>>(cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error>
210 where
211   Input: InputTakeAtPosition,
212   F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
213 {
214   move |i: Input| {
215     let e: ErrorKind = ErrorKind::TakeWhile1;
216     i.split_at_position1_complete(|c| !cond(c), e)
217   }
218 }
219 
220 /// Returns the longest (m <= len <= n) input slice  that matches the predicate
221 ///
222 /// The parser will return the longest slice that matches the given predicate *(a function that
223 /// takes the input and returns a bool)*
224 ///
225 /// It will return an `Err::Error((_, ErrorKind::TakeWhileMN))` if the pattern wasn't met or is out
226 /// of range (m <= len <= n)
227 ///
228 /// # Example
229 /// ```rust
230 /// # #[macro_use] extern crate nom;
231 /// # use nom::{Err, error::ErrorKind, Needed, IResult};
232 /// use nom::bytes::complete::take_while_m_n;
233 /// use nom::character::is_alphabetic;
234 ///
235 /// fn short_alpha(s: &[u8]) -> IResult<&[u8], &[u8]> {
236 ///   take_while_m_n(3, 6, is_alphabetic)(s)
237 /// }
238 ///
239 /// assert_eq!(short_alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..])));
240 /// assert_eq!(short_alpha(b"lengthy"), Ok((&b"y"[..], &b"length"[..])));
241 /// assert_eq!(short_alpha(b"latin"), Ok((&b""[..], &b"latin"[..])));
242 /// assert_eq!(short_alpha(b"ed"), Err(Err::Error((&b"ed"[..], ErrorKind::TakeWhileMN))));
243 /// assert_eq!(short_alpha(b"12345"), Err(Err::Error((&b"12345"[..], ErrorKind::TakeWhileMN))));
244 /// ```
take_while_m_n<F, Input, Error: ParseError<Input>>(m: usize, n: usize, cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error> where Input: InputTake + InputIter + InputLength + Slice<RangeFrom<usize>>, F: Fn(<Input as InputIter>::Item) -> bool,245 pub fn take_while_m_n<F, Input, Error: ParseError<Input>>(m: usize, n: usize, cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error>
246 where
247   Input: InputTake + InputIter + InputLength + Slice<RangeFrom<usize>>,
248   F: Fn(<Input as InputIter>::Item) -> bool,
249 {
250   move |i: Input| {
251     let input = i;
252 
253     match input.position(|c| !cond(c)) {
254       Some(idx) => {
255         if idx >= m {
256           if idx <= n {
257             let res: IResult<_, _, Error> = if let Some(index) = input.slice_index(idx) {
258               Ok(input.take_split(index))
259             } else {
260               Err(Err::Error(Error::from_error_kind(input, ErrorKind::TakeWhileMN)))
261             };
262             res
263           } else {
264             let res: IResult<_, _, Error> = if let Some(index) = input.slice_index(n) {
265               Ok(input.take_split(index))
266             } else {
267               Err(Err::Error(Error::from_error_kind(input, ErrorKind::TakeWhileMN)))
268             };
269             res
270           }
271         } else {
272           let e = ErrorKind::TakeWhileMN;
273           Err(Err::Error(Error::from_error_kind(input, e)))
274         }
275       }
276       None => {
277         let len = input.input_len();
278         if len >= n {
279           match input.slice_index(n) {
280             Some(index) => Ok(input.take_split(index)),
281             None => Err(Err::Error(Error::from_error_kind(input, ErrorKind::TakeWhileMN)))
282           }
283         } else {
284           if len >= m && len <= n {
285             let res: IResult<_, _, Error> = Ok((input.slice(len..), input));
286             res
287           } else {
288             let e = ErrorKind::TakeWhileMN;
289             Err(Err::Error(Error::from_error_kind(input, e)))
290           }
291         }
292       }
293     }
294   }
295 }
296 
297 /// Returns the longest input slice (if any) till a predicate is met
298 ///
299 /// The parser will return the longest slice till the given predicate *(a function that
300 /// takes the input and returns a bool)*
301 ///
302 /// # Example
303 /// ```rust
304 /// # #[macro_use] extern crate nom;
305 /// # use nom::{Err, error::ErrorKind, Needed, IResult};
306 /// use nom::bytes::complete::take_till;
307 ///
308 /// fn till_colon(s: &str) -> IResult<&str, &str> {
309 ///   take_till(|c| c == ':')(s)
310 /// }
311 ///
312 /// assert_eq!(till_colon("latin:123"), Ok((":123", "latin")));
313 /// assert_eq!(till_colon(":empty matched"), Ok((":empty matched", ""))); //allowed
314 /// assert_eq!(till_colon("12345"), Ok(("", "12345")));
315 /// assert_eq!(till_colon(""), Ok(("", "")));
316 /// ```
take_till<F, Input, Error: ParseError<Input>>(cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error> where Input: InputTakeAtPosition, F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,317 pub fn take_till<F, Input, Error: ParseError<Input>>(cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error>
318 where
319   Input: InputTakeAtPosition,
320   F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
321 {
322   move |i: Input| i.split_at_position_complete(|c| cond(c))
323 }
324 
325 /// Returns the longest (atleast 1) input slice till a predicate is met
326 ///
327 /// The parser will return the longest slice till the given predicate *(a function that
328 /// takes the input and returns a bool)*
329 ///
330 /// It will return `Err(Err::Error((_, ErrorKind::TakeTill1)))` if the input is empty or the
331 /// predicate matches the first input
332 ///
333 /// # Example
334 /// ```rust
335 /// # #[macro_use] extern crate nom;
336 /// # use nom::{Err, error::ErrorKind, Needed, IResult};
337 /// use nom::bytes::complete::take_till1;
338 ///
339 /// fn till_colon(s: &str) -> IResult<&str, &str> {
340 ///   take_till1(|c| c == ':')(s)
341 /// }
342 ///
343 /// assert_eq!(till_colon("latin:123"), Ok((":123", "latin")));
344 /// assert_eq!(till_colon(":empty matched"), Err(Err::Error((":empty matched", ErrorKind::TakeTill1))));
345 /// assert_eq!(till_colon("12345"), Ok(("", "12345")));
346 /// assert_eq!(till_colon(""), Err(Err::Error(("", ErrorKind::TakeTill1))));
347 /// ```
take_till1<F, Input, Error: ParseError<Input>>(cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error> where Input: InputTakeAtPosition, F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,348 pub fn take_till1<F, Input, Error: ParseError<Input>>(cond: F) -> impl Fn(Input) -> IResult<Input, Input, Error>
349 where
350   Input: InputTakeAtPosition,
351   F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
352 {
353   move |i: Input| {
354     let e: ErrorKind = ErrorKind::TakeTill1;
355     i.split_at_position1_complete(|c| cond(c), e)
356   }
357 }
358 
359 /// Returns an input slice containing the first N input elements (Input[..N])
360 ///
361 /// It will return `Err(Err::Error((_, ErrorKind::Eof)))` if the input is shorter than the argument
362 ///
363 /// # Example
364 /// ```rust
365 /// # #[macro_use] extern crate nom;
366 /// # use nom::{Err, error::ErrorKind, Needed, IResult};
367 /// use nom::bytes::complete::take;
368 ///
369 /// fn take6(s: &str) -> IResult<&str, &str> {
370 ///   take(6usize)(s)
371 /// }
372 ///
373 /// assert_eq!(take6("1234567"), Ok(("7", "123456")));
374 /// assert_eq!(take6("things"), Ok(("", "things")));
375 /// assert_eq!(take6("short"), Err(Err::Error(("short", ErrorKind::Eof))));
376 /// assert_eq!(take6(""), Err(Err::Error(("", ErrorKind::Eof))));
377 /// ```
take<C, Input, Error: ParseError<Input>>(count: C) -> impl Fn(Input) -> IResult<Input, Input, Error> where Input: InputIter + InputTake, C: ToUsize,378 pub fn take<C, Input, Error: ParseError<Input>>(count: C) -> impl Fn(Input) -> IResult<Input, Input, Error>
379 where
380   Input: InputIter + InputTake,
381   C: ToUsize,
382 {
383   let c = count.to_usize();
384   move |i: Input| match i.slice_index(c) {
385     None => Err(Err::Error(Error::from_error_kind(i, ErrorKind::Eof))),
386     Some(index) => Ok(i.take_split(index)),
387   }
388 }
389 
390 /// Returns the longest input slice till it matches the pattern.
391 ///
392 /// It doesn't consume the pattern. It will return `Err(Err::Error((_, ErrorKind::TakeUntil)))`
393 /// if the pattern wasn't met
394 ///
395 /// # Example
396 /// ```rust
397 /// # #[macro_use] extern crate nom;
398 /// # use nom::{Err, error::ErrorKind, Needed, IResult};
399 /// use nom::bytes::complete::take_until;
400 ///
401 /// fn until_eof(s: &str) -> IResult<&str, &str> {
402 ///   take_until("eof")(s)
403 /// }
404 ///
405 /// assert_eq!(until_eof("hello, worldeof"), Ok(("eof", "hello, world")));
406 /// assert_eq!(until_eof("hello, world"), Err(Err::Error(("hello, world", ErrorKind::TakeUntil))));
407 /// assert_eq!(until_eof(""), Err(Err::Error(("", ErrorKind::TakeUntil))));
408 /// ```
take_until<T, Input, Error: ParseError<Input>>(tag: T) -> impl Fn(Input) -> IResult<Input, Input, Error> where Input: InputTake + FindSubstring<T>, T: InputLength + Clone,409 pub fn take_until<T, Input, Error: ParseError<Input>>(tag: T) -> impl Fn(Input) -> IResult<Input, Input, Error>
410 where
411   Input: InputTake + FindSubstring<T>,
412   T: InputLength + Clone,
413 {
414   move |i: Input| {
415     let t = tag.clone();
416     let res: IResult<_, _, Error> = match i.find_substring(t) {
417       None => Err(Err::Error(Error::from_error_kind(i, ErrorKind::TakeUntil))),
418       Some(index) => Ok(i.take_split(index)),
419     };
420     res
421   }
422 }
423 
424 /// Matches a byte string with escaped characters.
425 ///
426 /// * The first argument matches the normal characters (it must not accept the control character),
427 /// * the second argument is the control character (like `\` in most languages),
428 /// * the third argument matches the escaped characters
429 ///
430 /// # Example
431 /// ```
432 /// # #[macro_use] extern crate nom;
433 /// # use nom::{Err, error::ErrorKind, Needed, IResult};
434 /// # use nom::character::complete::digit1;
435 /// use nom::bytes::complete::escaped;
436 /// use nom::character::complete::one_of;
437 ///
438 /// fn esc(s: &str) -> IResult<&str, &str> {
439 ///   escaped(digit1, '\\', one_of(r#""n\"#))(s)
440 /// }
441 ///
442 /// assert_eq!(esc("123;"), Ok((";", "123")));
443 /// assert_eq!(esc(r#"12\"34;"#), Ok((";", r#"12\"34"#)));
444 /// ```
445 ///
escaped<Input, Error, F, G, O1, O2>(normal: F, control_char: char, escapable: G) -> impl Fn(Input) -> IResult<Input, Input, Error> where Input: Clone + crate::traits::Offset + InputLength + InputTake + InputTakeAtPosition + Slice<RangeFrom<usize>> + InputIter, <Input as InputIter>::Item: crate::traits::AsChar, F: Fn(Input) -> IResult<Input, O1, Error>, G: Fn(Input) -> IResult<Input, O2, Error>, Error: ParseError<Input>,446 pub fn escaped<Input, Error, F, G, O1, O2>(normal: F, control_char: char, escapable: G) -> impl Fn(Input) -> IResult<Input, Input, Error>
447 where
448   Input: Clone + crate::traits::Offset + InputLength + InputTake + InputTakeAtPosition + Slice<RangeFrom<usize>> + InputIter,
449   <Input as InputIter>::Item: crate::traits::AsChar,
450   F: Fn(Input) -> IResult<Input, O1, Error>,
451   G: Fn(Input) -> IResult<Input, O2, Error>,
452   Error: ParseError<Input>,
453 {
454   use crate::traits::AsChar;
455 
456   move |input: Input| {
457     let mut i = input.clone();
458 
459     while i.input_len() > 0 {
460       match normal(i.clone()) {
461         Ok((i2, _)) => {
462           if i2.input_len() == 0 {
463             return Ok((input.slice(input.input_len()..), input));
464           } else {
465             i = i2;
466           }
467         }
468         Err(Err::Error(_)) => {
469           // unwrap() should be safe here since index < $i.input_len()
470           if i.iter_elements().next().unwrap().as_char() == control_char {
471             let next = control_char.len_utf8();
472             if next >= i.input_len() {
473               return Err(Err::Error(Error::from_error_kind(input, ErrorKind::Escaped)));
474             } else {
475               match escapable(i.slice(next..)) {
476                 Ok((i2, _)) => {
477                   if i2.input_len() == 0 {
478                     return Ok((input.slice(input.input_len()..), input));
479                   } else {
480                     i = i2;
481                   }
482                 }
483                 Err(e) => return Err(e),
484               }
485             }
486           } else {
487             let index = input.offset(&i);
488             if index == 0 {
489               return Err(Err::Error(Error::from_error_kind(input, ErrorKind::Escaped)));
490             }
491             return Ok(input.take_split(index));
492           }
493         }
494         Err(e) => {
495           return Err(e);
496         }
497       }
498     }
499 
500     Ok((input.slice(input.input_len()..), input))
501   }
502 }
503 
504 #[doc(hidden)]
escapedc<Input, Error, F, G, O1, O2>(i: Input, normal: F, control_char: char, escapable: G) -> IResult<Input, Input, Error> where Input: Clone + crate::traits::Offset + InputLength + InputTake + InputTakeAtPosition + Slice<RangeFrom<usize>> + InputIter, <Input as InputIter>::Item: crate::traits::AsChar, F: Fn(Input) -> IResult<Input, O1, Error>, G: Fn(Input) -> IResult<Input, O2, Error>, Error: ParseError<Input>,505 pub fn escapedc<Input, Error, F, G, O1, O2>(i: Input, normal: F, control_char: char, escapable: G) -> IResult<Input, Input, Error>
506 where
507   Input: Clone + crate::traits::Offset + InputLength + InputTake + InputTakeAtPosition + Slice<RangeFrom<usize>> + InputIter,
508   <Input as InputIter>::Item: crate::traits::AsChar,
509   F: Fn(Input) -> IResult<Input, O1, Error>,
510   G: Fn(Input) -> IResult<Input, O2, Error>,
511   Error: ParseError<Input>,
512 {
513   escaped(normal, control_char, escapable)(i)
514 }
515 
516 /// Matches a byte string with escaped characters.
517 ///
518 /// * The first argument matches the normal characters (it must not match the control character),
519 /// * the second argument is the control character (like `\` in most languages),
520 /// * the third argument matches the escaped characters and transforms them.
521 ///
522 /// As an example, the chain `abc\tdef` could be `abc    def` (it also consumes the control character)
523 ///
524 /// ```
525 /// # #[macro_use] extern crate nom;
526 /// # use nom::{Err, error::ErrorKind, Needed, IResult};
527 /// # use std::str::from_utf8;
528 /// use nom::bytes::complete::escaped_transform;
529 /// use nom::character::complete::alpha1;
530 ///
531 /// fn parser(input: &str) -> IResult<&str, String> {
532 ///   escaped_transform(
533 ///     alpha1,
534 ///     '\\',
535 ///     |i:&str| alt!(i,
536 ///         tag!("\\")       => { |_| "\\" }
537 ///       | tag!("\"")       => { |_| "\"" }
538 ///       | tag!("n")        => { |_| "\n" }
539 ///     )
540 ///   )(input)
541 /// }
542 ///
543 /// assert_eq!(parser("ab\\\"cd"), Ok(("", String::from("ab\"cd"))));
544 /// ```
545 #[cfg(feature = "alloc")]
escaped_transform<Input, Error, F, G, O1, O2, ExtendItem, Output>( normal: F, control_char: char, transform: G, ) -> impl Fn(Input) -> IResult<Input, Output, Error> where Input: Clone + crate::traits::Offset + InputLength + InputTake + InputTakeAtPosition + Slice<RangeFrom<usize>> + InputIter, Input: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>, O1: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>, O2: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>, Output: core::iter::Extend<<Input as crate::traits::ExtendInto>::Item>, Output: core::iter::Extend<<O1 as crate::traits::ExtendInto>::Item>, Output: core::iter::Extend<<O2 as crate::traits::ExtendInto>::Item>, <Input as InputIter>::Item: crate::traits::AsChar, F: Fn(Input) -> IResult<Input, O1, Error>, G: Fn(Input) -> IResult<Input, O2, Error>, Error: ParseError<Input>,546 pub fn escaped_transform<Input, Error, F, G, O1, O2, ExtendItem, Output>(
547   normal: F,
548   control_char: char,
549   transform: G,
550 ) -> impl Fn(Input) -> IResult<Input, Output, Error>
551 where
552   Input: Clone + crate::traits::Offset + InputLength + InputTake + InputTakeAtPosition + Slice<RangeFrom<usize>> + InputIter,
553   Input: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
554   O1: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
555   O2: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
556   Output: core::iter::Extend<<Input as crate::traits::ExtendInto>::Item>,
557   Output: core::iter::Extend<<O1 as crate::traits::ExtendInto>::Item>,
558   Output: core::iter::Extend<<O2 as crate::traits::ExtendInto>::Item>,
559   <Input as InputIter>::Item: crate::traits::AsChar,
560   F: Fn(Input) -> IResult<Input, O1, Error>,
561   G: Fn(Input) -> IResult<Input, O2, Error>,
562   Error: ParseError<Input>,
563 {
564   use crate::traits::AsChar;
565 
566   move |input: Input| {
567     let mut index = 0;
568     let mut res = input.new_builder();
569 
570     let i = input.clone();
571 
572     while index < i.input_len() {
573       let remainder = i.slice(index..);
574       match normal(remainder.clone()) {
575         Ok((i2, o)) => {
576           o.extend_into(&mut res);
577           if i2.input_len() == 0 {
578             return Ok((i.slice(i.input_len()..), res));
579           } else {
580             index = input.offset(&i2);
581           }
582         }
583         Err(Err::Error(_)) => {
584           // unwrap() should be safe here since index < $i.input_len()
585           if remainder.iter_elements().next().unwrap().as_char() == control_char {
586             let next = index + control_char.len_utf8();
587             let input_len = input.input_len();
588 
589             if next >= input_len {
590               return Err(Err::Error(Error::from_error_kind(remainder, ErrorKind::EscapedTransform)));
591             } else {
592               match transform(i.slice(next..)) {
593                 Ok((i2, o)) => {
594                   o.extend_into(&mut res);
595                   if i2.input_len() == 0 {
596                     return Ok((i.slice(i.input_len()..), res));
597                   } else {
598                     index = input.offset(&i2);
599                   }
600                 }
601                 Err(e) => return Err(e),
602               }
603             }
604           } else {
605             if index == 0 {
606               return Err(Err::Error(Error::from_error_kind(remainder, ErrorKind::EscapedTransform)));
607             }
608             return Ok((remainder, res));
609           }
610         }
611         Err(e) => return Err(e),
612       }
613     }
614     Ok((input.slice(index..), res))
615   }
616 }
617 
618 #[doc(hidden)]
619 #[cfg(feature = "alloc")]
escaped_transformc<Input, Error, F, G, O1, O2, ExtendItem, Output>( i: Input, normal: F, control_char: char, transform: G, ) -> IResult<Input, Output, Error> where Input: Clone + crate::traits::Offset + InputLength + InputTake + InputTakeAtPosition + Slice<RangeFrom<usize>> + InputIter, Input: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>, O1: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>, O2: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>, Output: core::iter::Extend<<Input as crate::traits::ExtendInto>::Item>, Output: core::iter::Extend<<O1 as crate::traits::ExtendInto>::Item>, Output: core::iter::Extend<<O2 as crate::traits::ExtendInto>::Item>, <Input as InputIter>::Item: crate::traits::AsChar, F: Fn(Input) -> IResult<Input, O1, Error>, G: Fn(Input) -> IResult<Input, O2, Error>, Error: ParseError<Input>,620 pub fn escaped_transformc<Input, Error, F, G, O1, O2, ExtendItem, Output>(
621   i: Input,
622   normal: F,
623   control_char: char,
624   transform: G,
625 ) -> IResult<Input, Output, Error>
626 where
627   Input: Clone + crate::traits::Offset + InputLength + InputTake + InputTakeAtPosition + Slice<RangeFrom<usize>> + InputIter,
628   Input: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
629   O1: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
630   O2: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
631   Output: core::iter::Extend<<Input as crate::traits::ExtendInto>::Item>,
632   Output: core::iter::Extend<<O1 as crate::traits::ExtendInto>::Item>,
633   Output: core::iter::Extend<<O2 as crate::traits::ExtendInto>::Item>,
634   <Input as InputIter>::Item: crate::traits::AsChar,
635   F: Fn(Input) -> IResult<Input, O1, Error>,
636   G: Fn(Input) -> IResult<Input, O2, Error>,
637   Error: ParseError<Input>,
638 {
639   escaped_transform(normal, control_char, transform)(i)
640 
641 }
642 
643 #[cfg(test)]
644 mod tests {
645   use super::*;
646 
647   #[test]
complete_take_while_m_n_utf8_all_matching()648   fn complete_take_while_m_n_utf8_all_matching() {
649     let result: IResult<&str, &str> = super::take_while_m_n(1, 4, |c: char| c.is_alphabetic())("øn");
650     assert_eq!(result, Ok(("", "øn")));
651   }
652 
653   #[test]
complete_take_while_m_n_utf8_all_matching_substring()654   fn complete_take_while_m_n_utf8_all_matching_substring() {
655     let result: IResult<&str, &str> = super::take_while_m_n(1, 1, |c: char| c.is_alphabetic())("øn");
656     assert_eq!(result, Ok(("n", "ø")));
657   }
658 }
659