flat_enum_macro 0.1.1

Expand nested enum into flattened enum
Documentation
use proc_macro_error::abort;
use syn::punctuated::{Pair, Punctuated};
use syn::spanned::Spanned;
use syn::*;
use template_quote::quote;

pub fn getrandom() -> u64 {
    use core::hash::{BuildHasher, Hash, Hasher};
    use proc_macro2::Span;
    use std::collections::hash_map::RandomState;

    let mut hasher = RandomState::new().build_hasher();
    format!("{:?}", &Span::call_site()).hash(&mut hasher);
    hasher.finish()
}

pub fn generics_remove_defaults(generics: &Generics) -> Generics {
    let mut ret = generics.clone();
    ret.params.iter_mut().for_each(|gp| match gp {
        GenericParam::Type(tp) => {
            tp.eq_token = None;
            tp.default = None;
        }
        GenericParam::Const(cp) => {
            cp.eq_token = None;
            cp.default = None;
        }
        _ => (),
    });
    ret
}

pub fn ident_to_path(ident: &Ident) -> Path {
    Path {
        leading_colon: None,
        segments: Some(PathSegment {
            ident: ident.clone(),
            arguments: PathArguments::None,
        })
        .into_iter()
        .collect(),
    }
}

pub fn generics_to_arguments(generics: &Generics) -> PathArguments {
    let mut args = Punctuated::new();
    for p in generics.params.pairs() {
        let v = match p.value() {
            GenericParam::Lifetime(lt) => GenericArgument::Lifetime(lt.lifetime.clone()),
            GenericParam::Type(tp) => GenericArgument::Type(Type::Path(TypePath {
                qself: None,
                path: ident_to_path(&tp.ident),
            })),
            GenericParam::Const(cp) => GenericArgument::Const(Expr::Path(ExprPath {
                attrs: Vec::new(),
                qself: None,
                path: ident_to_path(&cp.ident),
            })),
        };
        args.push_value(v);
        match p {
            Pair::Punctuated(_, p) => args.push_punct(p.clone()),
            _ => (),
        }
    }
    PathArguments::AngleBracketed(AngleBracketedGenericArguments {
        colon2_token: None,
        lt_token: generics.lt_token.unwrap_or(Default::default()),
        args,
        gt_token: generics.gt_token.unwrap_or(Default::default()),
    })
}

pub fn generic_arg_to_type(arg: GenericArgument) -> Type {
    match arg {
        GenericArgument::Lifetime(lt) => {
            syn::parse(quote! {& #lt ()}.into()).expect("Cannot parse reference to type")
        }
        GenericArgument::Type(ty) => ty,
        GenericArgument::Const(expr) => {
            syn::parse(quote! {[(); #expr]}.into()).expect("Cannot parse array to type")
        }
        _ => abort!(arg.span(), "Not supported"),
    }
}