From bc188140f0b03bd6fecbf956839ea8dcf0321320 Mon Sep 17 00:00:00 2001 From: mavolin <48887425+mavolin@users.noreply.github.com> Date: Mon, 11 May 2020 23:32:22 +0200 Subject: [PATCH] Utils: add NullableX types in option --- utils/json/nullable/bool.go | 14 ------ utils/json/nullable/nullable.go | 2 - utils/json/nullable/number.go | 25 ---------- utils/json/nullable/string.go | 12 ----- utils/json/option/bool.go | 47 ++++++++++++++++++ utils/json/option/number.go | 88 +++++++++++++++++++++++++++++++++ utils/json/option/string.go | 47 ++++++++++++++++-- 7 files changed, 179 insertions(+), 56 deletions(-) delete mode 100644 utils/json/nullable/bool.go delete mode 100644 utils/json/nullable/nullable.go delete mode 100644 utils/json/nullable/number.go delete mode 100644 utils/json/nullable/string.go diff --git a/utils/json/nullable/bool.go b/utils/json/nullable/bool.go deleted file mode 100644 index 0f76d29..0000000 --- a/utils/json/nullable/bool.go +++ /dev/null @@ -1,14 +0,0 @@ -package nullable - -// Bool is a nullable version of a bool. -type Bool *bool - -var ( - True = newBool(true) - False = newBool(false) -) - -// newBool creates a new Bool with the value of the passed bool. -func newBool(b bool) Bool { - return &b -} diff --git a/utils/json/nullable/nullable.go b/utils/json/nullable/nullable.go deleted file mode 100644 index dab82ee..0000000 --- a/utils/json/nullable/nullable.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package nullable provides nullable types that get serialized to JSON null. -package nullable diff --git a/utils/json/nullable/number.go b/utils/json/nullable/number.go deleted file mode 100644 index 97ac219..0000000 --- a/utils/json/nullable/number.go +++ /dev/null @@ -1,25 +0,0 @@ -package nullable - -type ( - // Uint is a nullable version of an unsigned integer (uint). - Uint *uint - // Int is a nullable version of an integer (int). - Int *int -) - -var ( - // ZeroUint is a Uint with 0 as value. - ZeroUint = NewUint(0) - // ZeroInt is an Int with 0 as value. - ZeroInt = NewInt(0) -) - -// NewUint creates a new Uint using the value of the passed uint. -func NewUint(u uint) Uint { - return &u -} - -// NewInt creates a new Int using the value of the passed int. -func NewInt(i int) Int { - return &i -} diff --git a/utils/json/nullable/string.go b/utils/json/nullable/string.go deleted file mode 100644 index e3eaefa..0000000 --- a/utils/json/nullable/string.go +++ /dev/null @@ -1,12 +0,0 @@ -package nullable - -// String is a nullable version of a string. -type String *string - -// EmptyString is a zero-length string. -var EmptyString = NewString("") - -// NewString creates a new String with the value of the passed string. -func NewString(s string) String { - return &s -} diff --git a/utils/json/option/bool.go b/utils/json/option/bool.go index 8e3482f..b28b146 100644 --- a/utils/json/option/bool.go +++ b/utils/json/option/bool.go @@ -1,5 +1,9 @@ package option +import "strconv" + +// ================================ Bool ================================ + // Bool is the option type for bool. type Bool *bool @@ -10,3 +14,46 @@ var ( // newBool creates a new Bool with the value of the passed bool. func newBool(b bool) Bool { return &b } + +// ================================ NullableBool ================================ + +// NullableBool is the nullable type for bool. +type NullableBool = *nullableBool + +type nullableBool struct { + Val bool + Init bool +} + +var ( + // NullBool serializes to JSON null. + NullBool = &nullableBool{} + NullableTrue = &nullableBool{ + Val: true, + Init: true, + } + NullableFalse = &nullableBool{ + Val: false, + Init: true, + } +) + +func (b nullableBool) MarshalJSON() ([]byte, error) { + if !b.Init { + return []byte("null"), nil + } + return []byte(strconv.FormatBool(b.Val)), nil +} + +func (b *nullableBool) UnmarshalJSON(json []byte) (err error) { + s := string(json) + + if s == "null" { + b.Init = false + return + } + + b.Val, err = strconv.ParseBool(s) + + return +} diff --git a/utils/json/option/number.go b/utils/json/option/number.go index f8a5b18..76a69fe 100644 --- a/utils/json/option/number.go +++ b/utils/json/option/number.go @@ -1,5 +1,7 @@ package option +import "strconv" + // ================================ Uint ================================ // Uint is the option type for unsigned integers (uint). @@ -21,3 +23,89 @@ var ZeroInt = NewInt(0) // NewInt creates a new Int using the value of the passed int. func NewInt(i int) Int { return &i } + +// ================================ NullableUint ================================ + +// NullableUint is a nullable version of an unsigned integer (uint). +type NullableUint = *nullableUint + +type nullableUint struct { + Val uint + Init bool +} + +// NullUint serializes to JSON null. +var NullUint = &nullableUint{} + +// NewUint creates a new non-null NullableUint using the value of the passed uint. +func NewNullableUint(v uint) NullableUint { + return &nullableUint{ + Val: v, + Init: true, + } +} + +func (u nullableUint) MarshalJSON() ([]byte, error) { + if !u.Init { + return []byte("null"), nil + } + return []byte(strconv.FormatUint(uint64(u.Val), 10)), nil +} + +func (u *nullableUint) UnmarshalJSON(json []byte) error { + s := string(json) + + if s == "null" { + u.Init = false + return nil + } + + v, err := strconv.ParseUint(s, 10, 64) + + u.Val = uint(v) + + return err +} + +// ================================ NullableInt ================================ + +// NullableInt is a nullable version of an integer (int). +type NullableInt *nullableInt + +type nullableInt struct { + Val int + Init bool +} + +// NullUint serializes to JSON null. +var NullInt = &nullableUint{} + +// NewInt creates a new non-null NullableInt using the value of the passed int. +func NewNullableInt(v int) NullableInt { + return &nullableInt{ + Val: v, + Init: true, + } +} + +func (i nullableInt) MarshalJSON() ([]byte, error) { + if !i.Init { + return []byte("null"), nil + } + return []byte(strconv.FormatUint(uint64(i.Val), 10)), nil +} + +func (i *nullableInt) UnmarshalJSON(json []byte) error { + s := string(json) + + if s == "null" { + i.Init = false + return nil + } + + v, err := strconv.ParseUint(s, 10, 64) + + i.Val = int(v) + + return err +} diff --git a/utils/json/option/string.go b/utils/json/option/string.go index 74ca0c6..44a942e 100644 --- a/utils/json/option/string.go +++ b/utils/json/option/string.go @@ -1,10 +1,51 @@ package option +import ( + "encoding/json" +) + +// ================================ String ================================ + // String is the option type for strings. type String *string -// EmptyString is a zero-length string. -var EmptyString = NewString("") - // NewString creates a new String with the value of the passed string. func NewString(s string) String { return &s } + +// ================================ NullableString ================================ + +// NullableString is a nullable version of a string. +type NullableString = *nullableString + +type nullableString struct { + Val string + Init bool +} + +// NullBool serializes to JSON null. +var NullString = &nullableString{} + +// NewNullableString creates a new non-null NullableString with the value of the passed string. +func NewNullableString(v string) NullableString { + return &nullableString{ + Val: v, + Init: true, + } +} + +func (s nullableString) MarshalJSON() ([]byte, error) { + if !s.Init { + return []byte("null"), nil + } + + return []byte("\"" + s.Val + "\""), nil +} + +func (s *nullableString) UnmarshalJSON(b []byte) error { + if string(b) == "null" { + s.Init = false + return nil + } + + return json.Unmarshal(b, &s.Val) +}