Coverage Report

Created: 2025-10-10 07:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/nom-7.1.3/src/bytes/streaming.rs
Line
Count
Source
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, Parser};
6
use crate::lib::std::ops::RangeFrom;
7
use crate::lib::std::result::Result::*;
8
use 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
/// ```
31
0
pub fn tag<T, Input, Error: ParseError<Input>>(
32
0
  tag: T,
33
0
) -> impl Fn(Input) -> IResult<Input, Input, Error>
34
0
where
35
0
  Input: InputTake + InputLength + Compare<T>,
36
0
  T: InputLength + Clone,
37
{
38
0
  move |i: Input| {
39
0
    let tag_len = tag.input_len();
40
0
    let t = tag.clone();
41
42
0
    let res: IResult<_, _, Error> = match i.compare(t) {
43
0
      CompareResult::Ok => Ok(i.take_split(tag_len)),
44
0
      CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(tag_len - i.input_len()))),
45
      CompareResult::Error => {
46
0
        let e: ErrorKind = ErrorKind::Tag;
47
0
        Err(Err::Error(Error::from_error_kind(i, e)))
48
      }
49
    };
50
0
    res
51
0
  }
52
0
}
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
/// ```
73
0
pub fn tag_no_case<T, Input, Error: ParseError<Input>>(
74
0
  tag: T,
75
0
) -> impl Fn(Input) -> IResult<Input, Input, Error>
76
0
where
77
0
  Input: InputTake + InputLength + Compare<T>,
78
0
  T: InputLength + Clone,
79
{
80
0
  move |i: Input| {
81
0
    let tag_len = tag.input_len();
82
0
    let t = tag.clone();
83
84
0
    let res: IResult<_, _, Error> = match (i).compare_no_case(t) {
85
0
      CompareResult::Ok => Ok(i.take_split(tag_len)),
86
0
      CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(tag_len - i.input_len()))),
87
      CompareResult::Error => {
88
0
        let e: ErrorKind = ErrorKind::Tag;
89
0
        Err(Err::Error(Error::from_error_kind(i, e)))
90
      }
91
    };
92
0
    res
93
0
  }
94
0
}
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
/// ```
117
0
pub fn is_not<T, Input, Error: ParseError<Input>>(
118
0
  arr: T,
119
0
) -> impl Fn(Input) -> IResult<Input, Input, Error>
120
0
where
121
0
  Input: InputTakeAtPosition,
122
0
  T: FindToken<<Input as InputTakeAtPosition>::Item>,
123
{
124
0
  move |i: Input| {
125
0
    let e: ErrorKind = ErrorKind::IsNot;
126
0
    i.split_at_position1(|c| arr.find_token(c), e)
127
0
  }
128
0
}
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
/// ```
153
0
pub fn is_a<T, Input, Error: ParseError<Input>>(
154
0
  arr: T,
155
0
) -> impl Fn(Input) -> IResult<Input, Input, Error>
156
0
where
157
0
  Input: InputTakeAtPosition,
158
0
  T: FindToken<<Input as InputTakeAtPosition>::Item>,
159
{
160
0
  move |i: Input| {
161
0
    let e: ErrorKind = ErrorKind::IsA;
162
0
    i.split_at_position1(|c| !arr.find_token(c), e)
163
0
  }
164
0
}
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
/// ```
188
0
pub fn take_while<F, Input, Error: ParseError<Input>>(
189
0
  cond: F,
190
0
) -> impl Fn(Input) -> IResult<Input, Input, Error>
191
0
where
192
0
  Input: InputTakeAtPosition,
193
0
  F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
194
{
195
0
  move |i: Input| i.split_at_position(|c| !cond(c))
196
0
}
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
/// ```
222
0
pub fn take_while1<F, Input, Error: ParseError<Input>>(
223
0
  cond: F,
224
0
) -> impl Fn(Input) -> IResult<Input, Input, Error>
225
0
where
226
0
  Input: InputTakeAtPosition,
227
0
  F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
228
{
229
0
  move |i: Input| {
230
0
    let e: ErrorKind = ErrorKind::TakeWhile1;
231
0
    i.split_at_position1(|c| !cond(c), e)
232
0
  }
233
0
}
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
/// ```
260
0
pub fn take_while_m_n<F, Input, Error: ParseError<Input>>(
261
0
  m: usize,
262
0
  n: usize,
263
0
  cond: F,
264
0
) -> impl Fn(Input) -> IResult<Input, Input, Error>
265
0
where
266
0
  Input: InputTake + InputIter + InputLength,
267
0
  F: Fn(<Input as InputIter>::Item) -> bool,
268
{
269
0
  move |i: Input| {
270
0
    let input = i;
271
272
0
    match input.position(|c| !cond(c)) {
273
0
      Some(idx) => {
274
0
        if idx >= m {
275
0
          if idx <= n {
276
0
            let res: IResult<_, _, Error> = if let Ok(index) = input.slice_index(idx) {
277
0
              Ok(input.take_split(index))
278
            } else {
279
0
              Err(Err::Error(Error::from_error_kind(
280
0
                input,
281
0
                ErrorKind::TakeWhileMN,
282
0
              )))
283
            };
284
0
            res
285
          } else {
286
0
            let res: IResult<_, _, Error> = if let Ok(index) = input.slice_index(n) {
287
0
              Ok(input.take_split(index))
288
            } else {
289
0
              Err(Err::Error(Error::from_error_kind(
290
0
                input,
291
0
                ErrorKind::TakeWhileMN,
292
0
              )))
293
            };
294
0
            res
295
          }
296
        } else {
297
0
          let e = ErrorKind::TakeWhileMN;
298
0
          Err(Err::Error(Error::from_error_kind(input, e)))
299
        }
300
      }
301
      None => {
302
0
        let len = input.input_len();
303
0
        if len >= n {
304
0
          match input.slice_index(n) {
305
0
            Ok(index) => Ok(input.take_split(index)),
306
0
            Err(_needed) => Err(Err::Error(Error::from_error_kind(
307
0
              input,
308
0
              ErrorKind::TakeWhileMN,
309
0
            ))),
310
          }
311
        } else {
312
0
          let needed = if m > len { m - len } else { 1 };
313
0
          Err(Err::Incomplete(Needed::new(needed)))
314
        }
315
      }
316
    }
317
0
  }
318
0
}
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
/// ```
343
0
pub fn take_till<F, Input, Error: ParseError<Input>>(
344
0
  cond: F,
345
0
) -> impl Fn(Input) -> IResult<Input, Input, Error>
346
0
where
347
0
  Input: InputTakeAtPosition,
348
0
  F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
349
{
350
0
  move |i: Input| i.split_at_position(|c| cond(c))
351
0
}
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
/// ```
375
0
pub fn take_till1<F, Input, Error: ParseError<Input>>(
376
0
  cond: F,
377
0
) -> impl Fn(Input) -> IResult<Input, Input, Error>
378
0
where
379
0
  Input: InputTakeAtPosition,
380
0
  F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
381
{
382
0
  move |i: Input| {
383
0
    let e: ErrorKind = ErrorKind::TakeTill1;
384
0
    i.split_at_position1(|c| cond(c), e)
385
0
  }
386
0
}
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
/// ```
411
0
pub fn take<C, Input, Error: ParseError<Input>>(
412
0
  count: C,
413
0
) -> impl Fn(Input) -> IResult<Input, Input, Error>
414
0
where
415
0
  Input: InputIter + InputTake + InputLength,
416
0
  C: ToUsize,
417
{
418
0
  let c = count.to_usize();
419
0
  move |i: Input| match i.slice_index(c) {
420
0
    Err(i) => Err(Err::Incomplete(i)),
421
0
    Ok(index) => Ok(i.take_split(index)),
422
0
  }
423
0
}
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
/// ```
446
0
pub fn take_until<T, Input, Error: ParseError<Input>>(
447
0
  tag: T,
448
0
) -> impl Fn(Input) -> IResult<Input, Input, Error>
449
0
where
450
0
  Input: InputTake + InputLength + FindSubstring<T>,
451
0
  T: Clone,
452
{
453
0
  move |i: Input| {
454
0
    let t = tag.clone();
455
456
0
    let res: IResult<_, _, Error> = match i.find_substring(t) {
457
0
      None => Err(Err::Incomplete(Needed::Unknown)),
458
0
      Some(index) => Ok(i.take_split(index)),
459
    };
460
0
    res
461
0
  }
462
0
}
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
/// ```
486
0
pub fn take_until1<T, Input, Error: ParseError<Input>>(
487
0
  tag: T,
488
0
) -> impl Fn(Input) -> IResult<Input, Input, Error>
489
0
where
490
0
  Input: InputTake + InputLength + FindSubstring<T>,
491
0
  T: Clone,
492
{
493
0
  move |i: Input| {
494
0
    let t = tag.clone();
495
496
0
    let res: IResult<_, _, Error> = match i.find_substring(t) {
497
0
      None => Err(Err::Incomplete(Needed::Unknown)),
498
0
      Some(0) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::TakeUntil))),
499
0
      Some(index) => Ok(i.take_split(index)),
500
    };
501
0
    res
502
0
  }
503
0
}
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
///
525
0
pub fn escaped<Input, Error, F, G, O1, O2>(
526
0
  mut normal: F,
527
0
  control_char: char,
528
0
  mut escapable: G,
529
0
) -> impl FnMut(Input) -> IResult<Input, Input, Error>
530
0
where
531
0
  Input: Clone
532
0
    + crate::traits::Offset
533
0
    + InputLength
534
0
    + InputTake
535
0
    + InputTakeAtPosition
536
0
    + Slice<RangeFrom<usize>>
537
0
    + InputIter,
538
0
  <Input as InputIter>::Item: crate::traits::AsChar,
539
0
  F: Parser<Input, O1, Error>,
540
0
  G: Parser<Input, O2, Error>,
541
0
  Error: ParseError<Input>,
542
{
543
  use crate::traits::AsChar;
544
545
0
  move |input: Input| {
546
0
    let mut i = input.clone();
547
548
0
    while i.input_len() > 0 {
549
0
      let current_len = i.input_len();
550
551
0
      match normal.parse(i.clone()) {
552
0
        Ok((i2, _)) => {
553
0
          if i2.input_len() == 0 {
554
0
            return Err(Err::Incomplete(Needed::Unknown));
555
0
          } else if i2.input_len() == current_len {
556
0
            let index = input.offset(&i2);
557
0
            return Ok(input.take_split(index));
558
0
          } else {
559
0
            i = i2;
560
0
          }
561
        }
562
        Err(Err::Error(_)) => {
563
          // unwrap() should be safe here since index < $i.input_len()
564
0
          if i.iter_elements().next().unwrap().as_char() == control_char {
565
0
            let next = control_char.len_utf8();
566
0
            if next >= i.input_len() {
567
0
              return Err(Err::Incomplete(Needed::new(1)));
568
            } else {
569
0
              match escapable.parse(i.slice(next..)) {
570
0
                Ok((i2, _)) => {
571
0
                  if i2.input_len() == 0 {
572
0
                    return Err(Err::Incomplete(Needed::Unknown));
573
0
                  } else {
574
0
                    i = i2;
575
0
                  }
576
                }
577
0
                Err(e) => return Err(e),
578
              }
579
            }
580
          } else {
581
0
            let index = input.offset(&i);
582
0
            return Ok(input.take_split(index));
583
          }
584
        }
585
0
        Err(e) => {
586
0
          return Err(e);
587
        }
588
      }
589
    }
590
591
0
    Err(Err::Incomplete(Needed::Unknown))
592
0
  }
593
0
}
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")))]
627
0
pub fn escaped_transform<Input, Error, F, G, O1, O2, ExtendItem, Output>(
628
0
  mut normal: F,
629
0
  control_char: char,
630
0
  mut transform: G,
631
0
) -> impl FnMut(Input) -> IResult<Input, Output, Error>
632
0
where
633
0
  Input: Clone
634
0
    + crate::traits::Offset
635
0
    + InputLength
636
0
    + InputTake
637
0
    + InputTakeAtPosition
638
0
    + Slice<RangeFrom<usize>>
639
0
    + InputIter,
640
0
  Input: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
641
0
  O1: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
642
0
  O2: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
643
0
  <Input as InputIter>::Item: crate::traits::AsChar,
644
0
  F: Parser<Input, O1, Error>,
645
0
  G: Parser<Input, O2, Error>,
646
0
  Error: ParseError<Input>,
647
{
648
  use crate::traits::AsChar;
649
650
0
  move |input: Input| {
651
0
    let mut index = 0;
652
0
    let mut res = input.new_builder();
653
654
0
    let i = input.clone();
655
656
0
    while index < i.input_len() {
657
0
      let current_len = i.input_len();
658
0
      let remainder = i.slice(index..);
659
0
      match normal.parse(remainder.clone()) {
660
0
        Ok((i2, o)) => {
661
0
          o.extend_into(&mut res);
662
0
          if i2.input_len() == 0 {
663
0
            return Err(Err::Incomplete(Needed::Unknown));
664
0
          } else if i2.input_len() == current_len {
665
0
            return Ok((remainder, res));
666
0
          } else {
667
0
            index = input.offset(&i2);
668
0
          }
669
        }
670
        Err(Err::Error(_)) => {
671
          // unwrap() should be safe here since index < $i.input_len()
672
0
          if remainder.iter_elements().next().unwrap().as_char() == control_char {
673
0
            let next = index + control_char.len_utf8();
674
0
            let input_len = input.input_len();
675
676
0
            if next >= input_len {
677
0
              return Err(Err::Incomplete(Needed::Unknown));
678
            } else {
679
0
              match transform.parse(i.slice(next..)) {
680
0
                Ok((i2, o)) => {
681
0
                  o.extend_into(&mut res);
682
0
                  if i2.input_len() == 0 {
683
0
                    return Err(Err::Incomplete(Needed::Unknown));
684
0
                  } else {
685
0
                    index = input.offset(&i2);
686
0
                  }
687
                }
688
0
                Err(e) => return Err(e),
689
              }
690
            }
691
          } else {
692
0
            return Ok((remainder, res));
693
          }
694
        }
695
0
        Err(e) => return Err(e),
696
      }
697
    }
698
0
    Err(Err::Incomplete(Needed::Unknown))
699
0
  }
700
0
}