aoc-parse 0.2.18

A little library for parsing your Advent of Code puzzle input
Documentation
use aoc_parse::{parser, prelude::*};

#[test]
fn day7() {
    let input = "\
light red bags contain 1 bright white bag, 2 muted yellow bags.
dark orange bags contain 3 bright white bags, 4 muted yellow bags.
bright white bags contain 1 shiny gold bag.
muted yellow bags contain 2 shiny gold bags, 9 faded blue bags.
shiny gold bags contain 1 dark olive bag, 2 vibrant plum bags.
dark olive bags contain 3 faded blue bags, 4 dotted black bags.
vibrant plum bags contain 5 faded blue bags, 6 dotted black bags.
faded blue bags contain no other bags.
dotted black bags contain no other bags.
";

    #[derive(Debug, PartialEq)]
    struct Bags {
        count: usize,
        color: String,
    }

    #[derive(Debug, PartialEq)]
    struct Rule {
        color: String,
        contents: Vec<Bags>,
    }

    // This tests backtracking across parser boundaries (`color` will initially
    // match too many words every time it's used), function calls inside
    // `string()`, and label scoping (there are two labels `color:`).
    let color = parser!(string(repeat_sep(alpha+, ' ')));
    let p = parser!(lines(
        color:color
        " bags contain "
        contents:{
            "no other bags" => vec![],
            repeat_sep(
                count:usize ' ' color:color ' ' {"bag", "bags"} => Bags { count, color },
                ", "
            )
        }
        '.'
            => Rule { color, contents}
    ));

    fn bags(count: usize, color: &str) -> Bags {
        let color = color.to_string();
        Bags { count, color }
    }

    assert_eq!(
        p.parse(input).unwrap(),
        vec![
            Rule {
                color: "light red".to_string(),
                contents: vec![bags(1, "bright white"), bags(2, "muted yellow")],
            },
            Rule {
                color: "dark orange".to_string(),
                contents: vec![bags(3, "bright white"), bags(4, "muted yellow")],
            },
            Rule {
                color: "bright white".to_string(),
                contents: vec![bags(1, "shiny gold")],
            },
            Rule {
                color: "muted yellow".to_string(),
                contents: vec![bags(2, "shiny gold"), bags(9, "faded blue")],
            },
            Rule {
                color: "shiny gold".to_string(),
                contents: vec![bags(1, "dark olive"), bags(2, "vibrant plum")],
            },
            Rule {
                color: "dark olive".to_string(),
                contents: vec![bags(3, "faded blue"), bags(4, "dotted black")],
            },
            Rule {
                color: "vibrant plum".to_string(),
                contents: vec![bags(5, "faded blue"), bags(6, "dotted black")],
            },
            Rule {
                color: "faded blue".to_string(),
                contents: vec![],
            },
            Rule {
                color: "dotted black".to_string(),
                contents: vec![],
            },
        ],
    );
}