Fix all unmarshaljson funcs and all types
This commit is contained in:
parent
1104869407
commit
fed49d7096
32 changed files with 521 additions and 839 deletions
8
bool.go
8
bool.go
|
@ -37,9 +37,6 @@ func BoolFromPtr(b *bool) Bool {
|
|||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
// It supports number and null input.
|
||||
// 0 will not be considered a null Bool.
|
||||
// It also supports unmarshalling a sql.NullBool.
|
||||
func (b *Bool) UnmarshalJSON(data []byte) error {
|
||||
if bytes.Equal(data, NullBytes) {
|
||||
b.Bool = false
|
||||
|
@ -56,8 +53,6 @@ func (b *Bool) UnmarshalJSON(data []byte) error {
|
|||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
// It will unmarshal to a null Bool if the input is a blank or not an integer.
|
||||
// It will return an error if the input is not an integer, blank, or "null".
|
||||
func (b *Bool) UnmarshalText(text []byte) error {
|
||||
str := string(text)
|
||||
switch str {
|
||||
|
@ -77,7 +72,6 @@ func (b *Bool) UnmarshalText(text []byte) error {
|
|||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
// It will encode null if this Bool is null.
|
||||
func (b Bool) MarshalJSON() ([]byte, error) {
|
||||
if !b.Valid {
|
||||
return []byte("null"), nil
|
||||
|
@ -89,7 +83,6 @@ func (b Bool) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
// It will encode a blank string if this Bool is null.
|
||||
func (b Bool) MarshalText() ([]byte, error) {
|
||||
if !b.Valid {
|
||||
return []byte{}, nil
|
||||
|
@ -115,7 +108,6 @@ func (b Bool) Ptr() *bool {
|
|||
}
|
||||
|
||||
// IsZero returns true for invalid Bools, for future omitempty support (Go 1.4?)
|
||||
// A non-null Bool with a 0 value will not be considered zero.
|
||||
func (b Bool) IsZero() bool {
|
||||
return !b.Valid
|
||||
}
|
||||
|
|
11
bool_test.go
11
bool_test.go
|
@ -6,9 +6,8 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
boolJSON = []byte(`true`)
|
||||
falseJSON = []byte(`false`)
|
||||
nullBoolJSON = []byte(`{"Bool":true,"Valid":true}`)
|
||||
boolJSON = []byte(`true`)
|
||||
falseJSON = []byte(`false`)
|
||||
)
|
||||
|
||||
func TestBoolFrom(t *testing.T) {
|
||||
|
@ -37,12 +36,6 @@ func TestUnmarshalBool(t *testing.T) {
|
|||
maybePanic(err)
|
||||
assertBool(t, b, "bool json")
|
||||
|
||||
var nb Bool
|
||||
err = json.Unmarshal(nullBoolJSON, &nb)
|
||||
if err == nil {
|
||||
panic("err should not be nil")
|
||||
}
|
||||
|
||||
var null Bool
|
||||
err = json.Unmarshal(nullJSON, &null)
|
||||
maybePanic(err)
|
||||
|
|
5
bytes.go
5
bytes.go
|
@ -40,8 +40,6 @@ func BytesFromPtr(b *[]byte) Bytes {
|
|||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
// If data is len 0 or nil, it will unmarshal to JSON null.
|
||||
// If not, it will copy your data slice into Bytes.
|
||||
func (b *Bytes) UnmarshalJSON(data []byte) error {
|
||||
if bytes.Equal(data, NullBytes) {
|
||||
b.Valid = false
|
||||
|
@ -60,7 +58,6 @@ func (b *Bytes) UnmarshalJSON(data []byte) error {
|
|||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
// It will unmarshal to nil if the text is nil or len 0.
|
||||
func (b *Bytes) UnmarshalText(text []byte) error {
|
||||
if text == nil || len(text) == 0 {
|
||||
b.Bytes = nil
|
||||
|
@ -74,7 +71,6 @@ func (b *Bytes) UnmarshalText(text []byte) error {
|
|||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
// It will encode null if the Bytes is nil.
|
||||
func (b Bytes) MarshalJSON() ([]byte, error) {
|
||||
if len(b.Bytes) == 0 || b.Bytes == nil {
|
||||
return []byte("null"), nil
|
||||
|
@ -83,7 +79,6 @@ func (b Bytes) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
// It will encode nil if the Bytes is invalid.
|
||||
func (b Bytes) MarshalText() ([]byte, error) {
|
||||
if !b.Valid {
|
||||
return nil, nil
|
||||
|
|
70
float32.go
70
float32.go
|
@ -1,35 +1,25 @@
|
|||
package null
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"gopkg.in/nullbio/null.v5/convert"
|
||||
)
|
||||
|
||||
// NullFloat32 is a replica of sql.NullFloat64 for float32 types.
|
||||
type NullFloat32 struct {
|
||||
// Float32 is a nullable float32.
|
||||
type Float32 struct {
|
||||
Float32 float32
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Float32 is a nullable float32.
|
||||
// It does not consider zero values to be null.
|
||||
// It will decode to null, not zero, if null.
|
||||
type Float32 struct {
|
||||
NullFloat32
|
||||
}
|
||||
|
||||
// NewFloat32 creates a new Float32
|
||||
func NewFloat32(f float32, valid bool) Float32 {
|
||||
return Float32{
|
||||
NullFloat32: NullFloat32{
|
||||
Float32: f,
|
||||
Valid: valid,
|
||||
},
|
||||
Float32: f,
|
||||
Valid: valid,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,33 +37,24 @@ func Float32FromPtr(f *float32) Float32 {
|
|||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
// It supports number and null input.
|
||||
// 0 will not be considered a null Float32.
|
||||
// It also supports unmarshalling a sql.NullFloat32.
|
||||
func (f *Float32) UnmarshalJSON(data []byte) error {
|
||||
var err error
|
||||
var v interface{}
|
||||
if err = json.Unmarshal(data, &v); err != nil {
|
||||
if bytes.Equal(data, NullBytes) {
|
||||
f.Valid = false
|
||||
f.Float32 = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
var x float64
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return err
|
||||
}
|
||||
switch x := v.(type) {
|
||||
case float64:
|
||||
f.Float32 = float32(x)
|
||||
case map[string]interface{}:
|
||||
err = json.Unmarshal(data, &f.NullFloat32)
|
||||
case nil:
|
||||
f.Valid = false
|
||||
return nil
|
||||
default:
|
||||
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.Float32", reflect.TypeOf(v).Name())
|
||||
}
|
||||
f.Valid = err == nil
|
||||
return err
|
||||
|
||||
f.Float32 = float32(x)
|
||||
f.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
// It will unmarshal to a null Float32 if the input is a blank or not an integer.
|
||||
// It will return an error if the input is not an integer, blank, or "null".
|
||||
func (f *Float32) UnmarshalText(text []byte) error {
|
||||
str := string(text)
|
||||
if str == "" || str == "null" {
|
||||
|
@ -90,7 +71,6 @@ func (f *Float32) UnmarshalText(text []byte) error {
|
|||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
// It will encode null if this Float32 is null.
|
||||
func (f Float32) MarshalJSON() ([]byte, error) {
|
||||
if !f.Valid {
|
||||
return []byte("null"), nil
|
||||
|
@ -99,7 +79,6 @@ func (f Float32) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
// It will encode a blank string if this Float32 is null.
|
||||
func (f Float32) MarshalText() ([]byte, error) {
|
||||
if !f.Valid {
|
||||
return []byte{}, nil
|
||||
|
@ -122,25 +101,24 @@ func (f Float32) Ptr() *float32 {
|
|||
}
|
||||
|
||||
// IsZero returns true for invalid Float32s, for future omitempty support (Go 1.4?)
|
||||
// A non-null Float32 with a 0 value will not be considered zero.
|
||||
func (f Float32) IsZero() bool {
|
||||
return !f.Valid
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullFloat32) Scan(value interface{}) error {
|
||||
func (f *Float32) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
n.Float32, n.Valid = 0, false
|
||||
f.Float32, f.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
return convert.ConvertAssign(&n.Float32, value)
|
||||
f.Valid = true
|
||||
return convert.ConvertAssign(&f.Float32, value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullFloat32) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
func (f Float32) Value() (driver.Value, error) {
|
||||
if !f.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return float64(n.Float32), nil
|
||||
return float64(f.Float32), nil
|
||||
}
|
||||
|
|
|
@ -6,8 +6,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
float32JSON = []byte(`1.2345`)
|
||||
nullFloat32JSON = []byte(`{"Float32":1.2345,"Valid":true}`)
|
||||
float32JSON = []byte(`1.2345`)
|
||||
)
|
||||
|
||||
func TestFloat32From(t *testing.T) {
|
||||
|
@ -36,11 +35,6 @@ func TestUnmarshalFloat32(t *testing.T) {
|
|||
maybePanic(err)
|
||||
assertFloat32(t, f, "float32 json")
|
||||
|
||||
var nf Float32
|
||||
err = json.Unmarshal(nullFloat32JSON, &nf)
|
||||
maybePanic(err)
|
||||
assertFloat32(t, nf, "sq.NullFloat32 json")
|
||||
|
||||
var null Float32
|
||||
err = json.Unmarshal(nullJSON, &null)
|
||||
maybePanic(err)
|
||||
|
|
68
float64.go
68
float64.go
|
@ -1,27 +1,25 @@
|
|||
package null
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"github.com/nullbio/null/convert"
|
||||
)
|
||||
|
||||
// Float64 is a nullable float64.
|
||||
// It does not consider zero values to be null.
|
||||
// It will decode to null, not zero, if null.
|
||||
type Float64 struct {
|
||||
sql.NullFloat64
|
||||
Float64 float64
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// NewFloat64 creates a new Float64
|
||||
func NewFloat64(f float64, valid bool) Float64 {
|
||||
return Float64{
|
||||
NullFloat64: sql.NullFloat64{
|
||||
Float64: f,
|
||||
Valid: valid,
|
||||
},
|
||||
Float64: f,
|
||||
Valid: valid,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,33 +37,22 @@ func Float64FromPtr(f *float64) Float64 {
|
|||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
// It supports number and null input.
|
||||
// 0 will not be considered a null Float64.
|
||||
// It also supports unmarshalling a sql.NullFloat64.
|
||||
func (f *Float64) UnmarshalJSON(data []byte) error {
|
||||
var err error
|
||||
var v interface{}
|
||||
if err = json.Unmarshal(data, &v); err != nil {
|
||||
return err
|
||||
}
|
||||
switch x := v.(type) {
|
||||
case float64:
|
||||
f.Float64 = float64(x)
|
||||
case map[string]interface{}:
|
||||
err = json.Unmarshal(data, &f.NullFloat64)
|
||||
case nil:
|
||||
if bytes.Equal(data, NullBytes) {
|
||||
f.Float64 = 0
|
||||
f.Valid = false
|
||||
return nil
|
||||
default:
|
||||
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.Float64", reflect.TypeOf(v).Name())
|
||||
}
|
||||
f.Valid = err == nil
|
||||
return err
|
||||
|
||||
if err := json.Unmarshal(data, &f.Float64); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
// It will unmarshal to a null Float64 if the input is a blank or not an integer.
|
||||
// It will return an error if the input is not an integer, blank, or "null".
|
||||
func (f *Float64) UnmarshalText(text []byte) error {
|
||||
str := string(text)
|
||||
if str == "" || str == "null" {
|
||||
|
@ -79,7 +66,6 @@ func (f *Float64) UnmarshalText(text []byte) error {
|
|||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
// It will encode null if this Float64 is null.
|
||||
func (f Float64) MarshalJSON() ([]byte, error) {
|
||||
if !f.Valid {
|
||||
return []byte("null"), nil
|
||||
|
@ -88,7 +74,6 @@ func (f Float64) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
// It will encode a blank string if this Float64 is null.
|
||||
func (f Float64) MarshalText() ([]byte, error) {
|
||||
if !f.Valid {
|
||||
return []byte{}, nil
|
||||
|
@ -111,7 +96,24 @@ func (f Float64) Ptr() *float64 {
|
|||
}
|
||||
|
||||
// IsZero returns true for invalid Float64s, for future omitempty support (Go 1.4?)
|
||||
// A non-null Float64 with a 0 value will not be considered zero.
|
||||
func (f Float64) IsZero() bool {
|
||||
return !f.Valid
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (f *Float64) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
f.Float64, f.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
f.Valid = true
|
||||
return convert.ConvertAssign(&f.Float64, value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (f Float64) Value() (driver.Value, error) {
|
||||
if !f.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return f.Float64, nil
|
||||
}
|
||||
|
|
|
@ -6,8 +6,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
float64JSON = []byte(`1.2345`)
|
||||
nullFloat64JSON = []byte(`{"Float64":1.2345,"Valid":true}`)
|
||||
float64JSON = []byte(`1.2345`)
|
||||
)
|
||||
|
||||
func TestFloat64From(t *testing.T) {
|
||||
|
@ -36,11 +35,6 @@ func TestUnmarshalFloat64(t *testing.T) {
|
|||
maybePanic(err)
|
||||
assertFloat64(t, f, "float64 json")
|
||||
|
||||
var nf Float64
|
||||
err = json.Unmarshal(nullFloat64JSON, &nf)
|
||||
maybePanic(err)
|
||||
assertFloat64(t, nf, "sq.NullFloat64 json")
|
||||
|
||||
var null Float64
|
||||
err = json.Unmarshal(nullJSON, &null)
|
||||
maybePanic(err)
|
||||
|
|
71
int.go
71
int.go
|
@ -1,35 +1,25 @@
|
|||
package null
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"gopkg.in/nullbio/null.v5/convert"
|
||||
)
|
||||
|
||||
// NullInt is a replica of sql.NullInt64 for int types.
|
||||
type NullInt struct {
|
||||
// Int is an nullable int.
|
||||
type Int struct {
|
||||
Int int
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Int is an nullable int.
|
||||
// It does not consider zero values to be null.
|
||||
// It will decode to null, not zero, if null.
|
||||
type Int struct {
|
||||
NullInt
|
||||
}
|
||||
|
||||
// NewInt creates a new Int
|
||||
func NewInt(i int, valid bool) Int {
|
||||
return Int{
|
||||
NullInt: NullInt{
|
||||
Int: i,
|
||||
Valid: valid,
|
||||
},
|
||||
Int: i,
|
||||
Valid: valid,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,34 +37,24 @@ func IntFromPtr(i *int) Int {
|
|||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
// It supports number and null input.
|
||||
// 0 will not be considered a null Int.
|
||||
// It also supports unmarshalling a sql.NullInt.
|
||||
func (i *Int) UnmarshalJSON(data []byte) error {
|
||||
var err error
|
||||
var v interface{}
|
||||
if err = json.Unmarshal(data, &v); err != nil {
|
||||
if bytes.Equal(data, NullBytes) {
|
||||
i.Valid = false
|
||||
i.Int = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
var x int64
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return err
|
||||
}
|
||||
switch v.(type) {
|
||||
case float64:
|
||||
// Unmarshal again, directly to int, to avoid intermediate float64
|
||||
err = json.Unmarshal(data, &i.Int)
|
||||
case map[string]interface{}:
|
||||
err = json.Unmarshal(data, &i.NullInt)
|
||||
case nil:
|
||||
i.Valid = false
|
||||
return nil
|
||||
default:
|
||||
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.Int", reflect.TypeOf(v).Name())
|
||||
}
|
||||
i.Valid = err == nil
|
||||
return err
|
||||
|
||||
i.Int = int(x)
|
||||
i.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
// It will unmarshal to a null Int if the input is a blank or not an integer.
|
||||
// It will return an error if the input is not an integer, blank, or "null".
|
||||
func (i *Int) UnmarshalText(text []byte) error {
|
||||
str := string(text)
|
||||
if str == "" || str == "null" {
|
||||
|
@ -91,7 +71,6 @@ func (i *Int) UnmarshalText(text []byte) error {
|
|||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
// It will encode null if this Int is null.
|
||||
func (i Int) MarshalJSON() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
return []byte("null"), nil
|
||||
|
@ -100,7 +79,6 @@ func (i Int) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
// It will encode a blank string if this Int is null.
|
||||
func (i Int) MarshalText() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
return []byte{}, nil
|
||||
|
@ -123,25 +101,24 @@ func (i Int) Ptr() *int {
|
|||
}
|
||||
|
||||
// IsZero returns true for invalid Ints, for future omitempty support (Go 1.4?)
|
||||
// A non-null Int with a 0 value will not be considered zero.
|
||||
func (i Int) IsZero() bool {
|
||||
return !i.Valid
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullInt) Scan(value interface{}) error {
|
||||
func (i *Int) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
n.Int, n.Valid = 0, false
|
||||
i.Int, i.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
return convert.ConvertAssign(&n.Int, value)
|
||||
i.Valid = true
|
||||
return convert.ConvertAssign(&i.Int, value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullInt) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
func (i Int) Value() (driver.Value, error) {
|
||||
if !i.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return int64(n.Int), nil
|
||||
return int64(i.Int), nil
|
||||
}
|
||||
|
|
73
int16.go
73
int16.go
|
@ -1,35 +1,27 @@
|
|||
package null
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"math"
|
||||
"strconv"
|
||||
|
||||
"gopkg.in/nullbio/null.v5/convert"
|
||||
)
|
||||
|
||||
// NullInt16 is a replica of sql.NullInt64 for int16 types.
|
||||
type NullInt16 struct {
|
||||
// Int16 is an nullable int16.
|
||||
type Int16 struct {
|
||||
Int16 int16
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Int16 is an nullable int16.
|
||||
// It does not consider zero values to be null.
|
||||
// It will decode to null, not zero, if null.
|
||||
type Int16 struct {
|
||||
NullInt16
|
||||
}
|
||||
|
||||
// NewInt16 creates a new Int16
|
||||
func NewInt16(i int16, valid bool) Int16 {
|
||||
return Int16{
|
||||
NullInt16: NullInt16{
|
||||
Int16: i,
|
||||
Valid: valid,
|
||||
},
|
||||
Int16: i,
|
||||
Valid: valid,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,34 +39,28 @@ func Int16FromPtr(i *int16) Int16 {
|
|||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
// It supports number and null input.
|
||||
// 0 will not be considered a null Int16.
|
||||
// It also supports unmarshalling a sql.NullInt16.
|
||||
func (i *Int16) UnmarshalJSON(data []byte) error {
|
||||
var err error
|
||||
var v interface{}
|
||||
if err = json.Unmarshal(data, &v); err != nil {
|
||||
if bytes.Equal(data, NullBytes) {
|
||||
i.Valid = false
|
||||
i.Int16 = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
var x int64
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return err
|
||||
}
|
||||
switch v.(type) {
|
||||
case float64:
|
||||
// Unmarshal again, directly to int16, to avoid intermediate float64
|
||||
err = json.Unmarshal(data, &i.Int16)
|
||||
case map[string]interface{}:
|
||||
err = json.Unmarshal(data, &i.NullInt16)
|
||||
case nil:
|
||||
i.Valid = false
|
||||
return nil
|
||||
default:
|
||||
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.Int16", reflect.TypeOf(v).Name())
|
||||
|
||||
if x > math.MaxInt16 {
|
||||
return fmt.Errorf("json: %d overflows max int16 value", x)
|
||||
}
|
||||
i.Valid = err == nil
|
||||
return err
|
||||
|
||||
i.Int16 = int16(x)
|
||||
i.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
// It will unmarshal to a null Int16 if the input is a blank or not an integer.
|
||||
// It will return an error if the input is not an integer, blank, or "null".
|
||||
func (i *Int16) UnmarshalText(text []byte) error {
|
||||
str := string(text)
|
||||
if str == "" || str == "null" {
|
||||
|
@ -91,7 +77,6 @@ func (i *Int16) UnmarshalText(text []byte) error {
|
|||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
// It will encode null if this Int16 is null.
|
||||
func (i Int16) MarshalJSON() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
return []byte("null"), nil
|
||||
|
@ -100,7 +85,6 @@ func (i Int16) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
// It will encode a blank string if this Int16 is null.
|
||||
func (i Int16) MarshalText() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
return []byte{}, nil
|
||||
|
@ -123,25 +107,24 @@ func (i Int16) Ptr() *int16 {
|
|||
}
|
||||
|
||||
// IsZero returns true for invalid Int16's, for future omitempty support (Go 1.4?)
|
||||
// A non-null Int16 with a 0 value will not be considered zero.
|
||||
func (i Int16) IsZero() bool {
|
||||
return !i.Valid
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullInt16) Scan(value interface{}) error {
|
||||
func (i *Int16) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
n.Int16, n.Valid = 0, false
|
||||
i.Int16, i.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
return convert.ConvertAssign(&n.Int16, value)
|
||||
i.Valid = true
|
||||
return convert.ConvertAssign(&i.Int16, value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullInt16) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
func (i Int16) Value() (driver.Value, error) {
|
||||
if !i.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return int64(n.Int16), nil
|
||||
return int64(i.Int16), nil
|
||||
}
|
||||
|
|
|
@ -2,14 +2,14 @@ package null
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var (
|
||||
int16JSON = []byte(`32766`)
|
||||
nullInt16JSON = []byte(`{"Int16":32766,"Valid":true}`)
|
||||
int16JSON = []byte(`32766`)
|
||||
)
|
||||
|
||||
func TestInt16From(t *testing.T) {
|
||||
|
@ -38,11 +38,6 @@ func TestUnmarshalInt16(t *testing.T) {
|
|||
maybePanic(err)
|
||||
assertInt16(t, i, "int16 json")
|
||||
|
||||
var ni Int16
|
||||
err = json.Unmarshal(nullInt16JSON, &ni)
|
||||
maybePanic(err)
|
||||
assertInt16(t, ni, "sq.NullInt16 json")
|
||||
|
||||
var null Int16
|
||||
err = json.Unmarshal(nullJSON, &null)
|
||||
maybePanic(err)
|
||||
|
@ -78,10 +73,11 @@ func TestUnmarshalInt16Overflow(t *testing.T) {
|
|||
var i Int16
|
||||
err := json.Unmarshal([]byte(strconv.FormatUint(uint64(int16Overflow), 10)), &i)
|
||||
maybePanic(err)
|
||||
|
||||
fmt.Println(i)
|
||||
// Attempt to overflow
|
||||
int16Overflow++
|
||||
err = json.Unmarshal([]byte(strconv.FormatUint(uint64(int16Overflow), 10)), &i)
|
||||
fmt.Println(i)
|
||||
if err == nil {
|
||||
panic("err should be present; decoded value overflows int16")
|
||||
}
|
||||
|
|
73
int32.go
73
int32.go
|
@ -1,35 +1,27 @@
|
|||
package null
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"math"
|
||||
"strconv"
|
||||
|
||||
"gopkg.in/nullbio/null.v5/convert"
|
||||
)
|
||||
|
||||
// NullInt32 is a replica of sql.NullInt64 for int32 types.
|
||||
type NullInt32 struct {
|
||||
// Int32 is an nullable int32.
|
||||
type Int32 struct {
|
||||
Int32 int32
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Int32 is an nullable int32.
|
||||
// It does not consider zero values to be null.
|
||||
// It will decode to null, not zero, if null.
|
||||
type Int32 struct {
|
||||
NullInt32
|
||||
}
|
||||
|
||||
// NewInt32 creates a new Int32
|
||||
func NewInt32(i int32, valid bool) Int32 {
|
||||
return Int32{
|
||||
NullInt32: NullInt32{
|
||||
Int32: i,
|
||||
Valid: valid,
|
||||
},
|
||||
Int32: i,
|
||||
Valid: valid,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,34 +39,28 @@ func Int32FromPtr(i *int32) Int32 {
|
|||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
// It supports number and null input.
|
||||
// 0 will not be considered a null Int32.
|
||||
// It also supports unmarshalling a sql.NullInt32.
|
||||
func (i *Int32) UnmarshalJSON(data []byte) error {
|
||||
var err error
|
||||
var v interface{}
|
||||
if err = json.Unmarshal(data, &v); err != nil {
|
||||
if bytes.Equal(data, NullBytes) {
|
||||
i.Valid = false
|
||||
i.Int32 = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
var x int64
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return err
|
||||
}
|
||||
switch v.(type) {
|
||||
case float64:
|
||||
// Unmarshal again, directly to int32, to avoid intermediate float64
|
||||
err = json.Unmarshal(data, &i.Int32)
|
||||
case map[string]interface{}:
|
||||
err = json.Unmarshal(data, &i.NullInt32)
|
||||
case nil:
|
||||
i.Valid = false
|
||||
return nil
|
||||
default:
|
||||
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.Int32", reflect.TypeOf(v).Name())
|
||||
|
||||
if x > math.MaxInt32 {
|
||||
return fmt.Errorf("json: %d overflows max int32 value", x)
|
||||
}
|
||||
i.Valid = err == nil
|
||||
return err
|
||||
|
||||
i.Int32 = int32(x)
|
||||
i.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
// It will unmarshal to a null Int32 if the input is a blank or not an integer.
|
||||
// It will return an error if the input is not an integer, blank, or "null".
|
||||
func (i *Int32) UnmarshalText(text []byte) error {
|
||||
str := string(text)
|
||||
if str == "" || str == "null" {
|
||||
|
@ -91,7 +77,6 @@ func (i *Int32) UnmarshalText(text []byte) error {
|
|||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
// It will encode null if this Int32 is null.
|
||||
func (i Int32) MarshalJSON() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
return []byte("null"), nil
|
||||
|
@ -100,7 +85,6 @@ func (i Int32) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
// It will encode a blank string if this Int32 is null.
|
||||
func (i Int32) MarshalText() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
return []byte{}, nil
|
||||
|
@ -123,25 +107,24 @@ func (i Int32) Ptr() *int32 {
|
|||
}
|
||||
|
||||
// IsZero returns true for invalid Int32's, for future omitempty support (Go 1.4?)
|
||||
// A non-null Int32 with a 0 value will not be considered zero.
|
||||
func (i Int32) IsZero() bool {
|
||||
return !i.Valid
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullInt32) Scan(value interface{}) error {
|
||||
func (i *Int32) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
n.Int32, n.Valid = 0, false
|
||||
i.Int32, i.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
return convert.ConvertAssign(&n.Int32, value)
|
||||
i.Valid = true
|
||||
return convert.ConvertAssign(&i.Int32, value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullInt32) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
func (i Int32) Value() (driver.Value, error) {
|
||||
if !i.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return int64(n.Int32), nil
|
||||
return int64(i.Int32), nil
|
||||
}
|
||||
|
|
|
@ -8,8 +8,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
int32JSON = []byte(`2147483646`)
|
||||
nullInt32JSON = []byte(`{"Int32":2147483646,"Valid":true}`)
|
||||
int32JSON = []byte(`2147483646`)
|
||||
)
|
||||
|
||||
func TestInt32From(t *testing.T) {
|
||||
|
@ -38,11 +37,6 @@ func TestUnmarshalInt32(t *testing.T) {
|
|||
maybePanic(err)
|
||||
assertInt32(t, i, "int32 json")
|
||||
|
||||
var ni Int32
|
||||
err = json.Unmarshal(nullInt32JSON, &ni)
|
||||
maybePanic(err)
|
||||
assertInt32(t, ni, "sq.NullInt32 json")
|
||||
|
||||
var null Int32
|
||||
err = json.Unmarshal(nullJSON, &null)
|
||||
maybePanic(err)
|
||||
|
|
71
int64.go
71
int64.go
|
@ -1,27 +1,25 @@
|
|||
package null
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"github.com/nullbio/null/convert"
|
||||
)
|
||||
|
||||
// Int64 is an nullable int64.
|
||||
// It does not consider zero values to be null.
|
||||
// It will decode to null, not zero, if null.
|
||||
type Int64 struct {
|
||||
sql.NullInt64
|
||||
Int64 int64
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// NewInt64 creates a new Int64
|
||||
func NewInt64(i int64, valid bool) Int64 {
|
||||
return Int64{
|
||||
NullInt64: sql.NullInt64{
|
||||
Int64: i,
|
||||
Valid: valid,
|
||||
},
|
||||
Int64: i,
|
||||
Valid: valid,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,34 +37,22 @@ func Int64FromPtr(i *int64) Int64 {
|
|||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
// It supports number and null input.
|
||||
// 0 will not be considered a null Int64.
|
||||
// It also supports unmarshalling a sql.NullInt64.
|
||||
func (i *Int64) UnmarshalJSON(data []byte) error {
|
||||
var err error
|
||||
var v interface{}
|
||||
if err = json.Unmarshal(data, &v); err != nil {
|
||||
if bytes.Equal(data, NullBytes) {
|
||||
i.Valid = false
|
||||
i.Int64 = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(data, &i.Int64); err != nil {
|
||||
return err
|
||||
}
|
||||
switch v.(type) {
|
||||
case float64:
|
||||
// Unmarshal again, directly to int64, to avoid intermediate float64
|
||||
err = json.Unmarshal(data, &i.Int64)
|
||||
case map[string]interface{}:
|
||||
err = json.Unmarshal(data, &i.NullInt64)
|
||||
case nil:
|
||||
i.Valid = false
|
||||
return nil
|
||||
default:
|
||||
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.Int64", reflect.TypeOf(v).Name())
|
||||
}
|
||||
i.Valid = err == nil
|
||||
return err
|
||||
|
||||
i.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
// It will unmarshal to a null Int64 if the input is a blank or not an integer.
|
||||
// It will return an error if the input is not an integer, blank, or "null".
|
||||
func (i *Int64) UnmarshalText(text []byte) error {
|
||||
str := string(text)
|
||||
if str == "" || str == "null" {
|
||||
|
@ -80,7 +66,6 @@ func (i *Int64) UnmarshalText(text []byte) error {
|
|||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
// It will encode null if this Int64 is null.
|
||||
func (i Int64) MarshalJSON() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
return []byte("null"), nil
|
||||
|
@ -89,7 +74,6 @@ func (i Int64) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
// It will encode a blank string if this Int64 is null.
|
||||
func (i Int64) MarshalText() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
return []byte{}, nil
|
||||
|
@ -112,7 +96,24 @@ func (i Int64) Ptr() *int64 {
|
|||
}
|
||||
|
||||
// IsZero returns true for invalid Int64's, for future omitempty support (Go 1.4?)
|
||||
// A non-null Int64 with a 0 value will not be considered zero.
|
||||
func (i Int64) IsZero() bool {
|
||||
return !i.Valid
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (i *Int64) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
i.Int64, i.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
i.Valid = true
|
||||
return convert.ConvertAssign(&i.Int64, value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (i Int64) Value() (driver.Value, error) {
|
||||
if !i.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return i.Int64, nil
|
||||
}
|
||||
|
|
|
@ -8,8 +8,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
int64JSON = []byte(`9223372036854775806`)
|
||||
nullInt64JSON = []byte(`{"Int64":9223372036854775806,"Valid":true}`)
|
||||
int64JSON = []byte(`9223372036854775806`)
|
||||
)
|
||||
|
||||
func TestInt64From(t *testing.T) {
|
||||
|
@ -38,11 +37,6 @@ func TestUnmarshalInt64(t *testing.T) {
|
|||
maybePanic(err)
|
||||
assertInt64(t, i, "int64 json")
|
||||
|
||||
var ni Int64
|
||||
err = json.Unmarshal(nullInt64JSON, &ni)
|
||||
maybePanic(err)
|
||||
assertInt64(t, ni, "sq.NullInt64 json")
|
||||
|
||||
var null Int64
|
||||
err = json.Unmarshal(nullJSON, &null)
|
||||
maybePanic(err)
|
||||
|
|
73
int8.go
73
int8.go
|
@ -1,35 +1,27 @@
|
|||
package null
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"math"
|
||||
"strconv"
|
||||
|
||||
"gopkg.in/nullbio/null.v5/convert"
|
||||
)
|
||||
|
||||
// NullInt8 is a replica of sql.NullInt64 for int8 types.
|
||||
type NullInt8 struct {
|
||||
// Int8 is an nullable int8.
|
||||
type Int8 struct {
|
||||
Int8 int8
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Int8 is an nullable int8.
|
||||
// It does not consider zero values to be null.
|
||||
// It will decode to null, not zero, if null.
|
||||
type Int8 struct {
|
||||
NullInt8
|
||||
}
|
||||
|
||||
// NewInt8 creates a new Int8
|
||||
func NewInt8(i int8, valid bool) Int8 {
|
||||
return Int8{
|
||||
NullInt8: NullInt8{
|
||||
Int8: i,
|
||||
Valid: valid,
|
||||
},
|
||||
Int8: i,
|
||||
Valid: valid,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,34 +39,28 @@ func Int8FromPtr(i *int8) Int8 {
|
|||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
// It supports number and null input.
|
||||
// 0 will not be considered a null Int8.
|
||||
// It also supports unmarshalling a sql.NullInt8.
|
||||
func (i *Int8) UnmarshalJSON(data []byte) error {
|
||||
var err error
|
||||
var v interface{}
|
||||
if err = json.Unmarshal(data, &v); err != nil {
|
||||
if bytes.Equal(data, NullBytes) {
|
||||
i.Valid = false
|
||||
i.Int8 = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
var x int64
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return err
|
||||
}
|
||||
switch v.(type) {
|
||||
case float64:
|
||||
// Unmarshal again, directly to int8, to avoid intermediate float64
|
||||
err = json.Unmarshal(data, &i.Int8)
|
||||
case map[string]interface{}:
|
||||
err = json.Unmarshal(data, &i.NullInt8)
|
||||
case nil:
|
||||
i.Valid = false
|
||||
return nil
|
||||
default:
|
||||
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.Int8", reflect.TypeOf(v).Name())
|
||||
|
||||
if x > math.MaxInt8 {
|
||||
return fmt.Errorf("json: %d overflows max int8 value", x)
|
||||
}
|
||||
i.Valid = err == nil
|
||||
return err
|
||||
|
||||
i.Int8 = int8(x)
|
||||
i.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
// It will unmarshal to a null Int8 if the input is a blank or not an integer.
|
||||
// It will return an error if the input is not an integer, blank, or "null".
|
||||
func (i *Int8) UnmarshalText(text []byte) error {
|
||||
str := string(text)
|
||||
if str == "" || str == "null" {
|
||||
|
@ -91,7 +77,6 @@ func (i *Int8) UnmarshalText(text []byte) error {
|
|||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
// It will encode null if this Int8 is null.
|
||||
func (i Int8) MarshalJSON() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
return []byte("null"), nil
|
||||
|
@ -100,7 +85,6 @@ func (i Int8) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
// It will encode a blank string if this Int8 is null.
|
||||
func (i Int8) MarshalText() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
return []byte{}, nil
|
||||
|
@ -123,25 +107,24 @@ func (i Int8) Ptr() *int8 {
|
|||
}
|
||||
|
||||
// IsZero returns true for invalid Int8's, for future omitempty support (Go 1.4?)
|
||||
// A non-null Int8 with a 0 value will not be considered zero.
|
||||
func (i Int8) IsZero() bool {
|
||||
return !i.Valid
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullInt8) Scan(value interface{}) error {
|
||||
func (i *Int8) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
n.Int8, n.Valid = 0, false
|
||||
i.Int8, i.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
return convert.ConvertAssign(&n.Int8, value)
|
||||
i.Valid = true
|
||||
return convert.ConvertAssign(&i.Int8, value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullInt8) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
func (i Int8) Value() (driver.Value, error) {
|
||||
if !i.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return int64(n.Int8), nil
|
||||
return int64(i.Int8), nil
|
||||
}
|
||||
|
|
|
@ -8,8 +8,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
int8JSON = []byte(`126`)
|
||||
nullInt8JSON = []byte(`{"Int8":126,"Valid":true}`)
|
||||
int8JSON = []byte(`126`)
|
||||
)
|
||||
|
||||
func TestInt8From(t *testing.T) {
|
||||
|
@ -38,11 +37,6 @@ func TestUnmarshalInt8(t *testing.T) {
|
|||
maybePanic(err)
|
||||
assertInt8(t, i, "int8 json")
|
||||
|
||||
var ni Int8
|
||||
err = json.Unmarshal(nullInt8JSON, &ni)
|
||||
maybePanic(err)
|
||||
assertInt8(t, ni, "sq.NullInt8 json")
|
||||
|
||||
var null Int8
|
||||
err = json.Unmarshal(nullJSON, &null)
|
||||
maybePanic(err)
|
||||
|
|
|
@ -6,8 +6,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
intJSON = []byte(`12345`)
|
||||
nullIntJSON = []byte(`{"Int":12345,"Valid":true}`)
|
||||
intJSON = []byte(`12345`)
|
||||
)
|
||||
|
||||
func TestIntFrom(t *testing.T) {
|
||||
|
@ -36,11 +35,6 @@ func TestUnmarshalInt(t *testing.T) {
|
|||
maybePanic(err)
|
||||
assertInt(t, i, "int json")
|
||||
|
||||
var ni Int
|
||||
err = json.Unmarshal(nullIntJSON, &ni)
|
||||
maybePanic(err)
|
||||
assertInt(t, ni, "sq.NullInt json")
|
||||
|
||||
var null Int
|
||||
err = json.Unmarshal(nullJSON, &null)
|
||||
maybePanic(err)
|
||||
|
|
4
json.go
4
json.go
|
@ -58,7 +58,6 @@ func (j JSON) Unmarshal(dest interface{}) error {
|
|||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
// If not, it will copy your data slice into JSON.
|
||||
func (j *JSON) UnmarshalJSON(data []byte) error {
|
||||
if data == nil {
|
||||
return fmt.Errorf("json: cannot unmarshal nil into Go value of type null.JSON")
|
||||
|
@ -78,7 +77,6 @@ func (j *JSON) UnmarshalJSON(data []byte) error {
|
|||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
// It will unmarshal to nil if the text is nil or len 0.
|
||||
func (j *JSON) UnmarshalText(text []byte) error {
|
||||
if text == nil || len(text) == 0 {
|
||||
j.JSON = nil
|
||||
|
@ -106,7 +104,6 @@ func (j *JSON) Marshal(obj interface{}) error {
|
|||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
// It will encode null if the JSON is nil.
|
||||
func (j JSON) MarshalJSON() ([]byte, error) {
|
||||
if len(j.JSON) == 0 || j.JSON == nil {
|
||||
return []byte("null"), nil
|
||||
|
@ -115,7 +112,6 @@ func (j JSON) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
// It will encode nil if the JSON is invalid.
|
||||
func (j JSON) MarshalText() ([]byte, error) {
|
||||
if !j.Valid {
|
||||
return nil, nil
|
||||
|
|
68
string.go
68
string.go
|
@ -1,20 +1,17 @@
|
|||
// Package null contains SQL types that consider zero input and null input as separate values,
|
||||
// with convenient support for JSON and text marshaling.
|
||||
// Types in this package will always encode to their null value if null.
|
||||
// Use the zero subpackage if you want zero values and null to be treated the same.
|
||||
package null
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/nullbio/null/convert"
|
||||
)
|
||||
|
||||
// String is a nullable string. It supports SQL and JSON serialization.
|
||||
// It will marshal to null if null. Blank string input will be considered null.
|
||||
type String struct {
|
||||
sql.NullString
|
||||
String string
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// StringFrom creates a new String that will never be blank.
|
||||
|
@ -33,39 +30,28 @@ func StringFromPtr(s *string) String {
|
|||
// NewString creates a new String
|
||||
func NewString(s string, valid bool) String {
|
||||
return String{
|
||||
NullString: sql.NullString{
|
||||
String: s,
|
||||
Valid: valid,
|
||||
},
|
||||
String: s,
|
||||
Valid: valid,
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
// It supports string and null input. Blank string input does not produce a null String.
|
||||
// It also supports unmarshalling a sql.NullString.
|
||||
func (s *String) UnmarshalJSON(data []byte) error {
|
||||
var err error
|
||||
var v interface{}
|
||||
if err = json.Unmarshal(data, &v); err != nil {
|
||||
return err
|
||||
}
|
||||
switch x := v.(type) {
|
||||
case string:
|
||||
s.String = x
|
||||
case map[string]interface{}:
|
||||
err = json.Unmarshal(data, &s.NullString)
|
||||
case nil:
|
||||
if bytes.Equal(data, NullBytes) {
|
||||
s.String = ""
|
||||
s.Valid = false
|
||||
return nil
|
||||
default:
|
||||
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.String", reflect.TypeOf(v).Name())
|
||||
}
|
||||
s.Valid = err == nil
|
||||
return err
|
||||
|
||||
if err := json.Unmarshal(data, &s.String); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
// It will encode null if this String is null.
|
||||
func (s String) MarshalJSON() ([]byte, error) {
|
||||
if !s.Valid {
|
||||
return []byte("null"), nil
|
||||
|
@ -74,7 +60,6 @@ func (s String) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
// It will encode a blank string when this String is null.
|
||||
func (s String) MarshalText() ([]byte, error) {
|
||||
if !s.Valid {
|
||||
return []byte{}, nil
|
||||
|
@ -83,7 +68,6 @@ func (s String) MarshalText() ([]byte, error) {
|
|||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
// It will unmarshal to a null String if the input is a blank string.
|
||||
func (s *String) UnmarshalText(text []byte) error {
|
||||
s.String = string(text)
|
||||
s.Valid = s.String != ""
|
||||
|
@ -108,3 +92,21 @@ func (s String) Ptr() *string {
|
|||
func (s String) IsZero() bool {
|
||||
return !s.Valid
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (s *String) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
s.String, s.Valid = "", false
|
||||
return nil
|
||||
}
|
||||
s.Valid = true
|
||||
return convert.ConvertAssign(&s.String, value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (s String) Value() (driver.Value, error) {
|
||||
if !s.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return s.String, nil
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
var (
|
||||
stringJSON = []byte(`"test"`)
|
||||
blankStringJSON = []byte(`""`)
|
||||
nullStringJSON = []byte(`{"String":"test","Valid":true}`)
|
||||
|
||||
nullJSON = []byte(`null`)
|
||||
invalidJSON = []byte(`:)`)
|
||||
|
@ -44,11 +43,6 @@ func TestUnmarshalString(t *testing.T) {
|
|||
maybePanic(err)
|
||||
assertStr(t, str, "string json")
|
||||
|
||||
var ns String
|
||||
err = json.Unmarshal(nullStringJSON, &ns)
|
||||
maybePanic(err)
|
||||
assertStr(t, ns, "sql.NullString json")
|
||||
|
||||
var blank String
|
||||
err = json.Unmarshal(blankStringJSON, &blank)
|
||||
maybePanic(err)
|
||||
|
|
88
time.go
88
time.go
|
@ -1,44 +1,18 @@
|
|||
package null
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Time is a nullable time.Time. It supports SQL and JSON serialization.
|
||||
// It will marshal to null if null.
|
||||
type Time struct {
|
||||
Time time.Time
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (t *Time) Scan(value interface{}) error {
|
||||
var err error
|
||||
switch x := value.(type) {
|
||||
case time.Time:
|
||||
t.Time = x
|
||||
case nil:
|
||||
t.Valid = false
|
||||
return nil
|
||||
default:
|
||||
err = fmt.Errorf("null: cannot scan type %T into null.Time: %v", value, value)
|
||||
}
|
||||
t.Valid = err == nil
|
||||
return err
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (t Time) Value() (driver.Value, error) {
|
||||
if !t.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return t.Time, nil
|
||||
}
|
||||
|
||||
// NewTime creates a new Time.
|
||||
func NewTime(t time.Time, valid bool) Time {
|
||||
return Time{
|
||||
|
@ -61,7 +35,6 @@ func TimeFromPtr(t *time.Time) Time {
|
|||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
// It will encode null if this time is null.
|
||||
func (t Time) MarshalJSON() ([]byte, error) {
|
||||
if !t.Valid {
|
||||
return []byte("null"), nil
|
||||
|
@ -70,36 +43,22 @@ func (t Time) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
// It supports string, object (e.g. pq.NullTime and friends)
|
||||
// and null input.
|
||||
func (t *Time) UnmarshalJSON(data []byte) error {
|
||||
var err error
|
||||
var v interface{}
|
||||
if err = json.Unmarshal(data, &v); err != nil {
|
||||
return err
|
||||
}
|
||||
switch x := v.(type) {
|
||||
case string:
|
||||
err = t.Time.UnmarshalJSON(data)
|
||||
case map[string]interface{}:
|
||||
ti, tiOK := x["Time"].(string)
|
||||
valid, validOK := x["Valid"].(bool)
|
||||
if !tiOK || !validOK {
|
||||
return fmt.Errorf(`json: unmarshalling object into Go value of type null.Time requires key "Time" to be of type string and key "Valid" to be of type bool; found %T and %T, respectively`, x["Time"], x["Valid"])
|
||||
}
|
||||
err = t.Time.UnmarshalText([]byte(ti))
|
||||
t.Valid = valid
|
||||
return err
|
||||
case nil:
|
||||
if bytes.Equal(data, NullBytes) {
|
||||
t.Valid = false
|
||||
t.Time = time.Time{}
|
||||
return nil
|
||||
default:
|
||||
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.Time", reflect.TypeOf(v).Name())
|
||||
}
|
||||
t.Valid = err == nil
|
||||
return err
|
||||
|
||||
if err := t.Time.UnmarshalJSON(data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
func (t Time) MarshalText() ([]byte, error) {
|
||||
if !t.Valid {
|
||||
return []byte("null"), nil
|
||||
|
@ -107,6 +66,7 @@ func (t Time) MarshalText() ([]byte, error) {
|
|||
return t.Time.MarshalText()
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
func (t *Time) UnmarshalText(text []byte) error {
|
||||
str := string(text)
|
||||
if str == "" || str == "null" {
|
||||
|
@ -133,3 +93,27 @@ func (t Time) Ptr() *time.Time {
|
|||
}
|
||||
return &t.Time
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (t *Time) Scan(value interface{}) error {
|
||||
var err error
|
||||
switch x := value.(type) {
|
||||
case time.Time:
|
||||
t.Time = x
|
||||
case nil:
|
||||
t.Valid = false
|
||||
return nil
|
||||
default:
|
||||
err = fmt.Errorf("null: cannot scan type %T into null.Time: %v", value, value)
|
||||
}
|
||||
t.Valid = err == nil
|
||||
return err
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (t Time) Value() (driver.Value, error) {
|
||||
if !t.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return t.Time, nil
|
||||
}
|
||||
|
|
16
time_test.go
16
time_test.go
|
@ -11,8 +11,6 @@ var (
|
|||
timeJSON = []byte(`"` + timeString + `"`)
|
||||
nullTimeJSON = []byte(`null`)
|
||||
timeValue, _ = time.Parse(time.RFC3339, timeString)
|
||||
timeObject = []byte(`{"Time":"2012-12-21T21:21:21Z","Valid":true}`)
|
||||
nullObject = []byte(`{"Time":"0001-01-01T00:00:00Z","Valid":false}`)
|
||||
badObject = []byte(`{"hello": "world"}`)
|
||||
)
|
||||
|
||||
|
@ -27,20 +25,10 @@ func TestUnmarshalTimeJSON(t *testing.T) {
|
|||
maybePanic(err)
|
||||
assertNullTime(t, null, "null time json")
|
||||
|
||||
var fromObject Time
|
||||
err = json.Unmarshal(timeObject, &fromObject)
|
||||
maybePanic(err)
|
||||
assertTime(t, fromObject, "time from object json")
|
||||
|
||||
var nullFromObj Time
|
||||
err = json.Unmarshal(nullObject, &nullFromObj)
|
||||
maybePanic(err)
|
||||
assertNullTime(t, nullFromObj, "null from object json")
|
||||
|
||||
var invalid Time
|
||||
err = invalid.UnmarshalJSON(invalidJSON)
|
||||
if _, ok := err.(*json.SyntaxError); !ok {
|
||||
t.Errorf("expected json.SyntaxError, not %T", err)
|
||||
if _, ok := err.(*time.ParseError); !ok {
|
||||
t.Errorf("expected json.ParseError, not %T", err)
|
||||
}
|
||||
assertNullTime(t, invalid, "invalid from object json")
|
||||
|
||||
|
|
111
uint.go
111
uint.go
|
@ -1,35 +1,25 @@
|
|||
package null
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"gopkg.in/nullbio/null.v5/convert"
|
||||
)
|
||||
|
||||
// NullUint is a replica of sql.NullInt64 for uint types.
|
||||
type NullUint struct {
|
||||
// Uint is an nullable uint.
|
||||
type Uint struct {
|
||||
Uint uint
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Uint is an nullable uint.
|
||||
// It does not consider zero values to be null.
|
||||
// It will decode to null, not zero, if null.
|
||||
type Uint struct {
|
||||
NullUint
|
||||
}
|
||||
|
||||
// NewUint creates a new Uint
|
||||
func NewUint(i uint, valid bool) Uint {
|
||||
return Uint{
|
||||
NullUint: NullUint{
|
||||
Uint: i,
|
||||
Valid: valid,
|
||||
},
|
||||
Uint: i,
|
||||
Valid: valid,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,101 +37,88 @@ func UintFromPtr(i *uint) Uint {
|
|||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
// It supports number and null input.
|
||||
// 0 will not be considered a null Uint.
|
||||
// It also supports unmarshalling a sql.NullUint.
|
||||
func (i *Uint) UnmarshalJSON(data []byte) error {
|
||||
var err error
|
||||
var v interface{}
|
||||
if err = json.Unmarshal(data, &v); err != nil {
|
||||
func (u *Uint) UnmarshalJSON(data []byte) error {
|
||||
if bytes.Equal(data, NullBytes) {
|
||||
u.Valid = false
|
||||
u.Uint = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
var x uint64
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return err
|
||||
}
|
||||
switch v.(type) {
|
||||
case float64:
|
||||
// Unmarshal again, directly to uint, to avoid intermediate float64
|
||||
err = json.Unmarshal(data, &i.Uint)
|
||||
case map[string]interface{}:
|
||||
err = json.Unmarshal(data, &i.NullUint)
|
||||
case nil:
|
||||
i.Valid = false
|
||||
return nil
|
||||
default:
|
||||
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.Uint", reflect.TypeOf(v).Name())
|
||||
}
|
||||
i.Valid = err == nil
|
||||
return err
|
||||
|
||||
u.Uint = uint(x)
|
||||
u.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
// It will unmarshal to a null Uint if the input is a blank or not an integer.
|
||||
// It will return an error if the input is not an integer, blank, or "null".
|
||||
func (i *Uint) UnmarshalText(text []byte) error {
|
||||
func (u *Uint) UnmarshalText(text []byte) error {
|
||||
str := string(text)
|
||||
if str == "" || str == "null" {
|
||||
i.Valid = false
|
||||
u.Valid = false
|
||||
return nil
|
||||
}
|
||||
var err error
|
||||
res, err := strconv.ParseUint(string(text), 10, 0)
|
||||
i.Valid = err == nil
|
||||
if i.Valid {
|
||||
i.Uint = uint(res)
|
||||
u.Valid = err == nil
|
||||
if u.Valid {
|
||||
u.Uint = uint(res)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
// It will encode null if this Uint is null.
|
||||
func (i Uint) MarshalJSON() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
func (u Uint) MarshalJSON() ([]byte, error) {
|
||||
if !u.Valid {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
return []byte(strconv.FormatUint(uint64(i.Uint), 10)), nil
|
||||
return []byte(strconv.FormatUint(uint64(u.Uint), 10)), nil
|
||||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
// It will encode a blank string if this Uint is null.
|
||||
func (i Uint) MarshalText() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
func (u Uint) MarshalText() ([]byte, error) {
|
||||
if !u.Valid {
|
||||
return []byte{}, nil
|
||||
}
|
||||
return []byte(strconv.FormatUint(uint64(i.Uint), 10)), nil
|
||||
return []byte(strconv.FormatUint(uint64(u.Uint), 10)), nil
|
||||
}
|
||||
|
||||
// SetValid changes this Uint's value and also sets it to be non-null.
|
||||
func (i *Uint) SetValid(n uint) {
|
||||
i.Uint = n
|
||||
i.Valid = true
|
||||
func (u *Uint) SetValid(n uint) {
|
||||
u.Uint = n
|
||||
u.Valid = true
|
||||
}
|
||||
|
||||
// Ptr returns a pointer to this Uint's value, or a nil pointer if this Uint is null.
|
||||
func (i Uint) Ptr() *uint {
|
||||
if !i.Valid {
|
||||
func (u Uint) Ptr() *uint {
|
||||
if !u.Valid {
|
||||
return nil
|
||||
}
|
||||
return &i.Uint
|
||||
return &u.Uint
|
||||
}
|
||||
|
||||
// IsZero returns true for invalid Uints, for future omitempty support (Go 1.4?)
|
||||
// A non-null Uint with a 0 value will not be considered zero.
|
||||
func (i Uint) IsZero() bool {
|
||||
return !i.Valid
|
||||
func (u Uint) IsZero() bool {
|
||||
return !u.Valid
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullUint) Scan(value interface{}) error {
|
||||
func (u *Uint) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
n.Uint, n.Valid = 0, false
|
||||
u.Uint, u.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
return convert.ConvertAssign(&n.Uint, value)
|
||||
u.Valid = true
|
||||
return convert.ConvertAssign(&u.Uint, value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullUint) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
func (u Uint) Value() (driver.Value, error) {
|
||||
if !u.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return int64(n.Uint), nil
|
||||
return int64(u.Uint), nil
|
||||
}
|
||||
|
|
113
uint16.go
113
uint16.go
|
@ -1,35 +1,27 @@
|
|||
package null
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"math"
|
||||
"strconv"
|
||||
|
||||
"gopkg.in/nullbio/null.v5/convert"
|
||||
)
|
||||
|
||||
// NullUint16 is a replica of sql.NullInt64 for uint16 types.
|
||||
type NullUint16 struct {
|
||||
// Uint16 is an nullable uint16.
|
||||
type Uint16 struct {
|
||||
Uint16 uint16
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Uint16 is an nullable uint16.
|
||||
// It does not consider zero values to be null.
|
||||
// It will decode to null, not zero, if null.
|
||||
type Uint16 struct {
|
||||
NullUint16
|
||||
}
|
||||
|
||||
// NewUint16 creates a new Uint16
|
||||
func NewUint16(i uint16, valid bool) Uint16 {
|
||||
return Uint16{
|
||||
NullUint16: NullUint16{
|
||||
Uint16: i,
|
||||
Valid: valid,
|
||||
},
|
||||
Uint16: i,
|
||||
Valid: valid,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,101 +39,92 @@ func Uint16FromPtr(i *uint16) Uint16 {
|
|||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
// It supports number and null input.
|
||||
// 0 will not be considered a null Uint16.
|
||||
// It also supports unmarshalling a sql.NullUint16.
|
||||
func (i *Uint16) UnmarshalJSON(data []byte) error {
|
||||
var err error
|
||||
var v interface{}
|
||||
if err = json.Unmarshal(data, &v); err != nil {
|
||||
func (u *Uint16) UnmarshalJSON(data []byte) error {
|
||||
if bytes.Equal(data, NullBytes) {
|
||||
u.Valid = false
|
||||
u.Uint16 = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
var x uint64
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return err
|
||||
}
|
||||
switch v.(type) {
|
||||
case float64:
|
||||
// Unmarshal again, directly to uint16, to avoid intermediate float64
|
||||
err = json.Unmarshal(data, &i.Uint16)
|
||||
case map[string]interface{}:
|
||||
err = json.Unmarshal(data, &i.NullUint16)
|
||||
case nil:
|
||||
i.Valid = false
|
||||
return nil
|
||||
default:
|
||||
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.Uint16", reflect.TypeOf(v).Name())
|
||||
|
||||
if x > math.MaxUint16 {
|
||||
return fmt.Errorf("json: %d overflows max uint8 value", x)
|
||||
}
|
||||
i.Valid = err == nil
|
||||
return err
|
||||
|
||||
u.Uint16 = uint16(x)
|
||||
u.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
// It will unmarshal to a null Uint16 if the input is a blank or not an integer.
|
||||
// It will return an error if the input is not an integer, blank, or "null".
|
||||
func (i *Uint16) UnmarshalText(text []byte) error {
|
||||
func (u *Uint16) UnmarshalText(text []byte) error {
|
||||
str := string(text)
|
||||
if str == "" || str == "null" {
|
||||
i.Valid = false
|
||||
u.Valid = false
|
||||
return nil
|
||||
}
|
||||
var err error
|
||||
res, err := strconv.ParseUint(string(text), 10, 16)
|
||||
i.Valid = err == nil
|
||||
if i.Valid {
|
||||
i.Uint16 = uint16(res)
|
||||
u.Valid = err == nil
|
||||
if u.Valid {
|
||||
u.Uint16 = uint16(res)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
// It will encode null if this Uint16 is null.
|
||||
func (i Uint16) MarshalJSON() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
func (u Uint16) MarshalJSON() ([]byte, error) {
|
||||
if !u.Valid {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
return []byte(strconv.FormatUint(uint64(i.Uint16), 10)), nil
|
||||
return []byte(strconv.FormatUint(uint64(u.Uint16), 10)), nil
|
||||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
// It will encode a blank string if this Uint16 is null.
|
||||
func (i Uint16) MarshalText() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
func (u Uint16) MarshalText() ([]byte, error) {
|
||||
if !u.Valid {
|
||||
return []byte{}, nil
|
||||
}
|
||||
return []byte(strconv.FormatUint(uint64(i.Uint16), 10)), nil
|
||||
return []byte(strconv.FormatUint(uint64(u.Uint16), 10)), nil
|
||||
}
|
||||
|
||||
// SetValid changes this Uint16's value and also sets it to be non-null.
|
||||
func (i *Uint16) SetValid(n uint16) {
|
||||
i.Uint16 = n
|
||||
i.Valid = true
|
||||
func (u *Uint16) SetValid(n uint16) {
|
||||
u.Uint16 = n
|
||||
u.Valid = true
|
||||
}
|
||||
|
||||
// Ptr returns a pointer to this Uint16's value, or a nil pointer if this Uint16 is null.
|
||||
func (i Uint16) Ptr() *uint16 {
|
||||
if !i.Valid {
|
||||
func (u Uint16) Ptr() *uint16 {
|
||||
if !u.Valid {
|
||||
return nil
|
||||
}
|
||||
return &i.Uint16
|
||||
return &u.Uint16
|
||||
}
|
||||
|
||||
// IsZero returns true for invalid Uint16's, for future omitempty support (Go 1.4?)
|
||||
// A non-null Uint16 with a 0 value will not be considered zero.
|
||||
func (i Uint16) IsZero() bool {
|
||||
return !i.Valid
|
||||
func (u Uint16) IsZero() bool {
|
||||
return !u.Valid
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullUint16) Scan(value interface{}) error {
|
||||
func (u *Uint16) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
n.Uint16, n.Valid = 0, false
|
||||
u.Uint16, u.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
return convert.ConvertAssign(&n.Uint16, value)
|
||||
u.Valid = true
|
||||
return convert.ConvertAssign(&u.Uint16, value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullUint16) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
func (u Uint16) Value() (driver.Value, error) {
|
||||
if !u.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return int64(n.Uint16), nil
|
||||
return int64(u.Uint16), nil
|
||||
}
|
||||
|
|
|
@ -8,8 +8,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
uint16JSON = []byte(`65534`)
|
||||
nullUint16JSON = []byte(`{"Uint16":65534,"Valid":true}`)
|
||||
uint16JSON = []byte(`65534`)
|
||||
)
|
||||
|
||||
func TestUint16From(t *testing.T) {
|
||||
|
@ -38,11 +37,6 @@ func TestUnmarshalUint16(t *testing.T) {
|
|||
maybePanic(err)
|
||||
assertUint16(t, i, "uint16 json")
|
||||
|
||||
var ni Uint16
|
||||
err = json.Unmarshal(nullUint16JSON, &ni)
|
||||
maybePanic(err)
|
||||
assertUint16(t, ni, "sq.NullUint16 json")
|
||||
|
||||
var null Uint16
|
||||
err = json.Unmarshal(nullJSON, &null)
|
||||
maybePanic(err)
|
||||
|
|
113
uint32.go
113
uint32.go
|
@ -1,35 +1,27 @@
|
|||
package null
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"math"
|
||||
"strconv"
|
||||
|
||||
"gopkg.in/nullbio/null.v5/convert"
|
||||
)
|
||||
|
||||
// NullUint32 is a replica of sql.NullInt64 for uint32 types.
|
||||
type NullUint32 struct {
|
||||
// Uint32 is an nullable uint32.
|
||||
type Uint32 struct {
|
||||
Uint32 uint32
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Uint32 is an nullable uint32.
|
||||
// It does not consider zero values to be null.
|
||||
// It will decode to null, not zero, if null.
|
||||
type Uint32 struct {
|
||||
NullUint32
|
||||
}
|
||||
|
||||
// NewUint32 creates a new Uint32
|
||||
func NewUint32(i uint32, valid bool) Uint32 {
|
||||
return Uint32{
|
||||
NullUint32: NullUint32{
|
||||
Uint32: i,
|
||||
Valid: valid,
|
||||
},
|
||||
Uint32: i,
|
||||
Valid: valid,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,101 +39,92 @@ func Uint32FromPtr(i *uint32) Uint32 {
|
|||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
// It supports number and null input.
|
||||
// 0 will not be considered a null Uint32.
|
||||
// It also supports unmarshalling a sql.NullUint32.
|
||||
func (i *Uint32) UnmarshalJSON(data []byte) error {
|
||||
var err error
|
||||
var v interface{}
|
||||
if err = json.Unmarshal(data, &v); err != nil {
|
||||
func (u *Uint32) UnmarshalJSON(data []byte) error {
|
||||
if bytes.Equal(data, NullBytes) {
|
||||
u.Valid = false
|
||||
u.Uint32 = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
var x uint64
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return err
|
||||
}
|
||||
switch v.(type) {
|
||||
case float64:
|
||||
// Unmarshal again, directly to uint32, to avoid intermediate float64
|
||||
err = json.Unmarshal(data, &i.Uint32)
|
||||
case map[string]interface{}:
|
||||
err = json.Unmarshal(data, &i.NullUint32)
|
||||
case nil:
|
||||
i.Valid = false
|
||||
return nil
|
||||
default:
|
||||
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.Uint32", reflect.TypeOf(v).Name())
|
||||
|
||||
if x > math.MaxUint32 {
|
||||
return fmt.Errorf("json: %d overflows max uint32 value", x)
|
||||
}
|
||||
i.Valid = err == nil
|
||||
return err
|
||||
|
||||
u.Uint32 = uint32(x)
|
||||
u.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
// It will unmarshal to a null Uint32 if the input is a blank or not an integer.
|
||||
// It will return an error if the input is not an integer, blank, or "null".
|
||||
func (i *Uint32) UnmarshalText(text []byte) error {
|
||||
func (u *Uint32) UnmarshalText(text []byte) error {
|
||||
str := string(text)
|
||||
if str == "" || str == "null" {
|
||||
i.Valid = false
|
||||
u.Valid = false
|
||||
return nil
|
||||
}
|
||||
var err error
|
||||
res, err := strconv.ParseUint(string(text), 10, 32)
|
||||
i.Valid = err == nil
|
||||
if i.Valid {
|
||||
i.Uint32 = uint32(res)
|
||||
u.Valid = err == nil
|
||||
if u.Valid {
|
||||
u.Uint32 = uint32(res)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
// It will encode null if this Uint32 is null.
|
||||
func (i Uint32) MarshalJSON() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
func (u Uint32) MarshalJSON() ([]byte, error) {
|
||||
if !u.Valid {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
return []byte(strconv.FormatUint(uint64(i.Uint32), 10)), nil
|
||||
return []byte(strconv.FormatUint(uint64(u.Uint32), 10)), nil
|
||||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
// It will encode a blank string if this Uint32 is null.
|
||||
func (i Uint32) MarshalText() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
func (u Uint32) MarshalText() ([]byte, error) {
|
||||
if !u.Valid {
|
||||
return []byte{}, nil
|
||||
}
|
||||
return []byte(strconv.FormatUint(uint64(i.Uint32), 10)), nil
|
||||
return []byte(strconv.FormatUint(uint64(u.Uint32), 10)), nil
|
||||
}
|
||||
|
||||
// SetValid changes this Uint32's value and also sets it to be non-null.
|
||||
func (i *Uint32) SetValid(n uint32) {
|
||||
i.Uint32 = n
|
||||
i.Valid = true
|
||||
func (u *Uint32) SetValid(n uint32) {
|
||||
u.Uint32 = n
|
||||
u.Valid = true
|
||||
}
|
||||
|
||||
// Ptr returns a pointer to this Uint32's value, or a nil pointer if this Uint32 is null.
|
||||
func (i Uint32) Ptr() *uint32 {
|
||||
if !i.Valid {
|
||||
func (u Uint32) Ptr() *uint32 {
|
||||
if !u.Valid {
|
||||
return nil
|
||||
}
|
||||
return &i.Uint32
|
||||
return &u.Uint32
|
||||
}
|
||||
|
||||
// IsZero returns true for invalid Uint32's, for future omitempty support (Go 1.4?)
|
||||
// A non-null Uint32 with a 0 value will not be considered zero.
|
||||
func (i Uint32) IsZero() bool {
|
||||
return !i.Valid
|
||||
func (u Uint32) IsZero() bool {
|
||||
return !u.Valid
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullUint32) Scan(value interface{}) error {
|
||||
func (u *Uint32) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
n.Uint32, n.Valid = 0, false
|
||||
u.Uint32, u.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
return convert.ConvertAssign(&n.Uint32, value)
|
||||
u.Valid = true
|
||||
return convert.ConvertAssign(&u.Uint32, value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullUint32) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
func (u Uint32) Value() (driver.Value, error) {
|
||||
if !u.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return int64(n.Uint32), nil
|
||||
return uint64(u.Uint32), nil
|
||||
}
|
||||
|
|
|
@ -8,8 +8,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
uint32JSON = []byte(`4294967294`)
|
||||
nullUint32JSON = []byte(`{"Uint32":4294967294,"Valid":true}`)
|
||||
uint32JSON = []byte(`4294967294`)
|
||||
)
|
||||
|
||||
func TestUint32From(t *testing.T) {
|
||||
|
@ -38,11 +37,6 @@ func TestUnmarshalUint32(t *testing.T) {
|
|||
maybePanic(err)
|
||||
assertUint32(t, i, "uint32 json")
|
||||
|
||||
var ni Uint32
|
||||
err = json.Unmarshal(nullUint32JSON, &ni)
|
||||
maybePanic(err)
|
||||
assertUint32(t, ni, "sq.NullUint32 json")
|
||||
|
||||
var null Uint32
|
||||
err = json.Unmarshal(nullJSON, &null)
|
||||
maybePanic(err)
|
||||
|
|
109
uint64.go
109
uint64.go
|
@ -1,35 +1,25 @@
|
|||
package null
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"gopkg.in/nullbio/null.v5/convert"
|
||||
)
|
||||
|
||||
// NullUint64 is a replica of sql.NullInt64 for uint64 types.
|
||||
type NullUint64 struct {
|
||||
// Uint64 is an nullable uint64.
|
||||
type Uint64 struct {
|
||||
Uint64 uint64
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Uint64 is an nullable uint64.
|
||||
// It does not consider zero values to be null.
|
||||
// It will decode to null, not zero, if null.
|
||||
type Uint64 struct {
|
||||
NullUint64
|
||||
}
|
||||
|
||||
// NewUint64 creates a new Uint64
|
||||
func NewUint64(i uint64, valid bool) Uint64 {
|
||||
return Uint64{
|
||||
NullUint64: NullUint64{
|
||||
Uint64: i,
|
||||
Valid: valid,
|
||||
},
|
||||
Uint64: i,
|
||||
Valid: valid,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,101 +37,86 @@ func Uint64FromPtr(i *uint64) Uint64 {
|
|||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
// It supports number and null input.
|
||||
// 0 will not be considered a null Uint64.
|
||||
// It also supports unmarshalling a sql.NullUint64.
|
||||
func (i *Uint64) UnmarshalJSON(data []byte) error {
|
||||
var err error
|
||||
var v interface{}
|
||||
if err = json.Unmarshal(data, &v); err != nil {
|
||||
func (u *Uint64) UnmarshalJSON(data []byte) error {
|
||||
if bytes.Equal(data, NullBytes) {
|
||||
u.Uint64 = 0
|
||||
u.Valid = false
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(data, &u.Uint64); err != nil {
|
||||
return err
|
||||
}
|
||||
switch v.(type) {
|
||||
case float64:
|
||||
// Unmarshal again, directly to uint64, to avoid intermediate float64
|
||||
err = json.Unmarshal(data, &i.Uint64)
|
||||
case map[string]interface{}:
|
||||
err = json.Unmarshal(data, &i.NullUint64)
|
||||
case nil:
|
||||
i.Valid = false
|
||||
return nil
|
||||
default:
|
||||
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.Uint64", reflect.TypeOf(v).Name())
|
||||
}
|
||||
i.Valid = err == nil
|
||||
return err
|
||||
|
||||
u.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
// It will unmarshal to a null Uint64 if the input is a blank or not an integer.
|
||||
// It will return an error if the input is not an integer, blank, or "null".
|
||||
func (i *Uint64) UnmarshalText(text []byte) error {
|
||||
func (u *Uint64) UnmarshalText(text []byte) error {
|
||||
str := string(text)
|
||||
if str == "" || str == "null" {
|
||||
i.Valid = false
|
||||
u.Valid = false
|
||||
return nil
|
||||
}
|
||||
var err error
|
||||
res, err := strconv.ParseUint(string(text), 10, 64)
|
||||
i.Valid = err == nil
|
||||
if i.Valid {
|
||||
i.Uint64 = uint64(res)
|
||||
u.Valid = err == nil
|
||||
if u.Valid {
|
||||
u.Uint64 = uint64(res)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
// It will encode null if this Uint64 is null.
|
||||
func (i Uint64) MarshalJSON() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
func (u Uint64) MarshalJSON() ([]byte, error) {
|
||||
if !u.Valid {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
return []byte(strconv.FormatUint(i.Uint64, 10)), nil
|
||||
return []byte(strconv.FormatUint(u.Uint64, 10)), nil
|
||||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
// It will encode a blank string if this Uint64 is null.
|
||||
func (i Uint64) MarshalText() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
func (u Uint64) MarshalText() ([]byte, error) {
|
||||
if !u.Valid {
|
||||
return []byte{}, nil
|
||||
}
|
||||
return []byte(strconv.FormatUint(i.Uint64, 10)), nil
|
||||
return []byte(strconv.FormatUint(u.Uint64, 10)), nil
|
||||
}
|
||||
|
||||
// SetValid changes this Uint64's value and also sets it to be non-null.
|
||||
func (i *Uint64) SetValid(n uint64) {
|
||||
i.Uint64 = n
|
||||
i.Valid = true
|
||||
func (u *Uint64) SetValid(n uint64) {
|
||||
u.Uint64 = n
|
||||
u.Valid = true
|
||||
}
|
||||
|
||||
// Ptr returns a pointer to this Uint64's value, or a nil pointer if this Uint64 is null.
|
||||
func (i Uint64) Ptr() *uint64 {
|
||||
if !i.Valid {
|
||||
func (u Uint64) Ptr() *uint64 {
|
||||
if !u.Valid {
|
||||
return nil
|
||||
}
|
||||
return &i.Uint64
|
||||
return &u.Uint64
|
||||
}
|
||||
|
||||
// IsZero returns true for invalid Uint64's, for future omitempty support (Go 1.4?)
|
||||
// A non-null Uint64 with a 0 value will not be considered zero.
|
||||
func (i Uint64) IsZero() bool {
|
||||
return !i.Valid
|
||||
func (u Uint64) IsZero() bool {
|
||||
return !u.Valid
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullUint64) Scan(value interface{}) error {
|
||||
func (u *Uint64) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
n.Uint64, n.Valid = 0, false
|
||||
u.Uint64, u.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
return convert.ConvertAssign(&n.Uint64, value)
|
||||
u.Valid = true
|
||||
return convert.ConvertAssign(&u.Uint64, value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullUint64) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
func (u Uint64) Value() (driver.Value, error) {
|
||||
if !u.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return int64(n.Uint64), nil
|
||||
return int64(u.Uint64), nil
|
||||
}
|
||||
|
|
|
@ -6,8 +6,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
uint64JSON = []byte(`18446744073709551614`)
|
||||
nullUint64JSON = []byte(`{"Uint64":18446744073709551614,"Valid":true}`)
|
||||
uint64JSON = []byte(`18446744073709551614`)
|
||||
)
|
||||
|
||||
func TestUint64From(t *testing.T) {
|
||||
|
@ -36,11 +35,6 @@ func TestUnmarshalUint64(t *testing.T) {
|
|||
maybePanic(err)
|
||||
assertUint64(t, i, "uint64 json")
|
||||
|
||||
var ni Uint64
|
||||
err = json.Unmarshal(nullUint64JSON, &ni)
|
||||
maybePanic(err)
|
||||
assertUint64(t, ni, "sq.NullUint64 json")
|
||||
|
||||
var null Uint64
|
||||
err = json.Unmarshal(nullJSON, &null)
|
||||
maybePanic(err)
|
||||
|
|
109
uint8.go
109
uint8.go
|
@ -1,35 +1,27 @@
|
|||
package null
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"math"
|
||||
"strconv"
|
||||
|
||||
"gopkg.in/nullbio/null.v5/convert"
|
||||
)
|
||||
|
||||
// NullUint8 is a replica of sql.NullInt64 for uint8 types.
|
||||
type NullUint8 struct {
|
||||
// Uint8 is an nullable uint8.
|
||||
type Uint8 struct {
|
||||
Uint8 uint8
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Uint8 is an nullable uint8.
|
||||
// It does not consider zero values to be null.
|
||||
// It will decode to null, not zero, if null.
|
||||
type Uint8 struct {
|
||||
NullUint8
|
||||
}
|
||||
|
||||
// NewUint8 creates a new Uint8
|
||||
func NewUint8(i uint8, valid bool) Uint8 {
|
||||
return Uint8{
|
||||
NullUint8: NullUint8{
|
||||
Uint8: i,
|
||||
Valid: valid,
|
||||
},
|
||||
Uint8: i,
|
||||
Valid: valid,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,99 +39,90 @@ func Uint8FromPtr(i *uint8) Uint8 {
|
|||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
// It supports number and null input.
|
||||
// 0 will not be considered a null Uint8.
|
||||
// It also supports unmarshalling a sql.NullUint8.
|
||||
func (i *Uint8) UnmarshalJSON(data []byte) error {
|
||||
var err error
|
||||
var v interface{}
|
||||
if err = json.Unmarshal(data, &v); err != nil {
|
||||
func (u *Uint8) UnmarshalJSON(data []byte) error {
|
||||
if bytes.Equal(data, NullBytes) {
|
||||
u.Valid = false
|
||||
u.Uint8 = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
var x uint64
|
||||
if err := json.Unmarshal(data, &x); err != nil {
|
||||
return err
|
||||
}
|
||||
switch v.(type) {
|
||||
case float64:
|
||||
// Unmarshal again, directly to uint8, to avoid intermediate float64
|
||||
err = json.Unmarshal(data, &i.Uint8)
|
||||
case map[string]interface{}:
|
||||
err = json.Unmarshal(data, &i.NullUint8)
|
||||
case nil:
|
||||
i.Valid = false
|
||||
return nil
|
||||
default:
|
||||
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.Uint8", reflect.TypeOf(v).Name())
|
||||
|
||||
if x > math.MaxUint8 {
|
||||
return fmt.Errorf("json: %d overflows max uint8 value", x)
|
||||
}
|
||||
i.Valid = err == nil
|
||||
return err
|
||||
|
||||
u.Uint8 = uint8(x)
|
||||
u.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
// It will unmarshal to a null Uint8 if the input is a blank or not an integer.
|
||||
// It will return an error if the input is not an integer, blank, or "null".
|
||||
func (i *Uint8) UnmarshalText(text []byte) error {
|
||||
func (u *Uint8) UnmarshalText(text []byte) error {
|
||||
str := string(text)
|
||||
if str == "" || str == "null" {
|
||||
i.Valid = false
|
||||
u.Valid = false
|
||||
return nil
|
||||
}
|
||||
var err error
|
||||
res, err := strconv.ParseUint(string(text), 10, 8)
|
||||
i.Valid = err == nil
|
||||
if i.Valid {
|
||||
i.Uint8 = uint8(res)
|
||||
u.Valid = err == nil
|
||||
if u.Valid {
|
||||
u.Uint8 = uint8(res)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
// It will encode null if this Uint8 is null.
|
||||
func (i Uint8) MarshalJSON() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
func (u Uint8) MarshalJSON() ([]byte, error) {
|
||||
if !u.Valid {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
return []byte(strconv.FormatUint(uint64(i.Uint8), 10)), nil
|
||||
return []byte(strconv.FormatUint(uint64(u.Uint8), 10)), nil
|
||||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
// It will encode a blank string if this Uint8 is null.
|
||||
func (i Uint8) MarshalText() ([]byte, error) {
|
||||
if !i.Valid {
|
||||
func (u Uint8) MarshalText() ([]byte, error) {
|
||||
if !u.Valid {
|
||||
return []byte{}, nil
|
||||
}
|
||||
return []byte(strconv.FormatUint(uint64(i.Uint8), 10)), nil
|
||||
return []byte(strconv.FormatUint(uint64(u.Uint8), 10)), nil
|
||||
}
|
||||
|
||||
// SetValid changes this Uint8's value and also sets it to be non-null.
|
||||
func (i *Uint8) SetValid(n uint8) {
|
||||
i.Uint8 = n
|
||||
i.Valid = true
|
||||
func (u *Uint8) SetValid(n uint8) {
|
||||
u.Uint8 = n
|
||||
u.Valid = true
|
||||
}
|
||||
|
||||
// Ptr returns a pointer to this Uint8's value, or a nil pointer if this Uint8 is null.
|
||||
func (i Uint8) Ptr() *uint8 {
|
||||
if !i.Valid {
|
||||
func (u Uint8) Ptr() *uint8 {
|
||||
if !u.Valid {
|
||||
return nil
|
||||
}
|
||||
return &i.Uint8
|
||||
return &u.Uint8
|
||||
}
|
||||
|
||||
// IsZero returns true for invalid Uint8's, for future omitempty support (Go 1.4?)
|
||||
// A non-null Uint8 with a 0 value will not be considered zero.
|
||||
func (i Uint8) IsZero() bool {
|
||||
return !i.Valid
|
||||
func (u Uint8) IsZero() bool {
|
||||
return !u.Valid
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullUint8) Scan(value interface{}) error {
|
||||
func (u *Uint8) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
n.Uint8, n.Valid = 0, false
|
||||
u.Uint8, u.Valid = 0, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
return convert.ConvertAssign(&n.Uint8, value)
|
||||
u.Valid = true
|
||||
return convert.ConvertAssign(&u.Uint8, value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullUint8) Value() (driver.Value, error) {
|
||||
func (n Uint8) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
@ -8,8 +8,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
uint8JSON = []byte(`254`)
|
||||
nullUint8JSON = []byte(`{"Uint8":254,"Valid":true}`)
|
||||
uint8JSON = []byte(`254`)
|
||||
)
|
||||
|
||||
func TestUint8From(t *testing.T) {
|
||||
|
@ -38,11 +37,6 @@ func TestUnmarshalUint8(t *testing.T) {
|
|||
maybePanic(err)
|
||||
assertUint8(t, i, "uint8 json")
|
||||
|
||||
var ni Uint8
|
||||
err = json.Unmarshal(nullUint8JSON, &ni)
|
||||
maybePanic(err)
|
||||
assertUint8(t, ni, "sq.NullUint8 json")
|
||||
|
||||
var null Uint8
|
||||
err = json.Unmarshal(nullJSON, &null)
|
||||
maybePanic(err)
|
||||
|
|
|
@ -6,8 +6,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
uintJSON = []byte(`12345`)
|
||||
nullUintJSON = []byte(`{"Uint":12345,"Valid":true}`)
|
||||
uintJSON = []byte(`12345`)
|
||||
)
|
||||
|
||||
func TestUintFrom(t *testing.T) {
|
||||
|
@ -36,11 +35,6 @@ func TestUnmarshalUint(t *testing.T) {
|
|||
maybePanic(err)
|
||||
assertUint(t, i, "uint json")
|
||||
|
||||
var ni Uint
|
||||
err = json.Unmarshal(nullUintJSON, &ni)
|
||||
maybePanic(err)
|
||||
assertUint(t, ni, "sq.NullUint json")
|
||||
|
||||
var null Uint
|
||||
err = json.Unmarshal(nullJSON, &null)
|
||||
maybePanic(err)
|
||||
|
|
Loading…
Reference in a new issue