proc-macro-regex 1.1.0

A proc macro regex library
Documentation
use proc_macro2::Span;
use syn::{
    parse::{Parse, ParseStream, Result as ParseResult},
    spanned::Spanned,
    Ident, LitByteStr, LitInt, LitStr, Visibility,
};

const DEFAULT_LIMIT: usize = 65536;

pub enum Regex {
    LitStr(LitStr),
    LitByteStr(LitByteStr),
}

impl Regex {
    fn is_str(&self) -> bool {
        match self {
            Regex::LitStr(_) => true,
            Regex::LitByteStr(_) => false,
        }
    }

    fn get_regex(&self) -> String {
        match self {
            Regex::LitStr(lit_str) => lit_str.value(),
            Regex::LitByteStr(lit_byte_str) => {
                let bytes = lit_byte_str.value();
                String::from_utf8(bytes).unwrap()
            }
        }
    }
}

impl Parse for Regex {
    fn parse(input: ParseStream) -> ParseResult<Self> {
        let lookahead = input.lookahead1();
        let result = if lookahead.peek(LitStr) {
            Regex::LitStr(input.parse()?)
        } else {
            Regex::LitByteStr(input.parse()?)
        };
        Ok(result)
    }
}

impl Spanned for Regex {
    fn span(&self) -> proc_macro2::Span {
        match self {
            Regex::LitStr(lit_str) => lit_str.span(),
            Regex::LitByteStr(lit_byte_str) => lit_byte_str.span(),
        }
    }
}

pub struct MacroInput {
    visibility: Visibility,
    name: Ident,
    regex: Regex,
    threshold: usize,
}

impl Parse for MacroInput {
    fn parse(input: ParseStream) -> ParseResult<Self> {
        let visibility: Visibility = input.parse()?;
        let name: Ident = input.parse()?;
        let regex = input.parse()?;
        let lookahead = input.lookahead1();
        let threshold = if lookahead.peek(LitInt) {
            let threshold: LitInt = input.parse()?;
            threshold.base10_parse()?
        } else {
            DEFAULT_LIMIT
        };
        Ok(MacroInput {
            visibility,
            name,
            regex,
            threshold,
        })
    }
}

impl MacroInput {
    pub fn is_str(&self) -> bool {
        self.regex.is_str()
    }

    pub fn get_regex(&self) -> String {
        self.regex.get_regex()
    }

    pub fn get_regex_span(&self) -> Span {
        self.regex.span()
    }

    pub fn get_name(&self) -> &Ident {
        &self.name
    }

    pub fn get_visibility(&self) -> &Visibility {
        &self.visibility
    }

    pub fn get_threshold(&self) -> usize {
        self.threshold
    }
}