diff --git a/entities.go b/entities.go index cbf4ffb..d44a435 100644 --- a/entities.go +++ b/entities.go @@ -395,9 +395,7 @@ func (o SchemaObj) MarshalJSON() ([]byte, error) { // ParamItemObj describes an property object, in param object or property of definition // see http://swagger.io/specification/#itemsObject type ParamItemObj struct { - Ref string `json:"$ref,omitempty"` - Type string `json:"type"` - Format string `json:"format,omitempty"` + CommonFields Items *ParamItemObj `json:"items,omitempty"` // Required if type is "array" CollectionFormat string `json:"collectionFormat,omitempty"` // "multi" - this is valid only for parameters in "query" or "formData" } diff --git a/parser.go b/parser.go index b7bef60..dac3279 100644 --- a/parser.go +++ b/parser.go @@ -571,14 +571,25 @@ func (g *Generator) ParseParameters(i interface{}) (string, []ParamObj) { param.CommonFields = schemaObj.CommonFields if schemaObj.Type == "array" && schemaObj.Items != nil { - if schemaObj.Items.Ref != "" || schemaObj.Items.Type == "array" { - panic("unsupported array of struct or nested array in parameter") + if schemaObj.Items.Ref != "" { + fieldType := refl.DeepIndirect(field.Type) + if fieldType.Kind() == reflect.Slice || fieldType.Kind() == reflect.Array { + g.ParseDefinition(reflect.Zero(field.Type.Elem()).Interface()) + + if def, ok := g.getDefinition(field.Type.Elem()); ok { + schemaObj.Items = &def + } + } } - param.Items = &ParamItemObj{ - Type: schemaObj.Items.Type, - Format: schemaObj.Items.Format, + if schemaObj.Items.Ref != "" || schemaObj.Items.Type == "array" || schemaObj.Items.Type == "object" { + panic("unsupported array of struct or nested array in parameter: " + fieldTypeName) } + + param.Items = &ParamItemObj{} + param.Items.CommonFields = schemaObj.Items.CommonFields + param.Items.Title = "" + param.Items.Description = "" param.CollectionFormat = "multi" // default for now } } diff --git a/parser_test.go b/parser_test.go index 162a79c..97bc920 100644 --- a/parser_test.go +++ b/parser_test.go @@ -402,3 +402,33 @@ func TestGenerator_SetPathItem_typeFile(t *testing.T) { assert.NoError(t, err) assert.JSONEq(t, expected, string(swg), coloredJSONDiff(expected, string(swg))) } + +type CountryCode string + +func (CountryCode) SwaggerDef() SwaggerData { + def := SwaggerData{} + def.Description = "Country Code" + def.Example = "us" + def.Type = "string" + def.Pattern = "^[a-zA-Z]{2}$" + return def +} + +func TestGenerator_ParseParameters_namedSchemaParamItem(t *testing.T) { + type Req struct { + Codes []CountryCode `query:"countries" collectionFormat:"csv"` + } + + g := NewGenerator() + pathItem := PathItemInfo{ + Request: new(Req), + Method: http.MethodGet, + Path: "/some", + } + g.SetPathItem(pathItem) + expected := `{"swagger":"2.0","info":{"title":"","description":"","termsOfService":"","contact":{"name":""},"license":{"name":""},"version":""},"basePath":"/","schemes":["http","https"],"paths":{"/some":{"get":{"summary":"","description":"","parameters":[{"type":"array","name":"countries","in":"query","items":{"type":"string","pattern":"^[a-zA-Z]{2}$"},"collectionFormat":"csv"}],"responses":{"200":{"description":"OK"}}}}},"definitions":{"CountryCode":{"description":"Country Code","type":"string","pattern":"^[a-zA-Z]{2}$","example":"us"}}}` + + swg, err := g.GenDocument() + assert.NoError(t, err) + assert.JSONEq(t, expected, string(swg), coloredJSONDiff(expected, string(swg))) +}