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()
}