Skip to content

Commit

Permalink
Support overriding a field as optional with #[openapi(optional)]
Browse files Browse the repository at this point in the history
  • Loading branch information
evforde committed Aug 23, 2024
1 parent 67d8463 commit 28fba9d
Showing 1 changed file with 21 additions and 2 deletions.
23 changes: 21 additions & 2 deletions macros/src/actix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1573,6 +1573,7 @@ fn handle_unnamed_field_struct(
let docs = docs.trim();

let override_required = OpenApiRequired::exists(&field.attrs);
let override_optional = OpenApiOptional::exists(&field.attrs);

let gen = if !SerdeFlatten::exists(&field.attrs) {
// this is really not what we'd want to do because that's not how the
Expand All @@ -1584,7 +1585,7 @@ fn handle_unnamed_field_struct(
s.description = Some(#docs.to_string());
}
schema.properties.insert(#inner_field_id.to_string(), s.into());
if #ty_ref::required() || #override_required {
if (#ty_ref::required() || #override_required) && !#override_optional {
schema.required.insert(#inner_field_id.to_string());
}
})
Expand Down Expand Up @@ -1726,6 +1727,7 @@ fn handle_field_struct(
};

let override_required = OpenApiRequired::exists(&field.attrs);
let override_optional = OpenApiOptional::exists(&field.attrs);
let gen = if !SerdeFlatten::exists(&field.attrs) {
quote!({
let mut s = #ty_ref::raw_schema();
Expand All @@ -1736,7 +1738,7 @@ fn handle_field_struct(
#example;
schema.properties.insert(#field_name.into(), s.into());

if #ty_ref::required() || #override_required {
if (#ty_ref::required() || #override_required) && !#override_optional {
schema.required.insert(#field_name.into());
}
})
Expand Down Expand Up @@ -1954,6 +1956,23 @@ impl OpenApiRequired {
}
}

/// Custom attribute that sets this attribute as optional, even if the type is not optional.
struct OpenApiOptional;

impl OpenApiOptional {
/// Traverses the field attributes and returns whether the field should be skipped or not
/// dependent on finding the `#[serde(skip]` attribute.
fn exists(field_attrs: &[Attribute]) -> bool {
extract_openapi_attrs(field_attrs).any(|nested| {
nested.len() == 1
&& match &nested[0] {
NestedMeta::Meta(Meta::Path(path)) => path.is_ident("optional"),
_ => false,
}
})
}
}

#[derive(Clone, Debug, Default)]
struct SerdeProps {
rename: Option<SerdeRename>,
Expand Down

0 comments on commit 28fba9d

Please sign in to comment.