matched_enums_macro 1.1.0

Contains the macro for matchable enums.
Documentation
extern crate alloc;

use alloc::vec::Vec;

use syn::{
    parse::{Parse, ParseStream},
    punctuated::Punctuated,
    Attribute, Expr, MetaNameValue, Token, Type,
};

use super::{match_arm::MatchArm, utils::try_convert_type_expr_into_type};

#[allow(
    dead_code,
    reason = "These attributes need to be parsed regardless. Might as well add them. Even if unused"
)]
pub struct MatchAttribute {
    pub attrs: Vec<Attribute>,
    pub arm: MatchArm,
    pub type_bind: Option<Type>,
}

impl MatchAttribute {
    fn set_type_bind(&mut self, val: &Expr) -> syn::Result<()> {
        self.type_bind = Some(try_convert_type_expr_into_type(val)?);
        Ok(())
    }
}

impl Parse for MatchAttribute {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        let mut match_attr = Self {
            attrs: input.call(Attribute::parse_outer)?,
            arm: MatchArm::parse(input)?,
            type_bind: None,
        };

        let sep: Option<Token![,]> = input.parse()?;
        if sep.is_none() {
            return Ok(match_attr);
        }

        for MetaNameValue {
            ref path,
            ref value,
            ..
        } in Punctuated::<MetaNameValue, Token![,]>::parse_terminated(input)?
        {
            if path.is_ident("bind") {
                match_attr.set_type_bind(value)?;
            }
        }

        Ok(match_attr)
    }
}