json.ErrorEmpty

master
Charles Iliya Krempeaux 2024-08-08 10:58:13 -07:00
parent 4ce81358ad
commit d4de6ca5ee
5 changed files with 70 additions and 11 deletions

9
errors.go 100644
View File

@ -0,0 +1,9 @@
package opt
import (
"github.com/reiver/go-erorr"
)
const (
errBadReflection = erorr.Error("opt: bad reflection")
)

9
go.mod
View File

@ -1,5 +1,10 @@
module github.com/reiver/go-opt module github.com/reiver/go-opt
go 1.18 go 1.22.4
require github.com/reiver/go-erorr v0.0.0-20240704145350-0485e21eaa82 require (
github.com/reiver/go-erorr v0.0.0-20240801233437-8cbde6d1fa3f
github.com/reiver/go-json v0.0.0-20240808163155-5fb56b49f847
)
require github.com/reiver/go-lck v0.0.0-20240808133902-b56df221c39f // indirect

8
go.sum
View File

@ -1,2 +1,6 @@
github.com/reiver/go-erorr v0.0.0-20240704145350-0485e21eaa82 h1:xxt7qL+7ZfRysXWXU2MpULOg/zWe5P+Fmw9VyUFCmZE= github.com/reiver/go-erorr v0.0.0-20240801233437-8cbde6d1fa3f h1:D1QSxKHm8U73XhjsW3SFLkT0zT5pKJi+1KGboMhY1Rk=
github.com/reiver/go-erorr v0.0.0-20240704145350-0485e21eaa82/go.mod h1:F0HbBf+Ak2ZlE8YkDW4Y+KxaUmT0KaaIJK6CXY3cJxE= github.com/reiver/go-erorr v0.0.0-20240801233437-8cbde6d1fa3f/go.mod h1:F0HbBf+Ak2ZlE8YkDW4Y+KxaUmT0KaaIJK6CXY3cJxE=
github.com/reiver/go-json v0.0.0-20240808163155-5fb56b49f847 h1:Y8BYW4keqqtdEWECdG7Pg60U0awT3DioXiIfcXvWhMY=
github.com/reiver/go-json v0.0.0-20240808163155-5fb56b49f847/go.mod h1:ns4kpzbK+OyMUZYT8UmBxrsYWNmvB/irZGmyIh99cxY=
github.com/reiver/go-lck v0.0.0-20240808133902-b56df221c39f h1:KBVWBoNIM8mHkUR3dP64hm2p2vxoD5xHZ6wUllCjFTc=
github.com/reiver/go-lck v0.0.0-20240808133902-b56df221c39f/go.mod h1:PFseSi8S0CBkc+YB6jYWtogPk83LumclnYJZZBQJJhs=

View File

@ -1,7 +1,11 @@
package opt package opt
import ( import (
"encoding/json" "encoding"
"fmt"
"reflect"
"github.com/reiver/go-json"
"github.com/reiver/go-erorr" "github.com/reiver/go-erorr"
) )
@ -11,15 +15,22 @@ var _ json.Marshaler = Nothing[string]()
// MarshalJSON makes it so json.Marshaler is implemented. // MarshalJSON makes it so json.Marshaler is implemented.
func (receiver Optional[T]) MarshalJSON() ([]byte, error) { func (receiver Optional[T]) MarshalJSON() ([]byte, error) {
switch interface{}(receiver.value).(type) { switch interface{}(receiver.value).(type) {
case bool, string, json.Marshaler: case json.Marshaler, encoding.TextMarshaler, bool, int, int8, int16, int32, int64, string, uint, uint8, uint16, uint32, uint64:
// these are OK. // these are OK.
default: default:
return nil, erorr.Errorf("opt: cannot marshal something of type %T into JSON because parameterized type is %T rather than bool, string, or json.Marshaler", receiver, receiver.value) var reflectedType reflect.Type = reflect.TypeOf(receiver.value)
if nil == reflectedType {
return nil, errBadReflection
}
if reflect.Struct != reflectedType.Kind() {
return nil, erorr.Errorf("opt: cannot marshal something of type %T into JSON because parameterized type is %T is not supported", receiver, receiver.value)
}
} }
if receiver.IsNothing() { if receiver.IsNothing() {
return nil, erorr.Errorf("opt: cannot marshal opt.Nothing[%T]() into JSON", receiver.value) return nil, json.ErrEmpty(fmt.Sprintf("opt: cannot marshal opt.Nothing[%T]() into JSON", receiver.value))
} }
return json.Marshal(receiver.value) return json.Marshal(receiver.value)

View File

@ -10,88 +10,118 @@ func TestOptional_MarshalJSON_int(t *testing.T) {
tests := []struct{ tests := []struct{
Value opt.Optional[int] Value opt.Optional[int]
Expected string
}{ }{
{ {
Value: opt.Something(-65536), Value: opt.Something(-65536),
Expected: `-65536`,
}, },
{ {
Value: opt.Something(-65535), Value: opt.Something(-65535),
Expected: `-65535`,
}, },
{ {
Value: opt.Something(-256), Value: opt.Something(-256),
Expected: `-256`,
}, },
{ {
Value: opt.Something(-255), Value: opt.Something(-255),
Expected: `-255`,
}, },
{ {
Value: opt.Something(-5), Value: opt.Something(-5),
Expected: `-5`,
}, },
{ {
Value: opt.Something(-4), Value: opt.Something(-4),
Expected: `-4`,
}, },
{ {
Value: opt.Something(-3), Value: opt.Something(-3),
Expected: `-3`,
}, },
{ {
Value: opt.Something(-2), Value: opt.Something(-2),
Expected: `-2`,
}, },
{ {
Value: opt.Something(-1), Value: opt.Something(-1),
Expected: `-1`,
}, },
{ {
Value: opt.Something(0), Value: opt.Something(0),
Expected: `0`,
}, },
{ {
Value: opt.Something(1), Value: opt.Something(1),
Expected: `1`,
}, },
{ {
Value: opt.Something(2), Value: opt.Something(2),
Expected: `2`,
}, },
{ {
Value: opt.Something(3), Value: opt.Something(3),
Expected: `3`,
}, },
{ {
Value: opt.Something(4), Value: opt.Something(4),
Expected: `4`,
}, },
{ {
Value: opt.Something(5), Value: opt.Something(5),
Expected: `5`,
}, },
{ {
Value: opt.Something(255), Value: opt.Something(255),
Expected: `255`,
}, },
{ {
Value: opt.Something(256), Value: opt.Something(256),
Expected: `256`,
}, },
{ {
Value: opt.Something(65535), Value: opt.Something(65535),
Expected: `65535`,
}, },
{ {
Value: opt.Something(65536), Value: opt.Something(65536),
Expected: `65536`,
}, },
} }
for testNumber, test := range tests { for testNumber, test := range tests {
actualBytes, err := test.Value.MarshalJSON() actualBytes, err := test.Value.MarshalJSON()
if nil == err { if nil != err {
t.Errorf("For test #%d, expected an error but did not actually get one." , testNumber) t.Errorf("For test #%d, did not expect an error but actually got one." , testNumber)
t.Logf("ACTUAL BYTES: %q", actualBytes)
t.Logf("ERROR: (%T) %s", err, err) t.Logf("ERROR: (%T) %s", err, err)
t.Logf("VALUE: %#v", test.Value) t.Logf("VALUE: %#v", test.Value)
continue continue
} }
actual := string(actualBytes)
expected := test.Expected
if expected != actual {
t.Errorf("For test #%d, the actual value for the JSON marshaling is not what was expected.", testNumber)
t.Logf("EXPECTED: %q", expected)
t.Logf("ACTUAL: %q", actual)
t.Logf("VALUE: %#v", test.Value)
continue
}
} }
} }