use proc_macro2::Span;
use syn::{
spanned::Spanned, Data, DataStruct, DeriveInput, Error, Field, Fields, Result, Type, TypePath,
};
pub(crate) fn get_data_struct(input: &DeriveInput) -> Result<&DataStruct> {
match &input.data {
Data::Struct(data_struct) => Ok(data_struct),
Data::Enum(_) => Err(Error::new(input.ident.span(), "Enum are not managed!")),
Data::Union(_) => Err(Error::new(input.ident.span(), "Union are not managed!")),
}
}
pub(crate) fn get_unnamed_field(data_struct: &DataStruct) -> Result<&Field> {
match &data_struct.fields {
Fields::Named(_) => Err(Error::new(
Span::call_site(),
"Macro don't manage Struct with Named field",
)),
Fields::Unnamed(fields) => {
let fields = &fields.unnamed;
if fields.len() == 1 {
Ok(fields.iter().next().unwrap())
} else if fields.is_empty() {
Err(Error::new(
Span::call_site(),
"Macro only manage struct with 1 unamed field. Don't managed unit struct",
))
} else {
Err(Error::new(
Span::call_site(),"Macro only manage struct with 1 unamed field. Don't managed struct with multiple field"))
}
}
Fields::Unit => Err(Error::new(
Span::call_site(),
"Macro don't manage Struct with Unit",
)),
}
}
pub(crate) fn check_unittype(data_struct: &DataStruct) -> Result<()> {
match data_struct.fields {
Fields::Named(_) => Err(Error::new(
Span::call_site(),
"Remove named field(s) from struct, this macro is intended to be used with Unit Struct",
)),
Fields::Unnamed(_) => Err(Error::new(
Span::call_site(),
"Remove Unnamed field(s) from struct. The macro is intended to be used with Unit Struct"
)),
Fields::Unit => {
Ok(())
},
}
}
pub(crate) fn get_field_path(field: &Field) -> Result<&TypePath> {
let field_type = &field.ty;
match field_type {
Type::Path(path) => Ok(path),
_ => Err(Error::new(
field.ident.span(),
"Other type than Path are not managed",
)),
}
}