I have the following data
let data = r#"title1
title1 line1
title1 line2
sep/
title2
title2 line1
title2 line2
title2 line3
sep/
title3
title3 line1
sep/"#;
Basically it represents three entries:
struct Entry {
title: String,
body: String,
}
Each entry has a title and a body. The title consumes a single line (not including the line ending) and the body consumes all the following lines until it met separator line (sep/
). The result I want is a vector of Entries. How can I use nom to parse it? I'm very new to nom and I can't make the pieces work together and form a working parser. Below is what I have:
use nom::IResult;
use nom::branch::alt;
use nom::bytes::complete::{tag, take_until, is_not, is_a};
use nom::error::ErrorKind::ParseTo;
use nom::sequence::{pair, tuple, delimited, terminated};
use nom::combinator::opt;
use nom::error::{Error, ErrorKind};
use nom::character::complete::line_ending;
use nom::regexp::str::{re_find, re_match, re_matches, re_capture};
use nom::multi::many0;
struct Entry {
title: String,
body: String,
}
fn get_entry_title(i: &str) -> IResult<&str, &str> {
delimited(tag(""),
take_until(alt((
tag("\r\n"),
tag("\n")
))),
alt((
tag("\r\n"),
tag("\n")
))
)(i)
}
fn get_entry_body(i: &str) -> IResult<&str, &str> {
terminated(
take_until( tag("sep/")),
tag("sep/")
)(i)
}
fn main() {
let data = r#"title1
title1 line1
title1 line2
sep/
title2
title2 line1
title2 line2
title2 line3
sep/
title3
title3 line1
sep/"#;
let result = get_entry_title(&data);
}
Here is a nom-only approach (nom 6.1.2):