1 /// Try a list of parsers and return the result of the first successful one 2 /// 3 /// ```rust,ignore 4 /// alt!(I -> IResult<I,O> | I -> IResult<I,O> | ... | I -> IResult<I,O> ) => I -> IResult<I, O> 5 /// ``` 6 /// All the parsers must have the same return type. 7 /// 8 /// If one of the parsers returns `Incomplete`, `alt!` will return `Incomplete`, to retry 9 /// once you get more input. Note that it is better for performance to know the 10 /// minimum size of data you need before you get into `alt!`. 11 /// 12 /// The `alt!` combinator is used in the following way: 13 /// 14 /// ```rust,ignore 15 /// alt!(parser_1 | parser_2 | ... | parser_n) 16 /// ``` 17 /// 18 /// # Basic example 19 /// 20 /// ``` 21 /// # #[macro_use] extern crate nom; 22 /// # fn main() { 23 /// // Create a parser that will match either "dragon" or "beast" 24 /// named!( dragon_or_beast, alt!( tag!( "dragon" ) | tag!( "beast" ) ) ); 25 /// 26 /// // Given the input "dragon slayer", the parser will match "dragon" 27 /// // and the rest will be " slayer" 28 /// let (rest, result) = dragon_or_beast(b"dragon slayer").unwrap(); 29 /// assert_eq!(result, b"dragon"); 30 /// assert_eq!(rest, b" slayer"); 31 /// 32 /// // Given the input "beast of Gevaudan", the parser will match "beast" 33 /// // and the rest will be " of Gevaudan" 34 /// let (rest, result) = dragon_or_beast(&b"beast of Gevaudan"[..]).unwrap(); 35 /// assert_eq!(result, b"beast"); 36 /// assert_eq!(rest, b" of Gevaudan"); 37 /// # } 38 /// ``` 39 /// 40 /// # Manipulate results 41 /// 42 /// There exists another syntax for `alt!` that gives you the ability to 43 /// manipulate the result from each parser: 44 /// 45 /// ``` 46 /// # #[macro_use] extern crate nom; 47 /// # fn main() { 48 /// # 49 /// // We create an enum to represent our creatures 50 /// #[derive(Debug,PartialEq,Eq)] 51 /// enum Creature { 52 /// Dragon, 53 /// Beast, 54 /// Unknown(usize) 55 /// } 56 /// 57 /// // Let's make a helper function that returns true when not a space 58 /// // we are required to do this because the `take_while!` macro is limited 59 /// // to idents, so we can't negate `ìs_space` at the call site 60 /// fn is_not_space(c: u8) -> bool { ! nom::character::is_space(c) } 61 /// 62 /// // Our parser will return the `Dragon` variant when matching "dragon", 63 /// // the `Beast` variant when matching "beast" and otherwise it will consume 64 /// // the input until a space is found and return an `Unknown` creature with 65 /// // the size of it's name. 66 /// named!(creature<Creature>, alt!( 67 /// tag!("dragon") => { |_| Creature::Dragon } | 68 /// tag!("beast") => { |_| Creature::Beast } | 69 /// take_while!(is_not_space) => { |r: &[u8]| Creature::Unknown(r.len()) } 70 /// // the closure takes the result as argument if the parser is successful 71 /// )); 72 /// 73 /// // Given the input "dragon slayer" the parser will return `Creature::Dragon` 74 /// // and the rest will be " slayer" 75 /// let (rest, result) = creature(b"dragon slayer").unwrap(); 76 /// assert_eq!(result, Creature::Dragon); 77 /// assert_eq!(rest, b" slayer"); 78 /// 79 /// // Given the input "beast of Gevaudan" the parser will return `Creature::Beast` 80 /// // and the rest will be " of Gevaudan" 81 /// let (rest, result) = creature(b"beast of Gevaudan").unwrap(); 82 /// assert_eq!(result, Creature::Beast); 83 /// assert_eq!(rest, b" of Gevaudan"); 84 /// 85 /// // Given the input "demon hunter" the parser will return `Creature::Unknown(5)` 86 /// // and the rest will be " hunter" 87 /// let (rest, result) = creature(b"demon hunter").unwrap(); 88 /// assert_eq!(result, Creature::Unknown(5)); 89 /// assert_eq!(rest, b" hunter"); 90 /// # } 91 /// ``` 92 /// 93 /// # Behaviour of `alt!` 94 /// 95 /// **BE CAREFUL** there is a case where the behaviour of `alt!` can be confusing: 96 /// 97 /// when the alternatives have different lengths, like this case: 98 /// 99 /// ```ignore 100 /// named!( test, alt!( tag!( "abcd" ) | tag!( "ef" ) | tag!( "ghi" ) | tag!( "kl" ) ) ); 101 /// ``` 102 /// 103 /// With this parser, if you pass `"abcd"` as input, the first alternative parses it correctly, 104 /// but if you pass `"efg"`, the first alternative will return `Incomplete`, since it needs an input 105 /// of 4 bytes. This behaviour of `alt!` is expected: if you get a partial input that isn't matched 106 /// by the first alternative, but would match if the input was complete, you want `alt!` to indicate 107 /// that it cannot decide with limited information. 108 /// 109 /// There are two ways to fix this behaviour. The first one consists in ordering the alternatives 110 /// by size, like this: 111 /// 112 /// ```ignore 113 /// named!( test, alt!( tag!( "ef" ) | tag!( "kl") | tag!( "ghi" ) | tag!( "abcd" ) ) ); 114 /// ``` 115 /// 116 /// With this solution, the largest alternative will be tested last. 117 /// 118 /// The other solution uses the `complete!` combinator, which transforms an `Incomplete` in an 119 /// `Error`. If one of the alternatives returns `Incomplete` but is wrapped by `complete!`, 120 /// `alt!` will try the next alternative. This is useful when you know that 121 /// you will not get partial input: 122 /// 123 /// ```ignore 124 /// named!( test, 125 /// alt!( 126 /// complete!( tag!( "abcd" ) ) | 127 /// complete!( tag!( "ef" ) ) | 128 /// complete!( tag!( "ghi" ) ) | 129 /// complete!( tag!( "kl" ) ) 130 /// ) 131 /// ); 132 /// ``` 133 /// 134 /// This behaviour of `alt!` can get especially confusing if multiple alternatives have different 135 /// sizes but a common prefix, like this: 136 /// 137 /// ```ignore 138 /// named!( test, alt!( tag!( "abcd" ) | tag!( "ab" ) | tag!( "ef" ) ) ); 139 /// ``` 140 /// 141 /// in that case, if you order by size, passing `"abcd"` as input will always be matched by the 142 /// smallest parser, so the solution using `complete!` is better suited. 143 /// 144 /// You can also nest multiple `alt!`, like this: 145 /// 146 /// ```ignore 147 /// named!( test, 148 /// alt!( 149 /// preceded!( 150 /// tag!("ab"), 151 /// alt!( 152 /// tag!( "cd" ) | 153 /// eof!() 154 /// ) 155 /// ) 156 /// | tag!( "ef" ) 157 /// ) 158 /// ); 159 /// ``` 160 /// 161 /// `preceded!` will first parse `"ab"` then, if successful, try the alternatives "cd", 162 /// or empty input (End Of File). If none of them work, `preceded!` will fail and 163 /// "ef" will be tested. 164 /// 165 #[macro_export(local_inner_macros)] 166 macro_rules! alt ( 167 (__impl $i:expr, $submac:ident!( $($args:tt)* ), $($rest:tt)* ) => ( 168 nom_compile_error!("alt uses '|' as separator, not ',': 169 170 alt!( 171 tag!(\"abcd\") | 172 tag!(\"efgh\") | 173 tag!(\"ijkl\") 174 ) 175 "); 176 ); 177 (__impl $i:expr, $e:path, $($rest:tt)* ) => ( 178 alt!(__impl $i, call!($e) , $($rest)*); 179 ); 180 (__impl $i:expr, $e:path | $($rest:tt)*) => ( 181 alt!(__impl $i, call!($e) | $($rest)*); 182 ); 183 184 (__impl $i:expr, $subrule:ident!( $($args:tt)*) | $($rest:tt)*) => ( 185 { 186 use $crate::lib::std::result::Result::*; 187 use $crate::Err; 188 189 let i_ = $i.clone(); 190 let res = $subrule!(i_, $($args)*); 191 match res { 192 Ok(o) => Ok(o), 193 Err(Err::Error(e)) => { 194 let out = alt!(__impl $i, $($rest)*); 195 196 // Compile-time hack to ensure that res's E type is not under-specified. 197 // This all has no effect at runtime. 198 #[allow(dead_code)] 199 fn unify_types<T>(_: &T, _: &T) {} 200 if let Err(Err::Error(ref e2)) = out { 201 unify_types(&e, e2); 202 } 203 204 out 205 }, 206 Err(e) => Err(e), 207 } 208 } 209 ); 210 211 (__impl $i:expr, $subrule:ident!( $($args:tt)* ) => { $gen:expr } | $($rest:tt)*) => ( 212 { 213 use $crate::lib::std::result::Result::*; 214 use $crate::Err; 215 216 let i_ = $i.clone(); 217 match $subrule!(i_, $($args)* ) { 218 Ok((i,o)) => Ok((i,$gen(o))), 219 Err(Err::Error(e)) => { 220 let out = alt!(__impl $i, $($rest)*); 221 222 // Compile-time hack to ensure that res's E type is not under-specified. 223 // This all has no effect at runtime. 224 fn unify_types<T>(_: &T, _: &T) {} 225 if let Err(Err::Error(ref e2)) = out { 226 unify_types(&e, e2); 227 } 228 229 out 230 }, 231 Err(e) => Err(e), 232 } 233 } 234 ); 235 236 (__impl $i:expr, $e:path => { $gen:expr } | $($rest:tt)*) => ( 237 alt!(__impl $i, call!($e) => { $gen } | $($rest)*); 238 ); 239 240 (__impl $i:expr, __end) => ( 241 { 242 use $crate::{Err,error::ErrorKind}; 243 let e2 = ErrorKind::Alt; 244 let err = Err::Error(error_position!($i, e2)); 245 246 Err(err) 247 } 248 ); 249 250 ($i:expr, $($rest:tt)*) => ( 251 { 252 alt!(__impl $i, $($rest)* | __end) 253 } 254 ); 255 ); 256 257 /// `switch!(I -> IResult<I,P>, P => I -> IResult<I,O> | ... | P => I -> IResult<I,O> ) => I -> IResult<I, O>` 258 /// choose the next parser depending on the result of the first one, if successful, 259 /// and returns the result of the second parser 260 /// 261 /// ``` 262 /// # #[macro_use] extern crate nom; 263 /// # use nom::Err; 264 /// # use nom::error::ErrorKind; 265 /// # fn main() { 266 /// named!(sw, 267 /// switch!(take!(4), 268 /// b"abcd" => tag!("XYZ") | 269 /// b"efgh" => tag!("123") 270 /// ) 271 /// ); 272 /// 273 /// let a = b"abcdXYZ123"; 274 /// let b = b"abcdef"; 275 /// let c = b"efgh123"; 276 /// let d = b"blah"; 277 /// 278 /// assert_eq!(sw(&a[..]), Ok((&b"123"[..], &b"XYZ"[..]))); 279 /// assert_eq!(sw(&b[..]), Err(Err::Error(error_node_position!(&b"abcdef"[..], ErrorKind::Switch, 280 /// error_position!(&b"ef"[..], ErrorKind::Tag))))); 281 /// assert_eq!(sw(&c[..]), Ok((&b""[..], &b"123"[..]))); 282 /// assert_eq!(sw(&d[..]), Err(Err::Error(error_position!(&b"blah"[..], ErrorKind::Switch)))); 283 /// # } 284 /// ``` 285 /// 286 /// You can specify a default case like with a normal match, using `_` 287 /// 288 /// ``` 289 /// # #[macro_use] extern crate nom; 290 /// # fn main() { 291 /// named!(sw, 292 /// switch!(take!(4), 293 /// b"abcd" => tag!("XYZ") | 294 /// _ => value!(&b"default"[..]) 295 /// ) 296 /// ); 297 /// 298 /// let a = b"abcdXYZ123"; 299 /// let b = b"blah"; 300 /// 301 /// assert_eq!(sw(&a[..]), Ok((&b"123"[..], &b"XYZ"[..]))); 302 /// assert_eq!(sw(&b[..]), Ok((&b""[..], &b"default"[..]))); 303 /// # } 304 /// ``` 305 /// 306 /// Due to limitations in Rust macros, it is not possible to have simple functions on the right hand 307 /// side of pattern, like this: 308 /// 309 /// ```ignore 310 /// named!(xyz, tag!("XYZ")); 311 /// named!(num, tag!("123")); 312 /// named!(sw, 313 /// switch!(take!(4), 314 /// b"abcd" => xyz | 315 /// b"efgh" => 123 316 /// ) 317 /// ); 318 /// ``` 319 /// 320 /// If you want to pass your own functions instead, you can use the `call!` combinator as follows: 321 /// 322 /// ```ignore 323 /// named!(xyz, tag!("XYZ")); 324 /// named!(num, tag!("123")); 325 /// named!(sw, 326 /// switch!(take!(4), 327 /// b"abcd" => call!(xyz) | 328 /// b"efgh" => call!(num) 329 /// ) 330 /// ); 331 /// ``` 332 /// 333 #[macro_export(local_inner_macros)] 334 macro_rules! switch ( 335 (__impl $i:expr, $submac:ident!( $($args:tt)* ), $( $($p:pat)|+ => $subrule:ident!( $($args2:tt)* ))|* ) => ( 336 { 337 use $crate::lib::std::result::Result::*; 338 use $crate::lib::std::option::Option::*; 339 use $crate::{Err,error::ErrorKind}; 340 341 let i_ = $i.clone(); 342 match map!(i_, $submac!($($args)*), Some) { 343 Err(Err::Error(err)) => { 344 fn unify_types<T>(_: &T, _: &T) {} 345 let e1 = ErrorKind::Switch; 346 let e2 = error_position!($i, e1.clone()); 347 unify_types(&err, &e2); 348 349 Err(Err::Error(error_node_position!($i, e1, err))) 350 }, 351 Err(e) => Err(e), 352 Ok((i, o)) => { 353 354 match o { 355 $($(Some($p) )|+ => match $subrule!(i, $($args2)*) { 356 Err(Err::Error(err)) => { 357 fn unify_types<T>(_: &T, _: &T) {} 358 let e1 = ErrorKind::Switch; 359 let e2 = error_position!($i, e1.clone()); 360 unify_types(&err, &e2); 361 362 Err(Err::Error(error_node_position!($i, e1, err))) 363 }, 364 Ok(o) => Ok(o), 365 Err(e) => Err(e), 366 }),*, 367 _ => Err(Err::convert(Err::Error(error_position!($i, ErrorKind::Switch)))) 368 } 369 } 370 } 371 } 372 ); 373 ($i:expr, $submac:ident!( $($args:tt)*), $($rest:tt)*) => ( 374 { 375 switch!(__impl $i, $submac!($($args)*), $($rest)*) 376 } 377 ); 378 ($i:expr, $e:path, $($rest:tt)*) => ( 379 { 380 switch!(__impl $i, call!($e), $($rest)*) 381 } 382 ); 383 ); 384 385 /// 386 /// 387 /// `permutation!(I -> IResult<I,A>, I -> IResult<I,B>, ... I -> IResult<I,X> ) => I -> IResult<I, (A,B,...X)>` 388 /// applies its sub parsers in a sequence, but independent from their order 389 /// this parser will only succeed if all of its sub parsers succeed 390 /// 391 /// the tuple of results is in the same order as the parsers are declared 392 /// 393 /// ``` 394 /// # #[macro_use] extern crate nom; 395 /// # use nom::{Err,error::ErrorKind,Needed}; 396 /// # fn main() { 397 /// named!(perm<(&[u8], &[u8], &[u8])>, 398 /// permutation!(tag!("abcd"), tag!("efg"), tag!("hi")) 399 /// ); 400 /// 401 /// // whatever the order, if the parser succeeds, each 402 /// // tag should have matched correctly 403 /// let expected = (&b"abcd"[..], &b"efg"[..], &b"hi"[..]); 404 /// 405 /// let a = &b"abcdefghijk"[..]; 406 /// assert_eq!(perm(a), Ok((&b"jk"[..], expected))); 407 /// let b = &b"efgabcdhijkl"[..]; 408 /// assert_eq!(perm(b), Ok((&b"jkl"[..], expected))); 409 /// let c = &b"hiefgabcdjklm"[..]; 410 /// assert_eq!(perm(c), Ok((&b"jklm"[..], expected))); 411 /// 412 /// let d = &b"efgxyzabcdefghi"[..]; 413 /// assert_eq!(perm(d), Err(Err::Error(error_node_position!(&b"efgxyzabcdefghi"[..], ErrorKind::Permutation, 414 /// error_position!(&b"xyzabcdefghi"[..], ErrorKind::Permutation))))); 415 /// 416 /// let e = &b"efgabc"[..]; 417 /// assert_eq!(perm(e), Err(Err::Incomplete(Needed::Size(4)))); 418 /// # } 419 /// ``` 420 /// 421 /// If one of the child parsers is followed by a `?`, that parser is now 422 /// optional: 423 /// 424 /// ``` 425 /// # #[macro_use] extern crate nom; 426 /// # use nom::{Err,error::ErrorKind,Needed}; 427 /// # fn main() { 428 /// named!(perm<&str, (Option<&str>, &str, &str)>, 429 /// permutation!(tag!("abcd")?, tag!("efg"), tag!("hi")) 430 /// ); 431 /// 432 /// // whatever the order, if the parser succeeds, each 433 /// // tag should have matched correctly 434 /// let expected = (Some("abcd"), "efg", "hi"); 435 /// 436 /// let a = "abcdefghijk"; 437 /// assert_eq!(perm(a), Ok(("jk", expected))); 438 /// let b = "efgabcdhijkl"; 439 /// assert_eq!(perm(b), Ok(("jkl", expected))); 440 /// let c = "hiefgabcdjklm"; 441 /// assert_eq!(perm(c), Ok(("jklm", expected))); 442 /// 443 /// // if `abcd` is missing: 444 /// let expected = (None, "efg", "hi"); 445 /// 446 /// let a = "efghijk"; 447 /// assert_eq!(perm(a), Ok(("jk", expected))); 448 /// let b = "efghijkl"; 449 /// assert_eq!(perm(b), Ok(("jkl", expected))); 450 /// let c = "hiefgjklm"; 451 /// assert_eq!(perm(c), Ok(("jklm", expected))); 452 /// 453 /// let e = "efgabc"; 454 /// assert_eq!(perm(e), Err(Err::Incomplete(Needed::Size(4)))); 455 /// # } 456 /// ``` 457 #[macro_export(local_inner_macros)] 458 macro_rules! permutation ( 459 ($i:expr, $($rest:tt)*) => ( 460 { 461 use $crate::lib::std::result::Result::*; 462 use $crate::lib::std::option::Option::*; 463 use $crate::{Err,error::ErrorKind}; 464 465 let mut res = permutation_init!((), $($rest)*); 466 let mut input = $i; 467 let mut error = None; 468 let mut needed = None; 469 470 loop { 471 let mut all_done = true; 472 permutation_iterator!(0, input, all_done, needed, res, $($rest)*); 473 474 //if we reach that part, it means none of the parsers were able to read anything 475 if !all_done { 476 //FIXME: should wrap the error returned by the child parser 477 error = Some(error_position!(input, ErrorKind::Permutation)); 478 } 479 break; 480 } 481 482 if let Some(need) = needed { 483 Err(Err::convert(need)) 484 } else { 485 if let Some(unwrapped_res) = { permutation_unwrap!(0, (), res, $($rest)*) } { 486 Ok((input, unwrapped_res)) 487 } else { 488 if let Some(e) = error { 489 Err(Err::Error(error_node_position!($i, ErrorKind::Permutation, e))) 490 } else { 491 Err(Err::Error(error_position!($i, ErrorKind::Permutation))) 492 } 493 } 494 } 495 } 496 ); 497 ); 498 499 #[doc(hidden)] 500 #[macro_export(local_inner_macros)] 501 macro_rules! permutation_init ( 502 ((), $e:ident?, $($rest:tt)*) => ( 503 permutation_init!(($crate::lib::std::option::Option::None), $($rest)*) 504 ); 505 ((), $e:ident, $($rest:tt)*) => ( 506 permutation_init!(($crate::lib::std::option::Option::None), $($rest)*) 507 ); 508 509 ((), $submac:ident!( $($args:tt)* )?, $($rest:tt)*) => ( 510 permutation_init!(($crate::lib::std::option::Option::None), $($rest)*) 511 ); 512 ((), $submac:ident!( $($args:tt)* ), $($rest:tt)*) => ( 513 permutation_init!(($crate::lib::std::option::Option::None), $($rest)*) 514 ); 515 516 (($($parsed:expr),*), $e:ident?, $($rest:tt)*) => ( 517 permutation_init!(($($parsed),* , $crate::lib::std::option::Option::None), $($rest)*); 518 ); 519 (($($parsed:expr),*), $e:ident, $($rest:tt)*) => ( 520 permutation_init!(($($parsed),* , $crate::lib::std::option::Option::None), $($rest)*); 521 ); 522 523 (($($parsed:expr),*), $submac:ident!( $($args:tt)* )?, $($rest:tt)*) => ( 524 permutation_init!(($($parsed),* , $crate::lib::std::option::Option::None), $($rest)*); 525 ); 526 (($($parsed:expr),*), $submac:ident!( $($args:tt)* ), $($rest:tt)*) => ( 527 permutation_init!(($($parsed),* , $crate::lib::std::option::Option::None), $($rest)*); 528 ); 529 530 (($($parsed:expr),*), $e:ident) => ( 531 ($($parsed),* , $crate::lib::std::option::Option::None) 532 ); 533 (($($parsed:expr),*), $e:ident?) => ( 534 ($($parsed),* , $crate::lib::std::option::Option::None) 535 ); 536 537 (($($parsed:expr),*), $submac:ident!( $($args:tt)* )?) => ( 538 ($($parsed),* , $crate::lib::std::option::Option::None) 539 ); 540 (($($parsed:expr),*), $submac:ident!( $($args:tt)* )) => ( 541 ($($parsed),* , $crate::lib::std::option::Option::None) 542 ); 543 (($($parsed:expr),*),) => ( 544 ($($parsed),*) 545 ); 546 ); 547 548 #[doc(hidden)] 549 #[macro_export(local_inner_macros)] 550 macro_rules! succ ( 551 (0, $submac:ident ! ($($rest:tt)*)) => ($submac!(1, $($rest)*)); 552 (1, $submac:ident ! ($($rest:tt)*)) => ($submac!(2, $($rest)*)); 553 (2, $submac:ident ! ($($rest:tt)*)) => ($submac!(3, $($rest)*)); 554 (3, $submac:ident ! ($($rest:tt)*)) => ($submac!(4, $($rest)*)); 555 (4, $submac:ident ! ($($rest:tt)*)) => ($submac!(5, $($rest)*)); 556 (5, $submac:ident ! ($($rest:tt)*)) => ($submac!(6, $($rest)*)); 557 (6, $submac:ident ! ($($rest:tt)*)) => ($submac!(7, $($rest)*)); 558 (7, $submac:ident ! ($($rest:tt)*)) => ($submac!(8, $($rest)*)); 559 (8, $submac:ident ! ($($rest:tt)*)) => ($submac!(9, $($rest)*)); 560 (9, $submac:ident ! ($($rest:tt)*)) => ($submac!(10, $($rest)*)); 561 (10, $submac:ident ! ($($rest:tt)*)) => ($submac!(11, $($rest)*)); 562 (11, $submac:ident ! ($($rest:tt)*)) => ($submac!(12, $($rest)*)); 563 (12, $submac:ident ! ($($rest:tt)*)) => ($submac!(13, $($rest)*)); 564 (13, $submac:ident ! ($($rest:tt)*)) => ($submac!(14, $($rest)*)); 565 (14, $submac:ident ! ($($rest:tt)*)) => ($submac!(15, $($rest)*)); 566 (15, $submac:ident ! ($($rest:tt)*)) => ($submac!(16, $($rest)*)); 567 (16, $submac:ident ! ($($rest:tt)*)) => ($submac!(17, $($rest)*)); 568 (17, $submac:ident ! ($($rest:tt)*)) => ($submac!(18, $($rest)*)); 569 (18, $submac:ident ! ($($rest:tt)*)) => ($submac!(19, $($rest)*)); 570 (19, $submac:ident ! ($($rest:tt)*)) => ($submac!(20, $($rest)*)); 571 ); 572 573 #[doc(hidden)] 574 #[macro_export(local_inner_macros)] 575 macro_rules! permutation_unwrap ( 576 ($it:tt, (), $res:ident, $e:ident?, $($rest:tt)*) => ( 577 succ!($it, permutation_unwrap!(($res.$it), $res, $($rest)*)); 578 ); 579 ($it:tt, (), $res:ident, $e:ident, $($rest:tt)*) => ({ 580 let res = $res.$it; 581 if res.is_some() { 582 succ!($it, permutation_unwrap!((res.unwrap()), $res, $($rest)*)) 583 } else { 584 $crate::lib::std::option::Option::None 585 } 586 }); 587 588 ($it:tt, (), $res:ident, $submac:ident!( $($args:tt)* )?, $($rest:tt)*) => ( 589 succ!($it, permutation_unwrap!(($res.$it), $res, $($rest)*)); 590 ); 591 ($it:tt, (), $res:ident, $submac:ident!( $($args:tt)* ), $($rest:tt)*) => ({ 592 let res = $res.$it; 593 if res.is_some() { 594 succ!($it, permutation_unwrap!((res.unwrap()), $res, $($rest)*)) 595 } else { 596 $crate::lib::std::option::Option::None 597 } 598 }); 599 600 ($it:tt, ($($parsed:expr),*), $res:ident, $e:ident?, $($rest:tt)*) => ( 601 succ!($it, permutation_unwrap!(($($parsed),* , $res.$it), $res, $($rest)*)); 602 ); 603 ($it:tt, ($($parsed:expr),*), $res:ident, $e:ident, $($rest:tt)*) => ({ 604 let res = $res.$it; 605 if res.is_some() { 606 succ!($it, permutation_unwrap!(($($parsed),* , res.unwrap()), $res, $($rest)*)) 607 } else { 608 $crate::lib::std::option::Option::None 609 } 610 }); 611 612 ($it:tt, ($($parsed:expr),*), $res:ident, $submac:ident!( $($args:tt)* )?, $($rest:tt)*) => ( 613 succ!($it, permutation_unwrap!(($($parsed),* , $res.$it), $res, $($rest)*)); 614 ); 615 ($it:tt, ($($parsed:expr),*), $res:ident, $submac:ident!( $($args:tt)* ), $($rest:tt)*) => ({ 616 let res = $res.$it; 617 if res.is_some() { 618 succ!($it, permutation_unwrap!(($($parsed),* , res.unwrap()), $res, $($rest)*)) 619 } else { 620 $crate::lib::std::option::Option::None 621 } 622 }); 623 624 ($it:tt, ($($parsed:expr),*), $res:ident?, $e:ident) => ( 625 $crate::lib::std::option::Option::Some(($($parsed),* , { $res.$it })) 626 ); 627 ($it:tt, ($($parsed:expr),*), $res:ident, $e:ident) => ({ 628 let res = $res.$it; 629 if res.is_some() { 630 $crate::lib::std::option::Option::Some(($($parsed),* , res.unwrap() )) 631 } else { 632 $crate::lib::std::option::Option::None 633 } 634 }); 635 636 ($it:tt, ($($parsed:expr),*), $res:ident, $submac:ident!( $($args:tt)* )?) => ( 637 $crate::lib::std::option::Option::Some(($($parsed),* , { $res.$it })) 638 ); 639 ($it:tt, ($($parsed:expr),*), $res:ident, $submac:ident!( $($args:tt)* )) => ({ 640 let res = $res.$it; 641 if res.is_some() { 642 $crate::lib::std::option::Option::Some(($($parsed),* , res.unwrap() )) 643 } else { 644 $crate::lib::std::option::Option::None 645 } 646 }); 647 ); 648 649 #[doc(hidden)] 650 #[macro_export(local_inner_macros)] 651 macro_rules! permutation_iterator ( 652 ($it:tt,$i:expr, $all_done:expr, $needed:expr, $res:expr, $e:ident?, $($rest:tt)*) => ( 653 permutation_iterator!($it, $i, $all_done, $needed, $res, call!($e), $($rest)*); 654 ); 655 ($it:tt,$i:expr, $all_done:expr, $needed:expr, $res:expr, $e:ident, $($rest:tt)*) => ( 656 permutation_iterator!($it, $i, $all_done, $needed, $res, call!($e), $($rest)*); 657 ); 658 659 ($it:tt, $i:expr, $all_done:expr, $needed:expr, $res:expr, $submac:ident!( $($args:tt)* )?, $($rest:tt)*) => { 660 permutation_iterator!($it, $i, $all_done, $needed, $res, $submac!($($args)*) , $($rest)*); 661 }; 662 ($it:tt, $i:expr, $all_done:expr, $needed:expr, $res:expr, $submac:ident!( $($args:tt)* ), $($rest:tt)*) => ({ 663 use $crate::lib::std::result::Result::*; 664 use $crate::lib::std::option::Option::*; 665 use $crate::Err; 666 667 if $res.$it.is_none() { 668 match $submac!($i, $($args)*) { 669 Ok((i,o)) => { 670 $i = i; 671 $res.$it = Some(o); 672 continue; 673 }, 674 Err(Err::Error(_)) => { 675 $all_done = false; 676 }, 677 Err(e) => { 678 $needed = Some(e); 679 break; 680 } 681 }; 682 } 683 succ!($it, permutation_iterator!($i, $all_done, $needed, $res, $($rest)*)); 684 }); 685 686 ($it:tt,$i:expr, $all_done:expr, $needed:expr, $res:expr, $e:ident?) => ( 687 permutation_iterator!($it, $i, $all_done, $needed, $res, call!($e)); 688 ); 689 ($it:tt,$i:expr, $all_done:expr, $needed:expr, $res:expr, $e:ident) => ( 690 permutation_iterator!($it, $i, $all_done, $needed, $res, call!($e)); 691 ); 692 693 ($it:tt, $i:expr, $all_done:expr, $needed:expr, $res:expr, $submac:ident!( $($args:tt)* )?) => { 694 permutation_iterator!($it, $i, $all_done, $needed, $res, $submac!($($args)*)); 695 }; 696 ($it:tt, $i:expr, $all_done:expr, $needed:expr, $res:expr, $submac:ident!( $($args:tt)* )) => ({ 697 use $crate::lib::std::result::Result::*; 698 use $crate::lib::std::option::Option::*; 699 use $crate::Err; 700 701 if $res.$it.is_none() { 702 match $submac!($i, $($args)*) { 703 Ok((i,o)) => { 704 $i = i; 705 $res.$it = Some(o); 706 continue; 707 }, 708 Err(Err::Error(_)) => { 709 $all_done = false; 710 }, 711 Err(e) => { 712 $needed = Some(e); 713 break; 714 } 715 }; 716 } 717 }); 718 ); 719 720 #[cfg(test)] 721 mod tests { 722 use crate::error::ErrorKind; 723 #[cfg(feature = "alloc")] 724 use crate::{ 725 error::ParseError, 726 lib::std::{ 727 fmt::Debug, 728 string::{String, ToString} 729 } 730 }; 731 use crate::internal::{Err, IResult, Needed}; 732 733 // reproduce the tag and take macros, because of module import order 734 macro_rules! tag ( 735 ($i:expr, $inp: expr) => ( 736 { 737 #[inline(always)] 738 fn as_bytes<T: $crate::AsBytes>(b: &T) -> &[u8] { 739 b.as_bytes() 740 } 741 742 let expected = $inp; 743 let bytes = as_bytes(&expected); 744 745 tag_bytes!($i,bytes) 746 } 747 ); 748 ); 749 750 macro_rules! tag_bytes ( 751 ($i:expr, $bytes: expr) => ( 752 { 753 use $crate::lib::std::cmp::min; 754 755 let len = $i.len(); 756 let blen = $bytes.len(); 757 let m = min(len, blen); 758 let reduced = &$i[..m]; 759 let b = &$bytes[..m]; 760 761 let res: IResult<_,_,_> = if reduced != b { 762 let e: ErrorKind = ErrorKind::Tag; 763 Err(Err::Error(error_position!($i, e))) 764 } else if m < blen { 765 Err(Err::Incomplete(Needed::Size(blen))) 766 } else { 767 Ok((&$i[blen..], reduced)) 768 }; 769 res 770 } 771 ); 772 ); 773 774 macro_rules! take( 775 ($i:expr, $count:expr) => ( 776 { 777 let cnt = $count as usize; 778 let res:IResult<&[u8],&[u8],_> = if $i.len() < cnt { 779 Err(Err::Incomplete(Needed::Size(cnt))) 780 } else { 781 Ok((&$i[cnt..],&$i[0..cnt])) 782 }; 783 res 784 } 785 ); 786 ); 787 788 #[cfg(feature = "alloc")] 789 #[derive(Debug, Clone, PartialEq)] 790 pub struct ErrorStr(String); 791 792 #[cfg(feature = "alloc")] 793 impl From<u32> for ErrorStr { from(i: u32) -> Self794 fn from(i: u32) -> Self { 795 ErrorStr(format!("custom error code: {}", i)) 796 } 797 } 798 799 #[cfg(feature = "alloc")] 800 impl<'a> From<&'a str> for ErrorStr { from(i: &'a str) -> Self801 fn from(i: &'a str) -> Self { 802 ErrorStr(format!("custom error message: {}", i)) 803 } 804 } 805 806 #[cfg(feature = "alloc")] 807 impl<I: Debug> ParseError<I> for ErrorStr { from_error_kind(input: I, kind: ErrorKind) -> Self808 fn from_error_kind(input: I, kind: ErrorKind) -> Self { 809 ErrorStr(format!("custom error message: ({:?}, {:?})", input, kind)) 810 } 811 append(input: I, kind: ErrorKind, other: Self) -> Self812 fn append(input: I, kind: ErrorKind, other: Self) -> Self { 813 ErrorStr(format!("custom error message: ({:?}, {:?}) - {:?}", input, kind, other)) 814 } 815 } 816 817 #[cfg(feature = "alloc")] 818 #[test] alt()819 fn alt() { 820 fn work(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { 821 Ok((&b""[..], input)) 822 } 823 824 #[allow(unused_variables)] 825 fn dont_work(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { 826 Err(Err::Error(ErrorStr("abcd".to_string()))) 827 } 828 829 fn work2(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { 830 Ok((input, &b""[..])) 831 } 832 833 fn alt1(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { 834 alt!(i, dont_work | dont_work) 835 } 836 fn alt2(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { 837 alt!(i, dont_work | work) 838 } 839 fn alt3(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { 840 alt!(i, dont_work | dont_work | work2 | dont_work) 841 } 842 //named!(alt1, alt!(dont_work | dont_work)); 843 //named!(alt2, alt!(dont_work | work)); 844 //named!(alt3, alt!(dont_work | dont_work | work2 | dont_work)); 845 846 let a = &b"abcd"[..]; 847 assert_eq!(alt1(a), Err(Err::Error(error_position!(a, ErrorKind::Alt)))); 848 assert_eq!(alt2(a), Ok((&b""[..], a))); 849 assert_eq!(alt3(a), Ok((a, &b""[..]))); 850 851 named!(alt4, alt!(tag!("abcd") | tag!("efgh"))); 852 let b = &b"efgh"[..]; 853 assert_eq!(alt4(a), Ok((&b""[..], a))); 854 assert_eq!(alt4(b), Ok((&b""[..], b))); 855 856 // test the alternative syntax 857 named!(alt5<bool>, alt!(tag!("abcd") => { |_| false } | tag!("efgh") => { |_| true })); 858 assert_eq!(alt5(a), Ok((&b""[..], false))); 859 assert_eq!(alt5(b), Ok((&b""[..], true))); 860 861 // compile-time test guarding against an underspecified E generic type (#474) 862 named!(alt_eof1, alt!(eof!() | eof!())); 863 named!(alt_eof2, alt!(eof!() => {|x| x} | eof!() => {|x| x})); 864 let _ = (alt_eof1, alt_eof2); 865 } 866 867 #[test] alt_incomplete()868 fn alt_incomplete() { 869 named!(alt1, alt!(tag!("a") | tag!("bc") | tag!("def"))); 870 871 let a = &b""[..]; 872 assert_eq!(alt1(a), Err(Err::Incomplete(Needed::Size(1)))); 873 let a = &b"b"[..]; 874 assert_eq!(alt1(a), Err(Err::Incomplete(Needed::Size(2)))); 875 let a = &b"bcd"[..]; 876 assert_eq!(alt1(a), Ok((&b"d"[..], &b"bc"[..]))); 877 let a = &b"cde"[..]; 878 assert_eq!(alt1(a), Err(Err::Error(error_position!(a, ErrorKind::Alt)))); 879 let a = &b"de"[..]; 880 assert_eq!(alt1(a), Err(Err::Incomplete(Needed::Size(3)))); 881 let a = &b"defg"[..]; 882 assert_eq!(alt1(a), Ok((&b"g"[..], &b"def"[..]))); 883 } 884 885 #[allow(unused_variables)] 886 #[test] switch()887 fn switch() { 888 named!( 889 sw, 890 switch!(take!(4), 891 b"abcd" | b"xxxx" => take!(2) | 892 b"efgh" => take!(4) 893 ) 894 ); 895 896 let a = &b"abcdefgh"[..]; 897 assert_eq!(sw(a), Ok((&b"gh"[..], &b"ef"[..]))); 898 899 let b = &b"efghijkl"[..]; 900 assert_eq!(sw(b), Ok((&b""[..], &b"ijkl"[..]))); 901 let c = &b"afghijkl"[..]; 902 assert_eq!(sw(c), Err(Err::Error(error_position!(&b"afghijkl"[..], ErrorKind::Switch)))); 903 904 let a = &b"xxxxefgh"[..]; 905 assert_eq!(sw(a), Ok((&b"gh"[..], &b"ef"[..]))); 906 } 907 908 #[test] permutation()909 fn permutation() { 910 named!(perm<(&[u8], &[u8], &[u8])>, permutation!(tag!("abcd"), tag!("efg"), tag!("hi"))); 911 912 let expected = (&b"abcd"[..], &b"efg"[..], &b"hi"[..]); 913 914 let a = &b"abcdefghijk"[..]; 915 assert_eq!(perm(a), Ok((&b"jk"[..], expected))); 916 let b = &b"efgabcdhijk"[..]; 917 assert_eq!(perm(b), Ok((&b"jk"[..], expected))); 918 let c = &b"hiefgabcdjk"[..]; 919 assert_eq!(perm(c), Ok((&b"jk"[..], expected))); 920 921 let d = &b"efgxyzabcdefghi"[..]; 922 assert_eq!( 923 perm(d), 924 Err(Err::Error(error_node_position!( 925 &b"efgxyzabcdefghi"[..], 926 ErrorKind::Permutation, 927 error_position!(&b"xyzabcdefghi"[..], ErrorKind::Permutation) 928 ))) 929 ); 930 931 let e = &b"efgabc"[..]; 932 assert_eq!(perm(e), Err(Err::Incomplete(Needed::Size(4)))); 933 } 934 935 /* 936 named!(does_not_compile, 937 alt!(tag!("abcd"), tag!("efgh")) 938 ); 939 */ 940 } 941