api-macro: handle renames in updater derive
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
4c37db22d2
commit
51d78fdd2b
@ -271,7 +271,8 @@ fn handle_regular_struct(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if derive {
|
if derive {
|
||||||
let updater = derive_updater(stru.clone(), schema.clone(), &mut stru)?;
|
let updater =
|
||||||
|
derive_updater(stru.clone(), schema.clone(), &mut stru, &container_attrs)?;
|
||||||
|
|
||||||
// make sure we don't leave #[updater] attributes on the original struct:
|
// make sure we don't leave #[updater] attributes on the original struct:
|
||||||
if let syn::Fields::Named(fields) = &mut stru.fields {
|
if let syn::Fields::Named(fields) = &mut stru.fields {
|
||||||
@ -403,6 +404,7 @@ fn derive_updater(
|
|||||||
mut stru: syn::ItemStruct,
|
mut stru: syn::ItemStruct,
|
||||||
mut schema: Schema,
|
mut schema: Schema,
|
||||||
original_struct: &mut syn::ItemStruct,
|
original_struct: &mut syn::ItemStruct,
|
||||||
|
container_attrs: &serde::ContainerAttrib,
|
||||||
) -> Result<TokenStream, Error> {
|
) -> Result<TokenStream, Error> {
|
||||||
let original_name = &original_struct.ident;
|
let original_name = &original_struct.ident;
|
||||||
stru.ident = Ident::new(&format!("{}Updater", stru.ident), stru.ident.span());
|
stru.ident = Ident::new(&format!("{}Updater", stru.ident), stru.ident.span());
|
||||||
@ -425,6 +427,7 @@ fn derive_updater(
|
|||||||
&mut schema,
|
&mut schema,
|
||||||
&mut all_of_schemas,
|
&mut all_of_schemas,
|
||||||
&mut is_empty_impl,
|
&mut is_empty_impl,
|
||||||
|
container_attrs,
|
||||||
) {
|
) {
|
||||||
Ok(FieldAction::Keep) => fields.named.push(field),
|
Ok(FieldAction::Keep) => fields.named.push(field),
|
||||||
Ok(FieldAction::Skip) => (),
|
Ok(FieldAction::Skip) => (),
|
||||||
@ -471,32 +474,51 @@ fn handle_updater_field(
|
|||||||
schema: &mut Schema,
|
schema: &mut Schema,
|
||||||
all_of_schemas: &mut TokenStream,
|
all_of_schemas: &mut TokenStream,
|
||||||
is_empty_impl: &mut TokenStream,
|
is_empty_impl: &mut TokenStream,
|
||||||
|
container_attrs: &serde::ContainerAttrib,
|
||||||
) -> Result<FieldAction, syn::Error> {
|
) -> Result<FieldAction, syn::Error> {
|
||||||
let updater_attrs = UpdaterFieldAttributes::from_attributes(&mut field.attrs);
|
let updater_attrs = UpdaterFieldAttributes::from_attributes(&mut field.attrs);
|
||||||
|
let serde_attrs = serde::FieldAttrib::try_from(&field.attrs[..])?;
|
||||||
|
|
||||||
let field_name = field.ident.as_ref().expect("unnamed field in FieldsNamed");
|
let field_name = field.ident.as_ref().expect("unnamed field in FieldsNamed");
|
||||||
let field_name_string = field_name.to_string();
|
let field_name_string = field_name.to_string();
|
||||||
|
|
||||||
|
let (name, name_span) = {
|
||||||
|
let ident: &Ident = field
|
||||||
|
.ident
|
||||||
|
.as_ref()
|
||||||
|
.ok_or_else(|| format_err!(&field => "field without name?"))?;
|
||||||
|
|
||||||
|
if let Some(renamed) = serde_attrs.rename.clone() {
|
||||||
|
(renamed.value(), ident.span())
|
||||||
|
} else if let Some(rename_all) = container_attrs.rename_all {
|
||||||
|
let name = rename_all.apply_to_field(&ident.to_string());
|
||||||
|
(name, ident.span())
|
||||||
|
} else {
|
||||||
|
(ident.to_string(), ident.span())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if updater_attrs.skip() {
|
if updater_attrs.skip() {
|
||||||
if !schema.remove_obj_property_by_ident(&field_name_string) {
|
if !schema.remove_obj_property_by_ident(&name)
|
||||||
bail!(
|
&& !schema.remove_obj_property_by_ident(&field_name_string)
|
||||||
field_name.span(),
|
{
|
||||||
"failed to find schema entry for {:?}",
|
bail!(name_span, "failed to find schema entry for {:?}", name);
|
||||||
field_name_string,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return Ok(FieldAction::Skip);
|
return Ok(FieldAction::Skip);
|
||||||
}
|
}
|
||||||
|
|
||||||
let field_schema = match schema.find_obj_property_by_ident_mut(&field_name_string) {
|
let field_schema = match schema.find_obj_property_by_ident_mut(&name) {
|
||||||
Some(obj) => obj,
|
Some(obj) => obj,
|
||||||
None => {
|
None => match schema.find_obj_property_by_ident_mut(&field_name_string) {
|
||||||
bail!(
|
Some(obj) => obj,
|
||||||
field_name.span(),
|
None => {
|
||||||
"failed to find schema entry for {:?}",
|
bail!(
|
||||||
field_name_string,
|
field_name.span(),
|
||||||
);
|
"failed to find schema entry for {:?}",
|
||||||
}
|
field_name_string,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let span = Span::call_site();
|
let span = Span::call_site();
|
||||||
|
@ -155,3 +155,19 @@ pub struct WithSerde {
|
|||||||
#[updater(serde(skip_serializing_if = "Option::is_none"))]
|
#[updater(serde(skip_serializing_if = "Option::is_none"))]
|
||||||
more: MyType,
|
more: MyType,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[api(
|
||||||
|
properties: {
|
||||||
|
another: { type: MyType },
|
||||||
|
},
|
||||||
|
)]
|
||||||
|
/// A struct where we replace serde attributes.
|
||||||
|
#[derive(Deserialize, Serialize, Updater)]
|
||||||
|
pub struct RenamedStuff {
|
||||||
|
/// Simple string.
|
||||||
|
data: String,
|
||||||
|
|
||||||
|
#[serde(rename = "another")]
|
||||||
|
#[updater(skip)]
|
||||||
|
more: MyType,
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user