1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
use syn::{Attribute, Field, LitStr, Result, Variant};
/// Find the value of a #[serde(rename = "...")] attribute.
fn attr_rename(attrs: &[Attribute]) -> Result<Option<String>> {
let mut rename = None;
for attr in attrs {
if !attr.path().is_ident("serde") {
continue;
}
attr.parse_nested_meta(|meta| {
if meta.path.is_ident("rename") {
let s: LitStr = meta.value()?.parse()?;
if rename.is_some() {
return Err(meta.error("duplicate rename attribute"));
}
rename = Some(s.value());
Ok(())
} else {
Err(meta.error("unsupported attribute"))
}
})?;
}
Ok(rename)
}
/// Determine the name of a field, respecting a rename attribute.
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()))
}
/// Determine the name of a variant, respecting a rename attribute.
pub fn name_of_variant(var: &Variant) -> Result<String> {
let rename = attr_rename(&var.attrs)?;
Ok(rename.unwrap_or_else(|| var.ident.to_string()))
}