glue 0.8.7

Glue is a parser combinator framework for parsing text based formats, it is easy to use and relatively fast too.
Documentation
use crate::prelude::*;

include!("struct-definition.rs");
include!("line-breaks.rs");

#[test]
fn line_break_parsers() {
    assert_eq!(line_break().parse((), "\n"), Ok(((), Ini::LineBreak, "")));
    assert_eq!(line_break().parse((), "\n\n"), Ok(((), Ini::LineBreak, "\n")));
}

include!("bad-line-spaces.rs");

#[test]
fn bad_line_space_parses() {
    assert_eq!(bad_line_space().parse((), " "), Ok(((), " ", "")));
    assert_eq!(bad_line_space().parse((), "\n"), Ok(((), "", "\n")));
}

include!("line-spaces.rs");

#[test]
fn line_space_parses() {
    assert_eq!(line_space().parse((), " "), Ok(((), " ", "")));
    assert_eq!(line_space().parse((), "\n"), Ok(((), "", "\n")));
}

include!("comments.rs");

#[test]
fn comment_parses() {
    assert_eq!(comment().parse((), ";"), Ok(((), Ini::Comment("".into()), "")));
    assert_eq!(
        comment().parse((), ";foobar\n"),
        Ok(((), Ini::Comment("foobar".into()), "\n"))
    );
}

include!("name-characters.rs");
include!("names.rs");

#[test]
fn name_parses() {
    assert_eq!(name().parse((), "foobar"), Ok(((), "foobar", "")));
    assert_eq!(name().parse((), "foobar "), Ok(((), "foobar", " ")));
    assert_eq!(name().parse((), "foobar;"), Ok(((), "foobar", ";")));
    assert_eq!(name().parse((), "foobar="), Ok(((), "foobar", "=")));
}

include!("separators.rs");

#[test]
fn separator_parses() {
    assert_eq!(separator().parse((), "="), Ok(((), "=", "")));
    assert_eq!(separator().parse((), " ="), Ok(((), " =", "")));
    assert_eq!(separator().parse((), "= "), Ok(((), "= ", "")));
    assert_eq!(separator().parse((), " = "), Ok(((), " = ", "")));
    assert_eq!(separator().parse((), "  =  "), Ok(((), "  =  ", "")));
}

include!("values.rs");

#[test]
fn value_parses() {
    assert_eq!(
        value().parse((), "foobar"),
        Ok(((), Ini::Value("foobar".into()), ""))
    );
    assert_eq!(
        value().parse((), "many words"),
        Ok(((), Ini::Value("many words".into()), ""))
    );
    assert_eq!(
        value().parse((), "foobar; not comments"),
        Ok(((), Ini::Value("foobar".into()), "; not comments"))
    );
    assert_eq!(
        value().parse((), "foobar\nnot line breaks"),
        Ok(((), Ini::Value("foobar".into()), "\nnot line breaks"))
    );
}

include!("properties.rs");

#[test]
fn property_parses() {
    assert_eq!(
        property().parse((), "foo=bar"),
        Ok((
            (),
            Ini::Property("foo".into(), vec![Ini::Value("bar".into())]),
            ""
        ))
    );
    assert_eq!(
        property().parse((), "foo = bar"),
        Ok((
            (),
            Ini::Property("foo".into(), vec![Ini::Value("bar".into())]),
            ""
        ))
    );
    assert_eq!(
        property().parse((), "foo = ;bar"),
        Ok((
            (),
            Ini::Property("foo".into(), vec![Ini::Comment("bar".into())]),
            ""
        ))
    );
}

include!("items.rs");

#[test]
fn items_parses() {
    assert_eq!(
        items().parse((), "foo=bar"),
        Ok((
            (),
            vec![Ini::Property("foo".into(), vec![Ini::Value("bar".into())])],
            ""
        ))
    );
}

include!("sections.rs");

#[test]
fn section_parses() {
    assert_eq!(
        section().parse((), "[abc]foo=bar"),
        Ok((
            (),
            Ini::Section(
                "abc".into(),
                vec![Ini::Property("foo".into(), vec![Ini::Value("bar".into())])]
            ),
            ""
        ))
    );
}

include!("documents.rs");

#[test]
fn document_parses() {
    assert_eq!(
        document().parse((), "[abc]foo=bar"),
        Ok((
            (),
            vec![Ini::Section(
                "abc".into(),
                vec![Ini::Property("foo".into(), vec![Ini::Value("bar".into())])],
            ),],
            ""
        ))
    );
}

#[allow(dead_code)]
fn main() {
    println!("{:#?}", document().parse((), include_str!("example.ini")));
}

mod filtered {
    use super::*;

    include!("filter-items.rs");
    include!("sections-filtered.rs");

    #[test]
    fn section_parses() {
        assert_eq!(
            section().parse((), "[abc]foo=bar"),
            Ok((
                (),
                Ini::Section(
                    "abc".into(),
                    vec![Ini::Property("foo".into(), vec![Ini::Value("bar".into())])]
                ),
                ""
            ))
        );
    }

    include!("documents-filtered.rs");

    #[test]
    fn document_parses() {
        assert_eq!(
            document().parse((), "[abc]foo=bar"),
            Ok((
                (),
                vec![Ini::Section(
                    "abc".into(),
                    vec![Ini::Property("foo".into(), vec![Ini::Value("bar".into())])],
                ),],
                ""
            ))
        );
    }
}