home ~ projects ~ socials

Parse Multiple Lines Of Input With nom In Rust

//! ```cargo
//! [dependencies]
//! nom = "7.1.3"
//! ```

use nom::branch::alt;
use nom::bytes::complete::is_not;
use nom::character::complete::line_ending;
use nom::character::complete::space1;
use nom::combinator::eof;
use nom::multi::many1;
use nom::multi::separated_list1;
use nom::sequence::terminated;
use nom::IResult;


fn main() {
  let input = "alfa bravo charlie
delta echo foxtrot golf
hotel india
juliette
. . #";
  let output = parse(input);
  dbg!(output.unwrap().1);
}


fn parse(source: &str) -> IResult<&str, Vec<Vec<&str>>> {
  let (source, results) = many1(terminated(line, alt((line_ending, eof))))(source)?;
  Ok((source, results))
}

fn line(source: &str) -> IResult<&str, Vec<&str>> {
  let (source, results) = separated_list1(space1, is_not(" \n\t"))(source)?;
  Ok((source, results))
}
Output:
[neopolitan_code_run:28] output.unwrap().1 = [
    [
        "alfa",
        "bravo",
        "charlie",
    ],
    [
        "delta",
        "echo",
        "foxtrot",
        "golf",
    ],
    [
        "hotel",
        "india",
    ],
    [
        "juliette",
    ],
    [
        ".",
        ".",
        "#",
    ],
]
-- end of line --