mshio 0.4.2

Parser for the Gmsh MSH file format version 4.1
Documentation
use nom::IResult;

use crate::error::MshParserError;
use crate::mshfile::{MshFloatT, MshIntT, MshUsizeT};
use crate::parsers::num_parsers::{construct_usize_parser, NumParsers};

pub(crate) trait ParsesSizeT<U: MshUsizeT> {
    fn parse_size_t<'a>(&self, i: &'a [u8]) -> IResult<&'a [u8], U, MshParserError<&'a [u8]>>;
    fn parse_to_usize<'a>(&self, i: &'a [u8])
        -> IResult<&'a [u8], usize, MshParserError<&'a [u8]>>;
}

pub(crate) trait ParsesInt<I: MshIntT> {
    fn parse_int<'a>(&self, i: &'a [u8]) -> IResult<&'a [u8], I, MshParserError<&'a [u8]>>;
}

pub(crate) trait ParsesFloat<F: MshFloatT> {
    fn parse_float<'a>(&self, i: &'a [u8]) -> IResult<&'a [u8], F, MshParserError<&'a [u8]>>;
}

impl<U: MshUsizeT, T> ParsesSizeT<U> for &T
where
    T: ParsesSizeT<U>,
{
    #[inline(always)]
    fn parse_size_t<'a>(&self, i: &'a [u8]) -> IResult<&'a [u8], U, MshParserError<&'a [u8]>> {
        (*self).parse_size_t(i)
    }

    #[inline(always)]
    fn parse_to_usize<'a>(
        &self,
        i: &'a [u8],
    ) -> IResult<&'a [u8], usize, MshParserError<&'a [u8]>> {
        (*self).parse_to_usize(i)
    }
}

impl<I: MshIntT, T> ParsesInt<I> for &T
where
    T: ParsesInt<I>,
{
    #[inline(always)]
    fn parse_int<'a>(&self, i: &'a [u8]) -> IResult<&'a [u8], I, MshParserError<&'a [u8]>> {
        (*self).parse_int(i)
    }
}

impl<F: MshFloatT, T> ParsesFloat<F> for &T
where
    T: ParsesFloat<F>,
{
    #[inline(always)]
    fn parse_float<'a>(&self, i: &'a [u8]) -> IResult<&'a [u8], F, MshParserError<&'a [u8]>> {
        (*self).parse_float(i)
    }
}

impl<U: MshUsizeT, I: MshIntT, F: MshFloatT, SizeTParser, IntParser, FloatParser> ParsesSizeT<U>
    for NumParsers<U, I, F, SizeTParser, IntParser, FloatParser>
where
    for<'a> SizeTParser: Fn(&'a [u8]) -> IResult<&'a [u8], U, MshParserError<&'a [u8]>>,
    for<'a> IntParser: Fn(&'a [u8]) -> IResult<&'a [u8], I, MshParserError<&'a [u8]>>,
    for<'a> FloatParser: Fn(&'a [u8]) -> IResult<&'a [u8], F, MshParserError<&'a [u8]>>,
{
    fn parse_size_t<'a>(&self, input: &'a [u8]) -> IResult<&'a [u8], U, MshParserError<&'a [u8]>> {
        (self.size_t_parser)(input)
    }

    fn parse_to_usize<'a>(
        &self,
        input: &'a [u8],
    ) -> IResult<&'a [u8], usize, MshParserError<&'a [u8]>> {
        construct_usize_parser(&self.size_t_parser)(input)
    }
}

impl<U: MshUsizeT, I: MshIntT, F: MshFloatT, SizeTParser, IntParser, FloatParser> ParsesInt<I>
    for NumParsers<U, I, F, SizeTParser, IntParser, FloatParser>
where
    for<'a> SizeTParser: Fn(&'a [u8]) -> IResult<&'a [u8], U, MshParserError<&'a [u8]>>,
    for<'a> IntParser: Fn(&'a [u8]) -> IResult<&'a [u8], I, MshParserError<&'a [u8]>>,
    for<'a> FloatParser: Fn(&'a [u8]) -> IResult<&'a [u8], F, MshParserError<&'a [u8]>>,
{
    fn parse_int<'a>(&self, input: &'a [u8]) -> IResult<&'a [u8], I, MshParserError<&'a [u8]>> {
        (self.int_parser)(input)
    }
}

impl<U: MshUsizeT, I: MshIntT, F: MshFloatT, SizeTParser, IntParser, FloatParser> ParsesFloat<F>
    for NumParsers<U, I, F, SizeTParser, IntParser, FloatParser>
where
    for<'a> SizeTParser: Fn(&'a [u8]) -> IResult<&'a [u8], U, MshParserError<&'a [u8]>>,
    for<'a> IntParser: Fn(&'a [u8]) -> IResult<&'a [u8], I, MshParserError<&'a [u8]>>,
    for<'a> FloatParser: Fn(&'a [u8]) -> IResult<&'a [u8], F, MshParserError<&'a [u8]>>,
{
    fn parse_float<'a>(&self, input: &'a [u8]) -> IResult<&'a [u8], F, MshParserError<&'a [u8]>> {
        (self.float_parser)(input)
    }
}

#[inline(always)]
pub(crate) fn size_t_parser<'a, U: MshUsizeT, P: ParsesSizeT<U> + 'a>(
    parser: P,
) -> impl for<'b> Fn(&'b [u8]) -> IResult<&'b [u8], U, MshParserError<&'b [u8]>> + 'a {
    move |i| parser.parse_size_t(i)
}

#[inline(always)]
pub(crate) fn usize_parser<'a, U: MshUsizeT, P: ParsesSizeT<U> + 'a>(
    parser: P,
) -> impl for<'b> Fn(&'b [u8]) -> IResult<&'b [u8], usize, MshParserError<&'b [u8]>> + 'a {
    move |i| parser.parse_to_usize(i)
}

#[inline(always)]
pub(crate) fn int_parser<'a, I: MshIntT, P: ParsesInt<I> + 'a>(
    parser: P,
) -> impl for<'b> Fn(&'b [u8]) -> IResult<&'b [u8], I, MshParserError<&'b [u8]>> + 'a {
    move |i| parser.parse_int(i)
}

#[inline(always)]
pub(crate) fn float_parser<'a, F: MshFloatT, P: ParsesFloat<F> + 'a>(
    parser: P,
) -> impl for<'b> Fn(&'b [u8]) -> IResult<&'b [u8], F, MshParserError<&'b [u8]>> + 'a {
    move |i| parser.parse_float(i)
}