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 /// ```
tag<T, Input, Error: ParseError<Input>>( tag: T, ) -> impl Fn(Input) -> IResult<Input, Input, Error> where Input: InputTake + InputLength + Compare<T>, T: InputLength + Clone,31 pub fn tag<T, Input, Error: ParseError<Input>>(
32 tag: T,
33 ) -> impl Fn(Input) -> IResult<Input, Input, Error>
34 where
35 Input: InputTake + InputLength + Compare<T>,
36 T: InputLength + Clone,
37 {
38 move |i: Input| {
39 let tag_len = tag.input_len();
40 let t = tag.clone();
41
42 let res: IResult<_, _, Error> = match i.compare(t) {
43 CompareResult::Ok => Ok(i.take_split(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(i, 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 /// ```
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,73 pub fn tag_no_case<T, Input, Error: ParseError<Input>>(
74 tag: T,
75 ) -> impl Fn(Input) -> IResult<Input, Input, Error>
76 where
77 Input: InputTake + InputLength + Compare<T>,
78 T: InputLength + Clone,
79 {
80 move |i: Input| {
81 let tag_len = tag.input_len();
82 let t = tag.clone();
83
84 let res: IResult<_, _, Error> = match (i).compare_no_case(t) {
85 CompareResult::Ok => Ok(i.take_split(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(i, 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 /// ```
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>,117 pub fn is_not<T, Input, Error: ParseError<Input>>(
118 arr: T,
119 ) -> impl Fn(Input) -> IResult<Input, Input, Error>
120 where
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| 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 /// ```
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>,153 pub fn is_a<T, Input, Error: ParseError<Input>>(
154 arr: T,
155 ) -> impl Fn(Input) -> IResult<Input, Input, Error>
156 where
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| !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 /// ```
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,188 pub fn take_while<F, Input, Error: ParseError<Input>>(
189 cond: F,
190 ) -> impl Fn(Input) -> IResult<Input, Input, Error>
191 where
192 Input: InputTakeAtPosition,
193 F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
194 {
195 move |i: Input| i.split_at_position(|c| !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 /// ```
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,222 pub fn take_while1<F, Input, Error: ParseError<Input>>(
223 cond: F,
224 ) -> impl Fn(Input) -> IResult<Input, Input, Error>
225 where
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| !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 /// ```
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,260 pub 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>
265 where
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 /// ```
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,343 pub fn take_till<F, Input, Error: ParseError<Input>>(
344 cond: F,
345 ) -> impl Fn(Input) -> IResult<Input, Input, Error>
346 where
347 Input: InputTakeAtPosition,
348 F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
349 {
350 move |i: Input| i.split_at_position(|c| 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 /// ```
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,375 pub fn take_till1<F, Input, Error: ParseError<Input>>(
376 cond: F,
377 ) -> impl Fn(Input) -> IResult<Input, Input, Error>
378 where
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| 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 /// ```
take<C, Input, Error: ParseError<Input>>( count: C, ) -> impl Fn(Input) -> IResult<Input, Input, Error> where Input: InputIter + InputTake + InputLength, C: ToUsize,411 pub fn take<C, Input, Error: ParseError<Input>>(
412 count: C,
413 ) -> impl Fn(Input) -> IResult<Input, Input, Error>
414 where
415 Input: InputIter + InputTake + InputLength,
416 C: ToUsize,
417 {
418 let c = count.to_usize();
419 move |i: Input| match i.slice_index(c) {
420 Err(i) => Err(Err::Incomplete(i)),
421 Ok(index) => Ok(i.take_split(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 /// ```
take_until<T, Input, Error: ParseError<Input>>( tag: T, ) -> impl Fn(Input) -> IResult<Input, Input, Error> where Input: InputTake + InputLength + FindSubstring<T>, T: Clone,446 pub fn take_until<T, Input, Error: ParseError<Input>>(
447 tag: T,
448 ) -> impl Fn(Input) -> IResult<Input, Input, Error>
449 where
450 Input: InputTake + InputLength + FindSubstring<T>,
451 T: Clone,
452 {
453 move |i: Input| {
454 let t = tag.clone();
455
456 let res: IResult<_, _, Error> = match i.find_substring(t) {
457 None => Err(Err::Incomplete(Needed::Unknown)),
458 Some(index) => Ok(i.take_split(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 /// ```
take_until1<T, Input, Error: ParseError<Input>>( tag: T, ) -> impl Fn(Input) -> IResult<Input, Input, Error> where Input: InputTake + InputLength + FindSubstring<T>, T: Clone,486 pub fn take_until1<T, Input, Error: ParseError<Input>>(
487 tag: T,
488 ) -> impl Fn(Input) -> IResult<Input, Input, Error>
489 where
490 Input: InputTake + InputLength + FindSubstring<T>,
491 T: Clone,
492 {
493 move |i: Input| {
494 let t = tag.clone();
495
496 let res: IResult<_, _, Error> = match i.find_substring(t) {
497 None => Err(Err::Incomplete(Needed::Unknown)),
498 Some(0) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::TakeUntil))),
499 Some(index) => Ok(i.take_split(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 ///
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>,525 pub 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>
530 where
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")))]
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>,627 pub 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>
632 where
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