-
Notifications
You must be signed in to change notification settings - Fork 214
[FIX] Issue #202 and #190 #206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
7674e75
1774d8b
7ea5e24
cb512b4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,6 @@ import ( | |
"fmt" | ||
"io" | ||
"reflect" | ||
"strconv" | ||
"strings" | ||
"time" | ||
) | ||
|
@@ -95,7 +94,10 @@ func newErrUnsupportedPtrType(rf reflect.Value, t reflect.Type, structField refl | |
func UnmarshalPayload(in io.Reader, model interface{}) error { | ||
payload := new(OnePayload) | ||
|
||
if err := json.NewDecoder(in).Decode(payload); err != nil { | ||
decoder := json.NewDecoder(in) | ||
decoder.UseNumber() | ||
|
||
if err := decoder.Decode(payload); err != nil { | ||
return err | ||
} | ||
|
||
|
@@ -116,7 +118,10 @@ func UnmarshalPayload(in io.Reader, model interface{}) error { | |
func UnmarshalManyPayload(in io.Reader, t reflect.Type) ([]interface{}, error) { | ||
payload := new(ManyPayload) | ||
|
||
if err := json.NewDecoder(in).Decode(payload); err != nil { | ||
decoder := json.NewDecoder(in) | ||
decoder.UseNumber() | ||
|
||
if err := decoder.Decode(payload); err != nil { | ||
return nil, err | ||
} | ||
|
||
|
@@ -209,18 +214,9 @@ func unmarshalNode(data *Node, model reflect.Value, included *map[string]*Node) | |
continue | ||
} | ||
|
||
// Value was not a string... only other supported type was a numeric, | ||
// which would have been sent as a float value. | ||
floatValue, err := strconv.ParseFloat(data.ID, 64) | ||
if err != nil { | ||
// Could not convert the value in the "id" attr to a float | ||
er = ErrBadJSONAPIID | ||
break | ||
} | ||
|
||
// Convert the numeric float to one of the supported ID numeric types | ||
// (int[8,16,32,64] or uint[8,16,32,64]) | ||
idValue, err := handleNumeric(floatValue, fieldType.Type, fieldValue) | ||
idValue, err := handleNumeric(json.Number(data.ID), fieldType.Type, fieldValue) | ||
if err != nil { | ||
// We had a JSON float (numeric), but our field was not one of the | ||
// allowed numeric types | ||
|
@@ -271,7 +267,10 @@ func unmarshalNode(data *Node, model reflect.Value, included *map[string]*Node) | |
buf := bytes.NewBuffer(nil) | ||
|
||
json.NewEncoder(buf).Encode(data.Relationships[args[1]]) | ||
json.NewDecoder(buf).Decode(relationship) | ||
|
||
decoder := json.NewDecoder(buf) | ||
decoder.UseNumber() | ||
decoder.Decode(relationship) | ||
|
||
data := relationship.Data | ||
models := reflect.New(fieldValue.Type()).Elem() | ||
|
@@ -298,10 +297,11 @@ func unmarshalNode(data *Node, model reflect.Value, included *map[string]*Node) | |
|
||
buf := bytes.NewBuffer(nil) | ||
|
||
json.NewEncoder(buf).Encode( | ||
data.Relationships[args[1]], | ||
) | ||
json.NewDecoder(buf).Decode(relationship) | ||
json.NewEncoder(buf).Encode(data.Relationships[args[1]]) | ||
|
||
decoder := json.NewDecoder(buf) | ||
decoder.UseNumber() | ||
decoder.Decode(relationship) | ||
|
||
/* | ||
http://jsonapi.org/format/#document-resource-object-relationships | ||
|
@@ -416,9 +416,12 @@ func unmarshalAttribute( | |
return | ||
} | ||
|
||
// JSON value was a float (numeric) | ||
if value.Kind() == reflect.Float64 { | ||
value, err = handleNumeric(attribute, fieldType, fieldValue) | ||
switch attribute.(type) { | ||
case json.Number: | ||
value, err = handleNumeric(attribute.(json.Number), fieldType, fieldValue) | ||
return | ||
case float64: | ||
value, err = handleNumeric(json.Number(fmt.Sprint(attribute)), fieldType, fieldValue) | ||
quetzyg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return | ||
} | ||
|
||
|
@@ -495,27 +498,26 @@ func handleTime(attribute interface{}, args []string, fieldValue reflect.Value) | |
return reflect.ValueOf(t), nil | ||
} | ||
|
||
var at int64 | ||
switch v.Interface().(type) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The original logic was kept, since we're still checking the type of the I wonder if we should check the |
||
case json.Number: | ||
i, err := v.Interface().(json.Number).Int64() | ||
if err == nil { | ||
return reflect.ValueOf(time.Unix(i, 0)), nil | ||
} | ||
|
||
if v.Kind() == reflect.Float64 { | ||
at = int64(v.Interface().(float64)) | ||
} else if v.Kind() == reflect.Int { | ||
at = v.Int() | ||
} else { | ||
return reflect.ValueOf(time.Now()), ErrInvalidTime | ||
f, err := v.Interface().(json.Number).Float64() | ||
if err == nil { | ||
return reflect.ValueOf(time.Unix(int64(f), 0)), nil | ||
} | ||
} | ||
|
||
t := time.Unix(at, 0) | ||
|
||
return reflect.ValueOf(t), nil | ||
return reflect.ValueOf(time.Now()), ErrInvalidTime | ||
} | ||
|
||
func handleNumeric( | ||
attribute interface{}, | ||
attribute json.Number, | ||
fieldType reflect.Type, | ||
fieldValue reflect.Value) (reflect.Value, error) { | ||
v := reflect.ValueOf(attribute) | ||
floatValue := v.Interface().(float64) | ||
|
||
var kind reflect.Kind | ||
if fieldValue.Kind() == reflect.Ptr { | ||
|
@@ -524,50 +526,41 @@ func handleNumeric( | |
kind = fieldType.Kind() | ||
} | ||
|
||
var numericValue reflect.Value | ||
i, err := attribute.Int64() | ||
|
||
switch kind { | ||
case reflect.Int: | ||
n := int(floatValue) | ||
numericValue = reflect.ValueOf(&n) | ||
return reflect.ValueOf(int(i)), err | ||
case reflect.Int8: | ||
n := int8(floatValue) | ||
numericValue = reflect.ValueOf(&n) | ||
return reflect.ValueOf(int8(i)), err | ||
case reflect.Int16: | ||
n := int16(floatValue) | ||
numericValue = reflect.ValueOf(&n) | ||
return reflect.ValueOf(int16(i)), err | ||
case reflect.Int32: | ||
n := int32(floatValue) | ||
numericValue = reflect.ValueOf(&n) | ||
return reflect.ValueOf(int32(i)), err | ||
case reflect.Int64: | ||
n := int64(floatValue) | ||
numericValue = reflect.ValueOf(&n) | ||
return reflect.ValueOf(i), err | ||
case reflect.Uint: | ||
n := uint(floatValue) | ||
numericValue = reflect.ValueOf(&n) | ||
return reflect.ValueOf(uint(i)), err | ||
case reflect.Uint8: | ||
n := uint8(floatValue) | ||
numericValue = reflect.ValueOf(&n) | ||
return reflect.ValueOf(uint8(i)), err | ||
case reflect.Uint16: | ||
n := uint16(floatValue) | ||
numericValue = reflect.ValueOf(&n) | ||
return reflect.ValueOf(uint16(i)), err | ||
case reflect.Uint32: | ||
n := uint32(floatValue) | ||
numericValue = reflect.ValueOf(&n) | ||
return reflect.ValueOf(uint32(i)), err | ||
case reflect.Uint64: | ||
n := uint64(floatValue) | ||
numericValue = reflect.ValueOf(&n) | ||
return reflect.ValueOf(uint64(i)), err | ||
} | ||
|
||
f, err := attribute.Float64() | ||
|
||
switch kind { | ||
case reflect.Float32: | ||
n := float32(floatValue) | ||
numericValue = reflect.ValueOf(&n) | ||
return reflect.ValueOf(float32(f)), err | ||
case reflect.Float64: | ||
n := floatValue | ||
numericValue = reflect.ValueOf(&n) | ||
default: | ||
return reflect.Value{}, ErrUnknownFieldNumberType | ||
return reflect.ValueOf(f), err | ||
} | ||
|
||
return numericValue, nil | ||
return reflect.Value{}, ErrUnknownFieldNumberType | ||
} | ||
|
||
func handlePointer( | ||
|
@@ -580,6 +573,8 @@ func handlePointer( | |
var concreteVal reflect.Value | ||
|
||
switch cVal := attribute.(type) { | ||
case json.Number: | ||
return handleNumeric(attribute.(json.Number), fieldType, fieldValue) | ||
case string: | ||
concreteVal = reflect.ValueOf(&cVal) | ||
case bool: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -303,7 +303,7 @@ func TestUnmarshalSetsID(t *testing.T) { | |
t.Fatal(err) | ||
} | ||
|
||
if out.ID != 2 { | ||
if out.ID != 9223372036854775807 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we used this value previously, the test would fail; |
||
t.Fatalf("Did not set ID on dst interface") | ||
} | ||
} | ||
|
@@ -1070,7 +1070,7 @@ func samplePayload() io.Reader { | |
func samplePayloadWithID() io.Reader { | ||
payload := &OnePayload{ | ||
Data: &Node{ | ||
ID: "2", | ||
ID: "9223372036854775807", | ||
Type: "blogs", | ||
Attributes: map[string]interface{}{ | ||
"title": "New blog", | ||
|
Uh oh!
There was an error while loading. Please reload this page.