diff --git a/optional.go b/optional.go index 530d16e..e46dafc 100644 --- a/optional.go +++ b/optional.go @@ -2,7 +2,6 @@ package opt import ( "fmt" - "encoding/json" ) // Optional represents an optional value. @@ -170,15 +169,6 @@ func (receiver Optional[T]) GoString() string { return fmt.Sprintf("opt.Something[%T](%#v)", receiver.value, receiver.value) } -// MarshalJSON makes it so json.Marshaler is implemented. -func (receiver Optional[string]) MarshalJSON() ([]byte, error) { - if !receiver.something { - return nil, fmt.Errorf("cannot marshal opt.Nothing[%T]()", receiver.value) - } - - return json.Marshal(receiver.value) -} - // WhenNothing will call ‘fn’ when ‘receiver’ is holding nothing. // // It will not call ‘fn’ when ‘receier’ is hold something. diff --git a/optional_marshaljson.go b/optional_marshaljson.go new file mode 100644 index 0000000..6233092 --- /dev/null +++ b/optional_marshaljson.go @@ -0,0 +1,19 @@ +package opt + +import ( + "fmt" + "encoding/json" +) + +type jsonMarshaler interface { + bool | string +} + +// MarshalJSON makes it so json.Marshaler is implemented. +func (receiver Optional[jsonMarshal]) MarshalJSON() ([]byte, error) { + if !receiver.something { + return nil, fmt.Errorf("cannot marshal opt.Nothing[%T]()", receiver.value) + } + + return json.Marshal(receiver.value) +} diff --git a/optional_marshaljson_bool_test.go b/optional_marshaljson_bool_test.go new file mode 100644 index 0000000..18a88dd --- /dev/null +++ b/optional_marshaljson_bool_test.go @@ -0,0 +1,46 @@ +package opt_test + +import ( + "testing" + + "sourcecode.social/reiver/go-opt" +) + +func TestOptional_MarshalJSON_bool(t *testing.T) { + + tests := []struct{ + Value opt.Optional[bool] + Expected string + }{ + { + Value: opt.Something(false), + Expected: "false", + }, + { + Value: opt.Something(true), + Expected: "true", + }, + } + + for testNumber, test := range tests { + + actualBytes, err := test.Value.MarshalJSON() + if nil != err { + t.Errorf("For test #%d, did not expect an error but actually got one." , testNumber) + t.Logf("ERROR: (%T) %s", err, err) + t.Logf("VALUE: %#v", test.Value) + 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 + } + } +} diff --git a/optional_marshaljson_string_test.go b/optional_marshaljson_string_test.go new file mode 100644 index 0000000..b33a837 --- /dev/null +++ b/optional_marshaljson_string_test.go @@ -0,0 +1,105 @@ +package opt_test + +import ( + "testing" + + "sourcecode.social/reiver/go-opt" +) + +func TestOptional_MarshalJSON_string(t *testing.T) { + + tests := []struct{ + Value opt.Optional[string] + Expected string + }{ + { + Value: opt.Something(""), + Expected: `""`, + }, + + + + { + Value: opt.Something("apple"), + Expected: `"apple"`, + }, + { + Value: opt.Something("banana"), + Expected: `"banana"`, + }, + { + Value: opt.Something("cherry"), + Expected: `"cherry"`, + }, + + + + { + Value: opt.Something("ONCE"), + Expected: `"ONCE"`, + }, + { + Value: opt.Something("TWICE"), + Expected: `"TWICE"`, + }, + { + Value: opt.Something("THRICE"), + Expected: `"THRICE"`, + }, + { + Value: opt.Something("FOURCE"), + Expected: `"FOURCE"`, + }, + + + + { + Value: opt.Something("🙂"), + Expected: `"🙂"`, + }, + { + Value: opt.Something("😈"), + Expected: `"😈"`, + }, + { + Value: opt.Something("❤️"), + Expected: `"❤️"`, + }, + + + + { + Value: opt.Something("٠١٢٣۴۵۶٧٨٩"), + Expected: `"٠١٢٣۴۵۶٧٨٩"`, + }, + + + + { + Value: opt.Something("𐏑𐏓𐏕"), + Expected: `"𐏑𐏓𐏕"`, + }, + } + + for testNumber, test := range tests { + + actualBytes, err := test.Value.MarshalJSON() + if nil != err { + t.Errorf("For test #%d, did not expect an error but actually got one." , testNumber) + t.Logf("ERROR: (%T) %s", err, err) + t.Logf("VALUE: %#v", test.Value) + 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 + } + } +}