use syn::{Attribute, Error, Field, Lit, Meta, NestedMeta, Result, Variant};
fn attr_rename(attrs: &[Attribute]) -> Result<Option<String>> {
let mut rename = None;
for attr in attrs {
if !attr.path.is_ident("serde") {
continue;
}
let list = match attr.parse_meta()? {
Meta::List(list) => list,
other => return Err(Error::new_spanned(other, "unsupported attribute")),
};
for meta in &list.nested {
if let NestedMeta::Meta(Meta::NameValue(value)) = meta {
if value.path.is_ident("rename") {
if let Lit::Str(s) = &value.lit {
if rename.is_some() {
return Err(Error::new_spanned(meta, "duplicate rename attribute"));
}
rename = Some(s.value());
continue;
}
}
}
return Err(Error::new_spanned(meta, "unsupported attribute"));
}
}
Ok(rename)
}
pub fn name_of_field(field: &Field) -> Result<String> {
let rename = attr_rename(&field.attrs)?;
Ok(rename.unwrap_or_else(|| field.ident.as_ref().unwrap().to_string()))
}
pub fn name_of_variant(var: &Variant) -> Result<String> {
let rename = attr_rename(&var.attrs)?;
Ok(rename.unwrap_or_else(|| var.ident.to_string()))
}