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