spire_enum_macros 1.2.0

Procedural macros distributed by the crate `spire_enum`.
Documentation
use kw::{mod_name as kw_mod_name, ty_name as kw_ty_name};
use syn::{parse_quote, token::Comma};

mod kw {
    syn::custom_keyword!(ty_name);
    syn::custom_keyword!(mod_name);
}

pub mod discriminant_to_generic;
pub mod variant_type_to_generic;
pub mod variant_type_to_variant_type;

use super::*;

fn var_to_field_ident(ident: &Ident) -> Ident {
    let str = ident.to_string().to_case(Case::Snake);
    Ident::new_raw(&str, Span::call_site())
}

#[derive(Default)]
struct SaneTableMetas {
    syn_metas: Vec<SynMeta>,
    cfg_metas: Vec<CfgMeta>,
    ty_name: Optional<SettingTypeName>,
    mod_name: Optional<SettingModName>,
}

#[derive(Parse, ToTokens)]
enum TableMeta {
    TypeName(SettingTypeName),
    ModuleName(SettingModName),
    Derive(SettingDerive),
    Attrs(SettingAttrs),
}

#[derive(Parse, ToTokens)]
struct SettingTypeName {
    kw: kw_ty_name,
    eq_token: Token![=],
    name: Ident,
}

#[derive(Parse, ToTokens)]
struct SettingModName {
    kw: kw_mod_name,
    eq_token: Token![=],
    name: Ident,
}

fn parse_table_metas(input: TokenStream1) -> Result<SaneTableMetas> {
    let input_attrs = syn::parse::<InputPunctuated<Meta<TableMeta>, Token![,]>>(input)?;
    parse_table_metas_inner(input_attrs)
}

#[allow(unused)]
fn parse_table_metas_syn(input: TokenStream) -> Result<SaneTableMetas> {
    let input_attrs = syn::parse2::<InputPunctuated<Meta<TableMeta>, Token![,]>>(input)?;
    parse_table_metas_inner(input_attrs)
}

fn parse_table_metas_inner(
    input_attrs: InputPunctuated<Meta<TableMeta>, Comma>,
) -> Result<SaneTableMetas> {
    let mut sane = SaneTableMetas::default();
    let (syn_metas, cfg_metas, custom_attrs) = split_input_metas(input_attrs.inner);
    sane.syn_metas = syn_metas;
    sane.cfg_metas = cfg_metas;

    for meta in custom_attrs {
        match meta {
            TableMeta::TypeName(ty_name) => {
                assign_unique_or_panic!(sane.ty_name, ty_name);
            }
            TableMeta::ModuleName(mod_name) => {
                assign_unique_or_panic!(sane.mod_name, mod_name);
            }
            TableMeta::Derive(SettingDerive { kw, paths }) => {
                let syn_meta: SynMeta = parse_quote! { #kw #paths };
                sane.syn_metas.push(syn_meta);
            }
            TableMeta::Attrs(SettingAttrs { kw: _, attrs }) => {
                sane.syn_metas.extend(attrs.into_inner().inner)
            }
        }
    }

    Ok(sane)
}

fn length_definition<'a>(
    ident: &Ident,
    var_cfgs: impl Iterator<Item = &'a Any<Attribute<CfgMeta>>>,
) -> TokenStream {
    quote! {
        const #ident: usize = {
            let mut count = 0;

            #(
                #var_cfgs
                {
                    count += 1;
                }
            )*
            count
        };
    }
}