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