EnumBitFlags 1.0.11

EnumBitFlags is an implementation of flags support for enums
Documentation
use super::flags_type::FlagsType;
use super::utils;
use proc_macro::*;

enum State {
    ExpectKey,
    ExpectEqual,
    ExpectValue,
    ExpectComma,
}
pub struct Arguments {
    pub flags_type: FlagsType,
    pub none_case: String,
    pub has_empty_value: bool,
    pub disable_empty_generation: bool,
    pub debug_mode: bool,
    state: State,
    key: String,
    value: String,
}

impl Arguments {
    pub fn new() -> Arguments {
        Arguments {
            flags_type: FlagsType::U32,
            none_case: String::from("None"),
            state: State::ExpectKey,
            key: String::new(),
            value: String::new(),
            has_empty_value: false,
            disable_empty_generation: false,
            debug_mode: false,
        }
    }
    fn validate_bits_attribute(&mut self) {
        match self.value.as_str() {
            "8" => self.flags_type = FlagsType::U8,
            "16" => self.flags_type = FlagsType::U16,
            "32" => self.flags_type = FlagsType::U32,
            "64" => self.flags_type = FlagsType::U64,
            "128" => self.flags_type = FlagsType::U128,
            _ => {
                panic!("The value for `bits` attribute can be 8,16,32,64 or 128. Provided value was: {}",self.value.as_str());
            }
        }
    }
    fn validate_empty_attribute(&mut self) {
        if !utils::validate_enum_variant_name(self.value.as_str()) {
            panic!("Invalid name for the empty case. A valid name should contains letters, numbers or underline and must not start with a number.");
        }
        self.none_case.clear();
        self.none_case.push_str(self.value.as_str());
        self.has_empty_value = true;
    }
    fn string_to_bool(text: &str) -> Option<bool> {
        match text {
            "true" | "yes" => {
                return Some(true);
            }
            "false" | "no" => {
                return Some(false);
            }
            _ => {
                return None;
            }
        }
    }
    fn validate_noempty_attribute(&mut self) {
        if let Some(value) = Arguments::string_to_bool(self.value.as_str()) {
            self.disable_empty_generation = value;
        } else {
            panic!("The value for `disable_empty_generation` attribute can only be 'true' or 'false'. Provided value was: {}",self.value.as_str());
        }
    }
    fn validate_debug_attribute(&mut self) {
        if let Some(value) = Arguments::string_to_bool(self.value.as_str()) {
            self.debug_mode = value;
        } else {
            panic!("The value for `debug` attribute can only be 'true' or 'false'. Provided value was: {}",self.value.as_str());
        }
    }

    fn validate_key_value_pair(&mut self) {
        match self.key.as_str() {
            "bits" => self.validate_bits_attribute(),
            "empty" => self.validate_empty_attribute(),
            "disable_empty_generation" => self.validate_noempty_attribute(),
            "debug" => self.validate_debug_attribute(),
            _ => {
                panic!("Unknown attribute `{}` for EnumBitFlags. Accepted attributes are 'bits' , 'empty' and 'disable_empty_generation' !",self.key.as_str());
            }
        }
    }
    fn validate_expect_key(&mut self, token: TokenTree) {
        if let TokenTree::Ident(ident) = token {
            self.key = ident.to_string();
            self.state = State::ExpectEqual;
        } else {
            panic!(
                "Expecting a key (a-zA-Z0-9) but got: `{}`",
                token.to_string()
            );
        }
    }
    fn validate_expect_equal(&mut self, token: TokenTree) {
        if let TokenTree::Punct(punctuation) = token {
            if (punctuation.as_char() != '=') && (punctuation.as_char() != ':') {
                panic!(
                    "Expecting asignamne ('=' or ':') symbol but got: {}",
                    punctuation.as_char()
                );
            }
            self.state = State::ExpectValue;
        } else {
            panic!(
                "Expecting asignamne ('=' or ':') symbol but got: {}",
                token.to_string()
            );
        }
    }
    fn validate_expect_value(&mut self, token: TokenTree) {
        if let TokenTree::Ident(ident) = token {
            self.value = ident.to_string();
            self.state = State::ExpectComma;
        } else if let TokenTree::Literal(literal) = token {
            self.value = literal.to_string();
            self.state = State::ExpectComma;
        } else {
            panic!(
                "Expecting a value (a-zA-Z0-9) but got: `{}`",
                token.to_string()
            );
        }
        self.validate_key_value_pair();
    }
    fn validate_expect_comma(&mut self, token: TokenTree) {
        if let TokenTree::Punct(punctuation) = token {
            if punctuation.as_char() != ',' {
                panic!(
                    "Expecting delimiter (',' comma) symbol but got: {}",
                    punctuation.as_char()
                );
            }
            self.state = State::ExpectKey;
        } else {
            panic!(
                "Expecting delimiter (',' comma) symbol but got:{}",
                token.to_string()
            );
        }
    }
    pub fn parse(&mut self, input: TokenStream) {
        for token in input.into_iter() {
            // println!("arg_token: {:?}", token);
            match self.state {
                State::ExpectKey => self.validate_expect_key(token),
                State::ExpectEqual => self.validate_expect_equal(token),
                State::ExpectValue => self.validate_expect_value(token),
                State::ExpectComma => self.validate_expect_comma(token),
            }
        }
    }
}