clone-fields-derive 0.4.1

Derive macro for CloneFields trait
Documentation
use proc_macro2::{Span, TokenStream};
use quote::ToTokens;
use syn;

pub enum Field {
    Named(syn::Ident),
    Unnamed(syn::Index),
}

impl ToTokens for Field {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        match self {
            Field::Named(id) => id.to_tokens(tokens),
            Field::Unnamed(idx) => idx.to_tokens(tokens),
        }
    }
}

pub struct StructData {
    pub name: syn::Ident,
    pub field_idents: Vec<Field>,
    pub generics: syn::Generics,
}

impl StructData {
    pub fn new(data_struct: syn::DataStruct, ident: syn::Ident, generics: syn::Generics) -> Self {
        let span = ident.span();
        StructData {
            name: ident,
            field_idents: get_fields(data_struct.fields.iter(), span),
            generics,
        }
    }
}

fn get_fields<'a>(fields: impl IntoIterator<Item = &'a syn::Field>, span: Span) -> Vec<Field> {
    fields
        .into_iter()
        .enumerate()
        .map(|(i, field)| {
            field.ident.clone().map(Field::Named).unwrap_or_else(|| {
                Field::Unnamed(syn::Index {
                    index: i as u32,
                    span,
                })
            })
        })
        .collect()
}