diff --git a/src/main.rs b/src/main.rs index e7a11a9..bac9a74 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,56 @@ -fn main() { - println!("Hello, world!"); +use nom::{ + IResult, Parser, + branch::permutation, + bytes::take_until, + character::{char, complete::multispace1}, + error::{FromExternalError, ParseError}, + multi::{fold, many_m_n}, + sequence::{delimited, preceded}, +}; + +enum Fragment<'a> { + Literal(&'a str), + Header(&'a str), +} + +fn main() { + let input = concat!( + "Hallo daar!\n", + "Hoe gaat het?\n", + "# Met mij gaat het goed\n", + "Met jou\n", + "## Ja ook goed\n", + "Echt?\n", + "### Wow (not matched because we only accept 1 or 2 '#')\n", + "#StartOfFileHeaderNoSpace <-- not matched because we require a space after '#'\n", + " ## Indented header\n" + ); + + let x = parse_string::<()>(input).unwrap(); + println!("{:?}", x); +} + +fn parse_string<'a, E>(input: &'a str) -> IResult<&'a str, String, E> +where + E: ParseError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>, +{ + fold(0.., parse_header, String::new, |mut string, newstr| { + string.push_str(newstr); + string + }) + .parse(input) +} +fn parse_fragment<'a, E>(input: &'a str) -> IResult<&'a str, StringFragment<'a>, E> +where + E: ParseError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>, +{ + alt((map(parse_header, Fragment::Header))) +} + +fn parse_header<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, &'a str, E> { + preceded( + permutation((char('\n'), many_m_n(1, 2, char('#')))), + take_until("\n"), + ) + .parse(input) }