16855e09eSopenharmony_ciuse std::collections::HashMap; 26855e09eSopenharmony_ciuse std::iter::Iterator; 36855e09eSopenharmony_ci 46855e09eSopenharmony_ciuse nom::bytes::complete::tag; 56855e09eSopenharmony_ciuse nom::character::complete::alphanumeric1; 66855e09eSopenharmony_ciuse nom::combinator::iterator; 76855e09eSopenharmony_ciuse nom::sequence::{separated_pair, terminated}; 86855e09eSopenharmony_ciuse nom::IResult; 96855e09eSopenharmony_ci 106855e09eSopenharmony_cifn main() { 116855e09eSopenharmony_ci let mut data = "abcabcabcabc"; 126855e09eSopenharmony_ci 136855e09eSopenharmony_ci fn parser(i: &str) -> IResult<&str, &str> { 146855e09eSopenharmony_ci tag("abc")(i) 156855e09eSopenharmony_ci } 166855e09eSopenharmony_ci 176855e09eSopenharmony_ci // `from_fn` (available from Rust 1.34) can create an iterator 186855e09eSopenharmony_ci // from a closure 196855e09eSopenharmony_ci let it = std::iter::from_fn(move || { 206855e09eSopenharmony_ci match parser(data) { 216855e09eSopenharmony_ci // when successful, a nom parser returns a tuple of 226855e09eSopenharmony_ci // the remaining input and the output value. 236855e09eSopenharmony_ci // So we replace the captured input data with the 246855e09eSopenharmony_ci // remaining input, to be parsed on the next call 256855e09eSopenharmony_ci Ok((i, o)) => { 266855e09eSopenharmony_ci data = i; 276855e09eSopenharmony_ci Some(o) 286855e09eSopenharmony_ci } 296855e09eSopenharmony_ci _ => None, 306855e09eSopenharmony_ci } 316855e09eSopenharmony_ci }); 326855e09eSopenharmony_ci 336855e09eSopenharmony_ci for value in it { 346855e09eSopenharmony_ci println!("parser returned: {}", value); 356855e09eSopenharmony_ci } 366855e09eSopenharmony_ci 376855e09eSopenharmony_ci println!("\n********************\n"); 386855e09eSopenharmony_ci 396855e09eSopenharmony_ci let data = "abcabcabcabc"; 406855e09eSopenharmony_ci 416855e09eSopenharmony_ci // if `from_fn` is not available, it is possible to fold 426855e09eSopenharmony_ci // over an iterator of functions 436855e09eSopenharmony_ci let res = 446855e09eSopenharmony_ci std::iter::repeat(parser) 456855e09eSopenharmony_ci .take(3) 466855e09eSopenharmony_ci .try_fold((data, Vec::new()), |(data, mut acc), parser| { 476855e09eSopenharmony_ci parser(data).map(|(i, o)| { 486855e09eSopenharmony_ci acc.push(o); 496855e09eSopenharmony_ci (i, acc) 506855e09eSopenharmony_ci }) 516855e09eSopenharmony_ci }); 526855e09eSopenharmony_ci 536855e09eSopenharmony_ci // will print "parser iterator returned: Ok(("abc", ["abc", "abc", "abc"]))" 546855e09eSopenharmony_ci println!("\nparser iterator returned: {:?}", res); 556855e09eSopenharmony_ci 566855e09eSopenharmony_ci println!("\n********************\n"); 576855e09eSopenharmony_ci 586855e09eSopenharmony_ci let data = "key1:value1,key2:value2,key3:value3,;"; 596855e09eSopenharmony_ci 606855e09eSopenharmony_ci // `nom::combinator::iterator` will return an iterator 616855e09eSopenharmony_ci // producing the parsed values. Compared to the previous 626855e09eSopenharmony_ci // solutions: 636855e09eSopenharmony_ci // - we can work with a normal iterator like `from_fn` 646855e09eSopenharmony_ci // - we can get the remaining input afterwards, like with the `try_fold` trick 656855e09eSopenharmony_ci let mut nom_it = iterator( 666855e09eSopenharmony_ci data, 676855e09eSopenharmony_ci terminated( 686855e09eSopenharmony_ci separated_pair(alphanumeric1, tag(":"), alphanumeric1), 696855e09eSopenharmony_ci tag(","), 706855e09eSopenharmony_ci ), 716855e09eSopenharmony_ci ); 726855e09eSopenharmony_ci 736855e09eSopenharmony_ci let res = nom_it 746855e09eSopenharmony_ci .map(|(k, v)| (k.to_uppercase(), v)) 756855e09eSopenharmony_ci .collect::<HashMap<_, _>>(); 766855e09eSopenharmony_ci 776855e09eSopenharmony_ci let parser_result: IResult<_, _> = nom_it.finish(); 786855e09eSopenharmony_ci let (remaining_input, ()) = parser_result.unwrap(); 796855e09eSopenharmony_ci 806855e09eSopenharmony_ci // will print "iterator returned {"key1": "value1", "key3": "value3", "key2": "value2"}, remaining input is ';'" 816855e09eSopenharmony_ci println!( 826855e09eSopenharmony_ci "iterator returned {:?}, remaining input is '{}'", 836855e09eSopenharmony_ci res, remaining_input 846855e09eSopenharmony_ci ); 856855e09eSopenharmony_ci} 86