#![crate_name = "small_iter_fields"]
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, Data, DeriveInput};
#[proc_macro_derive(IterFields)]
pub fn derive_iter_fields(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let name = input.ident;
let expanded = match input.data {
Data::Enum(e) => {
let variants: Vec<_> = e.variants.into_iter().map(|v| v.ident).collect();
quote! {
impl #name {
pub fn iter_fields() -> impl Iterator<Item = #name> {
vec![
#(#name::#variants), *
].into_iter()
}
}
}
},
_ => panic!("Can only be used on enums")
};
expanded.into()
}
#[proc_macro_derive(HashFields)]
pub fn derive_hash_fields(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let name = input.ident;
let expanded = match input.data {
Data::Enum(_) => {
quote! {
impl #name {
pub fn to_hashmap<T: Clone>(value: T) -> std::collections::HashMap<Self, T> {
std::collections::HashMap::from_iter(Self::iter_fields().map(|field| (field, value.clone())))
}
}
impl #name {
pub fn to_hashset() -> std::collections::HashSet<Self> {
std::collections::HashSet::from_iter(Self::iter_fields())
}
}
}
},
_ => panic!("Can only be used on enums")
};
expanded.into()
}
#[proc_macro_derive(LenFields)]
pub fn derive_len_fields(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let name = input.ident;
let expanded = match input.data {
Data::Enum(e) => {
let num = e.variants.len();
quote! {
impl #name {
pub fn len() -> usize {
#num
}
}
}
},
_ => panic!("Can only be used on enums")
};
expanded.into()
}