tinyrs 0.2.0

Parse Tiny format mappings in Rust.
Documentation
use crate::identifier;
use nom::{
    branch::alt,
    character::complete::char,
    combinator::{map, value},
    error::{context, ParseError},
    multi::many1_count,
    sequence::{pair, preceded, terminated},
    IResult,
};
use serde::{Deserialize, Serialize};

pub type DimensionSize = usize;

#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum JavaType {
    Void,
    Char,
    Byte,
    Short,
    Int,
    Long,
    Boolean,
    Float,
    Double,
    Class(String),
    Array(DimensionSize, Box<JavaType>),
}

fn dataless<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, JavaType, E> {
    context(
        "dataless",
        alt((
            value(JavaType::Void, char('V')),
            value(JavaType::Char, char('C')),
            value(JavaType::Byte, char('B')),
            value(JavaType::Short, char('S')),
            value(JavaType::Int, char('I')),
            value(JavaType::Long, char('J')),
            value(JavaType::Boolean, char('Z')),
            value(JavaType::Float, char('F')),
            value(JavaType::Double, char('D')),
        )),
    )(input)
}

fn class<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, JavaType, E> {
    context(
        "class",
        map(
            preceded(char('L'), terminated(identifier, char(';'))),
            |name: &str| JavaType::Class(name.into()),
        ),
    )(input)
}

fn array<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, JavaType, E> {
    context(
        "array",
        map(
            pair(many1_count(char('[')), parse_java_type),
            |(dim, java)| JavaType::Array(dim, Box::new(java)),
        ),
    )(input)
}

pub fn parse_java_type<'a, E: ParseError<&'a str>>(
    input: &'a str,
) -> IResult<&'a str, JavaType, E> {
    alt((dataless, class, array))(input)
}