Skip to content

Commit

Permalink
fix(actix): support parsing arrays for schemas (#531)
Browse files Browse the repository at this point in the history
Array field types were not being parsed.
Also in this case errors were not being handled gracefully.

Signed-off-by: Tiago Castro <[email protected]>
  • Loading branch information
tiagolobocastro authored Sep 10, 2024
1 parent f34aee5 commit e04adff
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 4 deletions.
16 changes: 12 additions & 4 deletions macros/src/actix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1443,7 +1443,9 @@ fn add_optional_impl(name: &Ident, generics: &Generics) -> proc_macro2::TokenStr

fn get_field_type(field: &Field) -> Option<proc_macro2::TokenStream> {
match field.ty {
Type::Path(_) | Type::Reference(_) => Some(address_type_for_fn_call(&field.ty)),
Type::Path(_) | Type::Reference(_) | Type::Array(_) => {
Some(address_type_for_fn_call(&field.ty))
}
_ => {
emit_warning!(
field.ty.span().unwrap(),
Expand Down Expand Up @@ -1491,7 +1493,10 @@ fn handle_unnamed_field_struct(
continue;
}

let ty_ref = get_field_type(field);
let ty_ref = match get_field_type(field) {
Some(ty_ref) => ty_ref,
None => continue,
};

let docs = extract_documentation(&field.attrs);
let docs = docs.trim();
Expand Down Expand Up @@ -1626,7 +1631,10 @@ fn handle_field_struct(
field_name = prop.rename(&field_name);
}

let ty_ref = get_field_type(field);
let ty_ref = match get_field_type(field) {
Some(ty_ref) => ty_ref,
None => continue,
};

let docs = extract_documentation(&field.attrs);
let docs = docs.trim();
Expand Down Expand Up @@ -1729,7 +1737,7 @@ fn handle_enum(e: &DataEnum, serde: &SerdeProps, props_gen: &mut proc_macro2::To
/// `Vec::<T>::foo`. Something similar applies to `str`. This function takes
/// care of that special treatment.
fn address_type_for_fn_call(old_ty: &Type) -> proc_macro2::TokenStream {
if let Type::Reference(_) = old_ty {
if matches!(old_ty, Type::Reference(_) | Type::Array(_)) {
return quote!(<(#old_ty)>);
}

Expand Down
77 changes: 77 additions & 0 deletions tests/test_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5518,3 +5518,80 @@ fn test_wrap() {
},
);
}

#[test]
fn test_array() {
#[derive(Deserialize, Serialize, Apiv2Schema)]
/// Pets are awesome!
struct Pet {
/// Names of other pet friends!
friends: [String; 4],
}

#[api_v2_operation]
fn echo_pets() -> impl Future<Output = Result<web::Json<Vec<Pet>>, Error>> {
fut_ok(web::Json(vec![]))
}

run_and_check_app(
|| {
App::new()
.wrap_api()
.service(web::resource("/pets").route(web::get().to(echo_pets)))
.with_json_spec_at("/api/spec")
.build()
},
|addr| {
let resp = CLIENT
.get(&format!("http://{}/api/spec", addr))
.send()
.expect("request failed?");

check_json(
resp,
json!({
"definitions": {
"Pet": {
"description": "Pets are awesome!",
"properties": {
"friends": {
"description": "Names of other pet friends!",
"type": "array",
"items": {
"type": "string",
}
}
},
"required": [
"friends"
],
"type": "object"
}
},
"info": {
"title": "",
"version": ""
},
"paths": {
"/pets": {
"get": {
"responses": {
"200": {
"description": "OK",
"schema": {
"items": {
"$ref": "#/definitions/Pet"
},
"type": "array"
}
}
}
}
}
},
"swagger": "2.0"
}),
);
},
);
}

0 comments on commit e04adff

Please sign in to comment.