github.com/seeker-insurance/kit@v0.0.13/db/null/bool.go (about) 1 package null 2 3 import ( 4 "database/sql" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "reflect" 9 ) 10 11 // Bool is a nullable bool. 12 // It does not consider false values to be null. 13 // It will decode to null, not false, if null. 14 type Bool struct { 15 sql.NullBool 16 } 17 18 // NewBool creates a new Bool 19 func NewBool(b bool, valid bool) Bool { 20 return Bool{ 21 NullBool: sql.NullBool{ 22 Bool: b, 23 Valid: valid, 24 }, 25 } 26 } 27 28 // BoolFrom creates a new Bool that will always be valid. 29 func BoolFrom(b bool) Bool { 30 return NewBool(b, true) 31 } 32 33 // BoolFromPtr creates a new Bool that will be null if f is nil. 34 func BoolFromPtr(b *bool) Bool { 35 if b == nil { 36 return NewBool(false, false) 37 } 38 return NewBool(*b, true) 39 } 40 41 // ValueOrZero returns the inner value if valid, otherwise false. 42 func (b Bool) ValueOrZero() bool { 43 return b.Valid && b.Bool 44 } 45 46 // UnmarshalJSON implements json.Unmarshaler. 47 // It supports number and null input. 48 // 0 will not be considered a null Bool. 49 // It also supports unmarshalling a sql.NullBool. 50 func (b *Bool) UnmarshalJSON(data []byte) error { 51 var err error 52 var v interface{} 53 if err = json.Unmarshal(data, &v); err != nil { 54 return err 55 } 56 switch x := v.(type) { 57 case bool: 58 b.Bool = x 59 case map[string]interface{}: 60 err = json.Unmarshal(data, &b.NullBool) 61 case nil: 62 b.Valid = false 63 return nil 64 default: 65 err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.Bool", reflect.TypeOf(v).Name()) 66 } 67 b.Valid = err == nil 68 return err 69 } 70 71 // UnmarshalText implements encoding.TextUnmarshaler. 72 // It will unmarshal to a null Bool if the input is a blank or not an integer. 73 // It will return an error if the input is not an integer, blank, or "null". 74 func (b *Bool) UnmarshalText(text []byte) error { 75 str := string(text) 76 switch str { 77 case "", "null": 78 b.Valid = false 79 return nil 80 case "true": 81 b.Bool = true 82 case "false": 83 b.Bool = false 84 default: 85 b.Valid = false 86 return errors.New("invalid input:" + str) 87 } 88 b.Valid = true 89 return nil 90 } 91 92 // MarshalJSON implements json.Marshaler. 93 // It will encode null if this Bool is null. 94 func (b Bool) MarshalJSON() ([]byte, error) { 95 if !b.Valid { 96 return []byte("null"), nil 97 } 98 if !b.Bool { 99 return []byte("false"), nil 100 } 101 return []byte("true"), nil 102 } 103 104 // MarshalText implements encoding.TextMarshaler. 105 // It will encode a blank string if this Bool is null. 106 func (b Bool) MarshalText() ([]byte, error) { 107 if !b.Valid { 108 return []byte{}, nil 109 } 110 if !b.Bool { 111 return []byte("false"), nil 112 } 113 return []byte("true"), nil 114 } 115 116 // SetValid changes this Bool's value and also sets it to be non-null. 117 func (b *Bool) SetValid(v bool) { 118 b.Bool = v 119 b.Valid = true 120 } 121 122 // Ptr returns a pointer to this Bool's value, or a nil pointer if this Bool is null. 123 func (b Bool) Ptr() *bool { 124 if !b.Valid { 125 return nil 126 } 127 return &b.Bool 128 } 129 130 // IsZero returns true for invalid Bools, for future omitempty support (Go 1.4?) 131 // A non-null Bool with a 0 value will not be considered zero. 132 func (b Bool) IsZero() bool { 133 return !b.Valid 134 }