diff --git a/macros/src/actix.rs b/macros/src/actix.rs index fc59a2558..29db8e4b6 100644 --- a/macros/src/actix.rs +++ b/macros/src/actix.rs @@ -1443,7 +1443,9 @@ fn add_optional_impl(name: &Ident, generics: &Generics) -> proc_macro2::TokenStr fn get_field_type(field: &Field) -> Option { 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(), @@ -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(); @@ -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(); @@ -1729,7 +1737,7 @@ fn handle_enum(e: &DataEnum, serde: &SerdeProps, props_gen: &mut proc_macro2::To /// `Vec::::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)>); } diff --git a/tests/test_app.rs b/tests/test_app.rs index a5abb27e0..148cb2c1e 100644 --- a/tests/test_app.rs +++ b/tests/test_app.rs @@ -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>, 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" + }), + ); + }, + ); +}