use syn::{
    parse::{
        Parse,
        ParseStream,
        Result,
    },
    Expr,
    ExprClosure,
    LitStr,
    Token,
};
pub(crate) struct RexValArgs {
    pub regex_str: LitStr,
    pub value: Expr, }
impl Parse for RexValArgs {
    fn parse(input: ParseStream<'_>) -> Result<Self> {
        let regex_str = input.parse::<LitStr>()?;
        input.parse::<Token![,]>()?;
        let value = input.parse::<Expr>()?;
        let _ = input.parse::<Token![,]>();         Ok(RexValArgs { regex_str, value })
    }
}
pub(crate) struct ReplaceArgs {
    pub regex_str: LitStr,
    pub value: Expr,
    pub replacer: MaybeFun,
}
pub(crate) enum MaybeFun {
    Fun(ExprClosure),
    Expr(Expr),
}
impl Parse for ReplaceArgs {
    fn parse(input: ParseStream<'_>) -> Result<Self> {
        let regex_str = input.parse::<LitStr>()?;
        input.parse::<Token![,]>()?;
        let value = input.parse::<Expr>()?;
        input.parse::<Token![,]>()?;
                        let replacer = if let Ok(fun) = input.parse::<ExprClosure>() {
            MaybeFun::Fun(fun)
        } else {
            MaybeFun::Expr(input.parse::<Expr>()?)
        };
        let _ = input.parse::<Token![,]>();         Ok(ReplaceArgs {
            regex_str,
            value,
            replacer,
        })
    }
}
pub(crate) struct RexIfArgs {
    pub regex_str: LitStr,
    pub value: Expr,     pub then: Expr,
}
impl Parse for RexIfArgs {
    fn parse(input: ParseStream<'_>) -> Result<Self> {
        let regex_str = input.parse::<LitStr>()?;
        input.parse::<Token![,]>()?;
        let value = input.parse::<Expr>()?;
        input.parse::<Token![,]>()?;
        let then = input.parse::<Expr>()?;
        let _ = input.parse::<Token![,]>();         Ok(Self {
            regex_str,
            value,
            then,
        })
    }
}
pub(crate) struct RexSwitchArgs {
    pub value: Expr,     pub arms: Vec<RexSwitchArmArgs>,
}
pub(crate) struct RexSwitchArmArgs {
    pub regex_str: LitStr,
    pub then: Expr,
}
impl Parse for RexSwitchArgs {
    fn parse(input: ParseStream<'_>) -> Result<Self> {
        let value = input.parse::<Expr>()?;
        input.parse::<Token![,]>()?;
        let mut arms = Vec::new();
        loop {
            let lookahead = input.lookahead1();
            if lookahead.peek(LitStr) {
                let arm = input.parse::<RexSwitchArmArgs>()?;
                arms.push(arm);
            } else {
                break;
            }
        }
        Ok(Self {
            value,
            arms,
        })
    }
}
impl Parse for RexSwitchArmArgs {
    fn parse(input: ParseStream<'_>) -> Result<Self> {
        let regex_str = input.parse::<LitStr>()?;
        input.parse::<Token![=>]>()?;
        let then = input.parse::<Expr>()?;
        let _ = input.parse::<Token![,]>();         Ok(Self {
            regex_str,
            then,
        })
    }
}