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