diff --git a/keywords.go b/keywords.go index 66c5eb5..f8467ad 100644 --- a/keywords.go +++ b/keywords.go @@ -22,21 +22,24 @@ var primitiveTypes = map[string]bool{ // DataType gives the primitive json type of a standard json-decoded value, plus the special case // "integer" for when numbers are whole func DataType(data interface{}) string { - switch v := data.(type) { - case nil: + if data == nil { return "null" - case bool: + } + + switch reflect.TypeOf(data).Kind() { + case reflect.Bool: return "boolean" - case float64: - if float64(int(v)) == v { + case reflect.Float64: + number := reflect.ValueOf(data).Float() + if float64(int(number)) == number { return "integer" } return "number" - case string: + case reflect.String: return "string" - case []interface{}: + case reflect.Array, reflect.Slice: return "array" - case map[string]interface{}: + case reflect.Map, reflect.Struct: return "object" default: return "unknown" diff --git a/schema_test.go b/schema_test.go index cecad8d..32dfed7 100644 --- a/schema_test.go +++ b/schema_test.go @@ -449,17 +449,24 @@ func runJSONTests(t *testing.T, testFilepaths []string) { } func TestDataType(t *testing.T) { + type customObject struct {} + type customNumber float64 + cases := []struct { data interface{} expect string }{ {nil, "null"}, - {struct{}{}, "unknown"}, {float64(4), "integer"}, {float64(4.5), "number"}, + {customNumber(4.5), "number"}, {"foo", "string"}, - {map[string]interface{}{}, "object"}, {[]interface{}{}, "array"}, + {[0]interface{}{}, "array"}, + {map[string]interface{}{}, "object"}, + {struct{}{}, "object"}, + {customObject{}, "object"}, + {int8(42), "unknown"}, } for i, c := range cases {