localize_it 2.5.1

Simple and fast library for localization
Documentation
use crate::utils::{errors::unknown_argument_error, typed_parse::TypedParse};
use proc_macro2::{Ident, Span};
use syn::{
    parse::{Parse, ParseStream}, Error, LitStr, Path, Result,
    Token,
};

pub struct Arguments {
    pub variants: Vec<Ident>,
    pub variants_label: Vec<LitStr>,
    pub storage: bool,
    pub path: Option<Path>,
    pub default: Ident,
    pub derive: Vec<Path>,
}

impl Parse for Arguments {
    fn parse(input: ParseStream) -> Result<Self> {
        let mut variants = Vec::new();
        let mut variants_label = Vec::new();
        let mut storage = false;
        let mut path = None;
        let mut default = None;
        let mut derive = Vec::new();

        let mut variants_is_end = false;
        input.parse_arguments(|argument, processor| {
            if input.peek(Token![=]) && !input.peek(Token![=>]) {
                input.parse::<Token![=]>()?;

                match processor.process(&argument)?.as_str() {
                    "storage" => storage = input.parse_bool("storage")?,
                    "path" => path = Some(input.parse_path("path")?),
                    "default" => default = Some(input.parse_ident("default")?),
                    "derive" => derive = input.parse_array("derive", Path::parse)?,
                    _ => return Err(unknown_argument_error(argument)),
                }

                variants_is_end = true;
            } else if variants_is_end {
                return Err(Error::new(
                    argument.span(),
                    "Expected variants list to precede optional arguments",
                ));
            } else {
                let label = if input.peek(Token![=>]) {
                    input.parse::<Token![=>]>()?;

                    input.parse()?
                } else {
                    LitStr::new(&argument.to_string(), argument.span())
                };

                variants.push(argument);
                variants_label.push(label);
            }

            Ok(())
        })?;

        let default = default.unwrap_or(
            variants
                .first()
                .ok_or(Error::new(
                    Span::call_site(),
                    "Expected at least one locale variant",
                ))?
                .clone(),
        );

        Ok(Self {
            variants,
            variants_label,
            storage,
            path,
            default,
            derive,
        })
    }
}