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