The words Under construction in black text on a yellow background with diagonal black stipes surrounding it
I'm in the process of moving my site. It's still a work in progress. Please excuse the mess and broken links.

Don't Use "rest" With "many1" In Rust's nom Parsing Crate

TODO: Pull subtitle into page object

I'm still working to figure this out...

This one works.

Code
#![allow(unused_imports)]
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::bytes::complete::take_until;
use nom::character::complete::multispace0;
use nom::combinator::rest;
use nom::multi::many1;
use nom::sequence::terminated;
use nom::IResult;

#[derive(Debug)]
enum Section {
    Alfa,
    Bravo,
}

fn main() {
    let source = "-- alfa\n\n-- bravo";
    dbg!(sections(source).unwrap());
}

fn sections(source: &str) -> IResult<&str, Vec<Section>> {
    let (source, sections) = many1(alt((alfa, bravo)))(source)?;
    Ok((source, sections))
}

fn alfa(source: &str) -> IResult<&str, Section> {
    let (source, _section) = tag("-- alfa")(source)?;
    let (source, data) = terminated(take_until("\n\n"), tag("\n\n"))(source)?;
    Ok((source, Section::Alfa))
}

fn bravo(source: &str) -> IResult<&str, Section> {
    let (source, _section) = tag("-- bravo")(source)?;
    let (source, data) = alt((terminated(take_until("\n\n"), tag("\n\n")), rest))(source)?;
    Ok((source, Section::Bravo))
}

Earlier notes about what wasn't working

Need to do a little more verification, but I think part of the problems I've been running into with nom and the `many`` functions is because I was pulling in content below them with `rest``. The way `many1`` and `many0`` work is that the stop processing when they hit an error. By using `rest`` to slurp the rest of the content that wasn't happening.

This is some code where I figured that out

Code
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::bytes::complete::take_until;
use nom::character::complete::multispace0;
use nom::combinator::rest;
use nom::multi::many1;
use nom::sequence::terminated;
use nom::IResult;

fn main() {
    let source = "alfa bravo\n\ncharlie delta\n\necho foxtrot";
    dbg!(this_works(&source).unwrap());
    dbg!(this_fails(&source).unwrap());
}

fn this_works(source: &str) -> IResult<&str, Vec<&str>> {
    let (source, x) = many1(this_works_part_2)(source)?;
    Ok((source, x))
}

fn this_works_part_2(source: &str) -> IResult<&str, &str> {
    let (source, _) = multispace0(source)?;
    let (source, captured) = terminated(take_until("\n\n"), tag("\n\n"))(source)?;
    Ok((source, captured))
}

fn this_fails(source: &str) -> IResult<&str, Vec<&str>> {
    let (source, x) = many1(this_fails_part_2)(source)?;
    Ok((source, x))
}

fn this_fails_part_2(source: &str) -> IResult<&str, &str> {
    let (source, _) = multispace0(source)?;
    let (source, captured) = alt((terminated(take_until("\n\n"), tag("\n\n")), rest))(source)?;
    Ok((source, captured))
}

Notes

Debugging Stuff

I'm moving stuff around right now. All this below is helping me figure out where to put stuff

        -- title

Don't Use "rest" With "many1" In Rust's nom Parsing Crate

-- note

I'm still working to figure this out...

This one works. 

-- code
-- rust


#![allow(unused_imports)]
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::bytes::complete::take_until;
use nom::character::complete::multispace0;
use nom::combinator::rest;
use nom::multi::many1;
use nom::sequence::terminated;
use nom::IResult;

#[derive(Debug)]
enum Section {
    Alfa,
    Bravo,
}

fn main() {
    let source = "-- alfa\n\n-- bravo";
    dbg!(sections(source).unwrap());
}

fn sections(source: &str) -> IResult<&str, Vec<Section>> {
    let (source, sections) = many1(alt((alfa, bravo)))(source)?;
    Ok((source, sections))
}

fn alfa(source: &str) -> IResult<&str, Section> {
    let (source, _section) = tag("-- alfa")(source)?;
    let (source, data) = terminated(take_until("\n\n"), tag("\n\n"))(source)?;
    Ok((source, Section::Alfa))
}

fn bravo(source: &str) -> IResult<&str, Section> {
    let (source, _section) = tag("-- bravo")(source)?;
    let (source, data) = alt((terminated(take_until("\n\n"), tag("\n\n")), rest))(source)?;
    Ok((source, Section::Bravo))
}


-- h3

Earlier notes about what wasn't working


Need to do a little more verification, but I think part
of the problems I've been running into with nom and the `many``
functions is because I was pulling in content below them 
with `rest``. The way `many1`` and `many0`` work is that the
stop processing when they hit an error. By using `rest``
to slurp the rest of the content that wasn't happening. 

This is some code where I figured that out

-- code
-- rust

use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::bytes::complete::take_until;
use nom::character::complete::multispace0;
use nom::combinator::rest;
use nom::multi::many1;
use nom::sequence::terminated;
use nom::IResult;

fn main() {
    let source = "alfa bravo\n\ncharlie delta\n\necho foxtrot";
    dbg!(this_works(&source).unwrap());
    dbg!(this_fails(&source).unwrap());
}

fn this_works(source: &str) -> IResult<&str, Vec<&str>> {
    let (source, x) = many1(this_works_part_2)(source)?;
    Ok((source, x))
}

fn this_works_part_2(source: &str) -> IResult<&str, &str> {
    let (source, _) = multispace0(source)?;
    let (source, captured) = terminated(take_until("\n\n"), tag("\n\n"))(source)?;
    Ok((source, captured))
}

fn this_fails(source: &str) -> IResult<&str, Vec<&str>> {
    let (source, x) = many1(this_fails_part_2)(source)?;
    Ok((source, x))
}

fn this_fails_part_2(source: &str) -> IResult<&str, &str> {
    let (source, _) = multispace0(source)?;
    let (source, captured) = alt((terminated(take_until("\n\n"), tag("\n\n")), rest))(source)?;
    Ok((source, captured))
}


-- notes

- I don't know if `rest`` always returns true or not, but it
certinaly seems like it might. 


-- ref
-- url: https://docs.rs/nom/latest/nom/combinator/fn.rest.html

-- ref
-- url: https://docs.rs/nom/latest/nom/multi/fn.many1.html

-- ref
-- url: https://docs.rs/nom/latest/nom/multi/fn.many0.html



-- categories
-- Rust 
-- nom 

-- metadata
-- date: 2023-07-19 20:03:31
-- id: 2sosoyfv
-- site: aws
-- type: post
-- status: draft