Skip to content

Commit

Permalink
Merge pull request #254 from nathanejohnson/SwaggerAddTypeTag
Browse files Browse the repository at this point in the history
Adding 'type' struct tag that can override the guessed type
  • Loading branch information
emicklei committed Nov 16, 2015
2 parents e9659cd + f91272c commit b38cb13
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 10 deletions.
24 changes: 19 additions & 5 deletions swagger/model_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,11 @@ func (b modelBuilder) buildProperty(field reflect.StructField, model *Model, mod
modelDescription = tag
}

fieldType := field.Type

prop.setPropertyMetadata(field)
if prop.Type != nil {
return jsonName, modelDescription, prop
}
fieldType := field.Type

// check if type is doing its own marshalling
marshalerType := reflect.TypeOf((*json.Marshaler)(nil)).Elem()
Expand Down Expand Up @@ -212,8 +214,12 @@ func hasNamedJSONTag(field reflect.StructField) bool {
}

func (b modelBuilder) buildStructTypeProperty(field reflect.StructField, jsonName string, model *Model) (nameJson string, prop ModelProperty) {
fieldType := field.Type
prop.setPropertyMetadata(field)
// Check for type override in tag
if prop.Type != nil {
return jsonName, prop
}
fieldType := field.Type
// check for anonymous
if len(fieldType.Name()) == 0 {
// anonymous
Expand Down Expand Up @@ -263,8 +269,12 @@ func (b modelBuilder) buildStructTypeProperty(field reflect.StructField, jsonNam
}

func (b modelBuilder) buildArrayTypeProperty(field reflect.StructField, jsonName, modelName string) (nameJson string, prop ModelProperty) {
fieldType := field.Type
// check for type override in tags
prop.setPropertyMetadata(field)
if prop.Type != nil {
return jsonName, prop
}
fieldType := field.Type
var pType = "array"
prop.Type = &pType
elemTypeName := b.getElementTypeName(modelName, jsonName, fieldType.Elem())
Expand All @@ -284,8 +294,12 @@ func (b modelBuilder) buildArrayTypeProperty(field reflect.StructField, jsonName
}

func (b modelBuilder) buildPointerTypeProperty(field reflect.StructField, jsonName, modelName string) (nameJson string, prop ModelProperty) {
fieldType := field.Type
prop.setPropertyMetadata(field)
// Check for type override in tags
if prop.Type != nil {
return jsonName, prop
}
fieldType := field.Type

// override type of pointer to list-likes
if fieldType.Elem().Kind() == reflect.Slice || fieldType.Elem().Kind() == reflect.Array {
Expand Down
31 changes: 31 additions & 0 deletions swagger/model_builder_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package swagger

import (
"net"
"testing"
"time"
)
Expand Down Expand Up @@ -1109,3 +1110,33 @@ func TestNestedStructDescription(t *testing.T) {
`
testJsonFromStruct(t, A{}, expected)
}

// This tests a primitive with type overrides in the struct tags
type FakeInt int
type E struct {
Id FakeInt `type:"integer"`
IP net.IP `type:"string"`
}

func TestOverridenTypeTagE1(t *testing.T) {
expected := `
{
"swagger.E": {
"id": "swagger.E",
"required": [
"Id",
"IP"
],
"properties": {
"Id": {
"type": "integer"
},
"IP": {
"type": "string"
}
}
}
}
`
testJsonFromStruct(t, E{}, expected)
}
7 changes: 7 additions & 0 deletions swagger/model_property_ext.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ func (prop *ModelProperty) setMaximum(field reflect.StructField) {
}
}

func (prop *ModelProperty) setType(field reflect.StructField) {
if tag := field.Tag.Get("type"); tag != "" {
prop.Type = &tag
}
}

func (prop *ModelProperty) setMinimum(field reflect.StructField) {
if tag := field.Tag.Get("minimum"); tag != "" {
prop.Minimum = tag
Expand All @@ -56,4 +62,5 @@ func (prop *ModelProperty) setPropertyMetadata(field reflect.StructField) {
prop.setMaximum(field)
prop.setUniqueItems(field)
prop.setDefaultValue(field)
prop.setType(field)
}
24 changes: 19 additions & 5 deletions swagger/model_property_ext_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package swagger

import "testing"
import (
"net"
"testing"
)

// clear && go test -v -test.run TestThatExtraTagsAreReadIntoModel ...swagger
func TestThatExtraTagsAreReadIntoModel(t *testing.T) {
type fakeint int
type Anything struct {
Name string `description:"name" modelDescription:"a test"`
Size int `minimum:"0" maximum:"10"`
Stati string `enum:"off|on" default:"on" modelDescription:"more description"`
ID string `unique:"true"`
Name string `description:"name" modelDescription:"a test"`
Size int `minimum:"0" maximum:"10"`
Stati string `enum:"off|on" default:"on" modelDescription:"more description"`
ID string `unique:"true"`
FakeInt fakeint `type:"integer"`
IP net.IP `type:"string"`
Password string
}
m := modelsFromStruct(Anything{})
Expand Down Expand Up @@ -39,6 +45,14 @@ func TestThatExtraTagsAreReadIntoModel(t *testing.T) {
if got, want := *p5.Type, "string"; got != want {
t.Errorf("got %v want %v", got, want)
}
p6, _ := props.Properties.At("FakeInt")
if got, want := *p6.Type, "integer"; got != want {
t.Errorf("got %v want %v", got, want)
}
p7, _ := props.Properties.At("IP")
if got, want := *p7.Type, "string"; got != want {
t.Errorf("got %v want %v", got, want)
}

if got, want := props.Description, "a test\nmore description"; got != want {
t.Errorf("got %v want %v", got, want)
Expand Down

0 comments on commit b38cb13

Please sign in to comment.