diff --git a/type/interfaces.go b/type/interfaces.go index 4192c8a..e0f5683 100644 --- a/type/interfaces.go +++ b/type/interfaces.go @@ -1,6 +1,9 @@ package Type -import "database/sql" +import ( + "database/sql" + "encoding/json" +) // Created to abstract over Is_some and Is_ok type ValueContainer interface { @@ -47,4 +50,8 @@ var ( _ ValueContainer = (*Result[any])(nil) _ sql.Scanner = (*Optional[any])(nil) // _ sql.Scanner = (*Result[any])(nil) + _ json.Marshaler = (*Optional[any])(nil) + // _ json.Marshaler = (*Result[any])(nil) + _ json.Unmarshaler = (*Optional[any])(nil) + // _ json.Unmarshaler = (*Result[any])(nil) ) diff --git a/type/optional.go b/type/optional.go index 652c894..4cb2552 100644 --- a/type/optional.go +++ b/type/optional.go @@ -2,6 +2,7 @@ package Type import ( "database/sql" + "encoding/json" "fmt" "reflect" "time" @@ -253,3 +254,26 @@ ok: opt.present = true return Some[error](nil) } + +func (opt Optional[T]) MarshalJSON() ([]byte, error) { + if !opt.present { + // Return null for `omitempty` compatibility + return []byte("null"), nil + // panic("Tried to marshal an Optional that did not have a value!") + } + return json.Marshal(opt.value) +} + +func (opt *Optional[T]) UnmarshalJSON(data []byte) error { + if string(data) == "null" { + opt.present = false + return nil + } + var value T + if err := json.Unmarshal(data, &value); err != nil { + return err + } + opt.value = value + opt.present = true + return nil +}