(ast: &DeriveInput)
| 5 | use super::helpers::{non_enum_error, HasStrumVariantProperties, HasTypeProperties}; |
| 6 | |
| 7 | pub fn enum_iter_inner(ast: &DeriveInput) -> syn::Result<TokenStream> { |
| 8 | let name = &ast.ident; |
| 9 | let gen = &ast.generics; |
| 10 | let (impl_generics, ty_generics, where_clause) = gen.split_for_impl(); |
| 11 | let vis = &ast.vis; |
| 12 | let type_properties = ast.get_type_properties()?; |
| 13 | let strum_module_path = type_properties.crate_module_path(); |
| 14 | let doc_comment = format!("An iterator over the variants of [{name}]"); |
| 15 | |
| 16 | if gen.lifetimes().count() > 0 { |
| 17 | return Err(syn::Error::new( |
| 18 | Span::call_site(), |
| 19 | "This macro doesn't support enums with lifetimes. \ |
| 20 | The resulting enums would be unbounded.", |
| 21 | )); |
| 22 | } |
| 23 | |
| 24 | let phantom_data = if gen.type_params().count() > 0 { |
| 25 | let g = gen.type_params().map(|param| ¶m.ident); |
| 26 | quote! { < ( #(#g),* ) > } |
| 27 | } else { |
| 28 | quote! { < () > } |
| 29 | }; |
| 30 | |
| 31 | let variants = match &ast.data { |
| 32 | Data::Enum(v) => &v.variants, |
| 33 | _ => return Err(non_enum_error()), |
| 34 | }; |
| 35 | |
| 36 | let mut arms = Vec::new(); |
| 37 | let mut idx = 0usize; |
| 38 | for variant in variants { |
| 39 | if variant.get_variant_properties()?.disabled.is_some() { |
| 40 | continue; |
| 41 | } |
| 42 | |
| 43 | let ident = &variant.ident; |
| 44 | let params = match &variant.fields { |
| 45 | Fields::Unit => quote! {}, |
| 46 | Fields::Unnamed(fields) => { |
| 47 | let defaults = ::core::iter::repeat(quote!(::core::default::Default::default())) |
| 48 | .take(fields.unnamed.len()); |
| 49 | quote! { (#(#defaults),*) } |
| 50 | } |
| 51 | Fields::Named(fields) => { |
| 52 | let fields = fields |
| 53 | .named |
| 54 | .iter() |
| 55 | .map(|field| field.ident.as_ref().unwrap()); |
| 56 | quote! { {#(#fields: ::core::default::Default::default()),*} } |
| 57 | } |
| 58 | }; |
| 59 | |
| 60 | arms.push(quote! {#idx => ::core::option::Option::Some(#name::#ident #params)}); |
| 61 | idx += 1; |
| 62 | } |
| 63 | |
| 64 | let variant_count = arms.len(); |
no test coverage detected