ninja-build-syntax 0.0.2

Parser for ninja's manifest file format, i.e. `ninja.build` files.
Documentation
use std::result;

use bstr::ByteSlice as _;

type Error<'a> = nom::Err<(&'a [u8], nom::error::ErrorKind)>;
type Result<'a, T> = result::Result<(&'a [u8], T), Error<'a>>;

pub fn test_parse_impl<T: PartialEq<T> + ::std::fmt::Debug>(
    expected_result: T,
    expected_rest: &[u8],
    parse_input: &[u8],
    actual_iresult: Result<T>,
    parse_function_name: &str,
    filename: &str,
    line: u32,
) {
    match actual_iresult {
        Ok((ref actual_rest, ref actual_result))
            if *actual_rest == expected_rest && *actual_result == expected_result => {}
        Ok((actual_rest, actual_result)) => {
            panic!(
                r#"
{}:{}: Parsing failed:
    input:         {:?}
    function:      {}
    expected:      {:?}
    expected rest: {:?}
    actual:        {:?}
    actual_rest:   {:?}
"#,
                filename,
                line,
                parse_input.as_bstr(),
                parse_function_name,
                expected_result,
                expected_rest.as_bstr(),
                actual_result,
                actual_rest.as_bstr(),
            );
        }
        Err(error) => {
            panic!(
                r#"
{}:{}: Parsing failed:
    input:         {:?}
    function:      {}
    error:         {:?}
"#,
                filename,
                line,
                parse_input.as_bstr(),
                parse_function_name,
                error,
            );
        }
    }
}

#[macro_export]
macro_rules! test_parse {
    ($parse_function:ident($parse_input:expr), $expected_result:expr) => {
        test_parse!($parse_function($parse_input), $expected_result, b"")
    };
    ($parse_function:ident($parse_input:expr), $expected_result:expr, $rest:expr) => {
        $crate::parsers::test_macros::test_parse_impl(
            $expected_result,
            &$rest[..],
            &$parse_input[..],
            $parse_function(&$parse_input[..]),
            stringify!($parse_function),
            file!(),
            line!(),
        );
    };
}
macro_rules! test_parse_error {
    ($parse_function:ident($parse_input:expr)) => {
        match $parse_function(&$parse_input[..]) {
            Err(nom::Err::Error(_)) | Err(nom::Err::Failure(_)) => (),
            x => panic!(
                "expected {}({:?}) to return Error but got {:?}",
                stringify!($parse_function),
                &$parse_input[..],
                x
            ),
        }
    };
}

macro_rules! value {
    ( $( $item:expr ),* ) => {
        Value(vec![ $( $item ),* ])
    };
    ( $( $item:expr ),* , ) => {
        value![ $( $item ),* ]
    };
}

macro_rules! plain {
    ($value:expr) => {
        $crate::parsers::ValuePiece::Plain(&$value[..])
    };
}

macro_rules! reference {
    ($value:expr) => {
        $crate::parsers::ValuePiece::Reference(&$value[..])
    };
}

macro_rules! id {
    ($s:expr) => {
        Identifier(&$s[..])
    };
}