diff --git a/README.md b/README.md index 9710f43..1a897aa 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,20 @@ This helps to work-around that numbers in JSON are effectively "broken". Online documentation, which includes examples, can be found at: http://godoc.org/sourcecode.social/reiver/go-jsonint [![GoDoc](https://godoc.org/sourcecode.social/reiver/go-jsonint?status.svg)](https://godoc.org/sourcecode.social/reiver/go-jsonint) + +## Example + +Here is an example: +```go +type Account struct { + FollowersCount jsonint.Int `json:"followers_count"` + FollowingCount jsonint.Int `json:"following_count"` + StatusexCount jsonint.Int `json:"statuses_count"` +} + +// ... + +var account Account + +err := json.Unmarshal(data, &account) +``` diff --git a/errors.go b/errors.go index afd6f8a..5ae6487 100644 --- a/errors.go +++ b/errors.go @@ -5,6 +5,5 @@ import ( ) const ( - errNilReceiver = erorr.Error("jsonint: nil receiver") - errCannotMarshalNothingIntoJSON = erorr.Error("jsonint: cannot marshal jsonint.Nothing() into JSON") + errNilReceiver = erorr.Error("jsonint: nil receiver") ) diff --git a/int.go b/int.go index 2f5dc49..de82756 100644 --- a/int.go +++ b/int.go @@ -5,43 +5,45 @@ import ( "strconv" "sourcecode.social/reiver/go-erorr" - "sourcecode.social/reiver/go-opt" ) var _ json.Marshaler = Int{} var _ json.Unmarshaler = new(Int) type Int struct { - value opt.Optional[string] -} - -func Nothing() Int { - return Int{} + value string } func Int64(value int64) Int { + if 0 == value { + return Int{} + } + return Int{ - value: opt.Something(strconv.FormatInt(value, 10)), + value: strconv.FormatInt(value, 10), } } func Uint64(value uint64) Int { - return Int{ - value: opt.Something(strconv.FormatUint(value, 10)), + if 0 == value { + return Int{} } -} -func (receiver Int) Get() (string, bool) { - return receiver.value.Get() + return Int{ + value: strconv.FormatUint(value, 10), + } } func (receiver Int) MarshalJSON() ([]byte, error) { - value, found := receiver.value.Get() - if !found { - return nil, errCannotMarshalNothingIntoJSON + return []byte(receiver.String()), nil +} + +func (receiver Int) String() string { + if "" == receiver.value { + return "0" } - return []byte(value), nil + return receiver.value } func (receiver *Int) UnmarshalJSON(data []byte) error { @@ -53,7 +55,14 @@ func (receiver *Int) UnmarshalJSON(data []byte) error { return erorr.Errorf("jsonint: cannot unmarshal %q into value of type %T", data, Int{}) } - receiver.value = opt.Something(string(data)) + s := string(data) + switch s { + case "0","-0","+0": + receiver.value = "" + return nil + } + + receiver.value = string(data) return nil } diff --git a/int_marshaljson_test.go b/int_marshaljson_test.go index 58de042..8ec5323 100644 --- a/int_marshaljson_test.go +++ b/int_marshaljson_test.go @@ -12,6 +12,13 @@ func TestInt_MarshalJSON(t *testing.T) { Int jsonint.Int Expected string }{ + { + Int: jsonint.Int{}, + Expected: "0", + }, + + + { Int: jsonint.Int64(-65537), Expected: "-65537", @@ -191,20 +198,3 @@ func TestInt_MarshalJSON(t *testing.T) { } } } - -func TestInt_MarshalJSON_fail(t *testing.T) { - - var datum jsonint.Int - - actualBytes, err := datum.MarshalJSON() - if nil == err { - t.Error("Expected an error but did not actually get one.") - return - } - if nil != actualBytes { - t.Error("Expected return bytes to be nil but actually wasn't.") - t.Logf("ACTUAL BYTES: %#v", actualBytes) - t.Logf("ACTUAL BYTES: %q", actualBytes) - return - } -} diff --git a/int_unmarshaljson_test.go b/int_unmarshaljson_test.go index cca04c7..a58a41c 100644 --- a/int_unmarshaljson_test.go +++ b/int_unmarshaljson_test.go @@ -3,6 +3,8 @@ package jsonint_test import ( "testing" + "encoding/json" + "sourcecode.social/reiver/go-jsonint" ) @@ -251,3 +253,79 @@ func TestInt_UnmarshalJSON(t *testing.T) { } } } + +func TestInt_UnmarshalJSON_fail(t *testing.T) { + + tests := []struct{ + JSON []byte + }{ + { + JSON: nil, + }, + + + + { + JSON: []byte{}, + }, + + + + { + JSON: []byte(""), + }, + + + + { + JSON: []byte(" "), + }, + { + JSON: []byte(" "), + }, + { + JSON: []byte(" "), + }, + + + + { + JSON: []byte("apple"), + }, + { + JSON: []byte("banana"), + }, + { + JSON: []byte("cherry"), + }, + + + + { + JSON: []byte("ONE"), + }, + { + JSON: []byte("TWO"), + }, + { + JSON: []byte("THREE"), + }, + { + JSON: []byte("FOUR"), + }, + { + JSON: []byte("FIVE"), + }, + } + + for testNumber, test := range tests { + + var actual jsonint.Int + + err := json.Unmarshal(test.JSON, &actual) + if nil == err { + t.Errorf("For test #%d, expected an error but did not actually get one.", testNumber) + continue + } + } +} diff --git a/zero_test.go b/zero_test.go new file mode 100644 index 0000000..0572b77 --- /dev/null +++ b/zero_test.go @@ -0,0 +1,37 @@ +package jsonint_test + +import ( + "testing" + + "encoding/json" + + "sourcecode.social/reiver/go-jsonint" +) + +func TestZero(t *testing.T) { + + var nothing jsonint.Int + + var int64zero jsonint.Int = jsonint.Int64(0) + var uint64zero jsonint.Int = jsonint.Uint64(0) + + var jsonzero jsonint.Int + { + var data []byte = []byte("0") + + err := json.Unmarshal(data, &jsonzero) + if nil != err { + panic(err) + } + } + + if nothing != int64zero { + t.Error("nothing ≠ int64zero") + } + if nothing != uint64zero { + t.Error("nothing ≠ uint64zero") + } + if nothing != jsonzero { + t.Error("nothing ≠ json64zero") + } +}