github.com/seeker-insurance/kit@v0.0.13/db/null/zero/bool.go (about) 1 package zero 2 3 import ( 4 "database/sql" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "reflect" 9 ) 10 11 // Bool is a nullable bool. False input is considered null. 12 // JSON marshals to false if null. 13 // Considered null to SQL unmarshaled from a false value. 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 be null if false. 29 func BoolFrom(b bool) Bool { 30 return NewBool(b, b) 31 } 32 33 // BoolFromPtr creates a new Bool that be null if b 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 // UnmarshalJSON implements json.Unmarshaler. 42 // "false" will be considered a null Bool. 43 // It also supports unmarshalling a sql.NullBool. 44 func (b *Bool) UnmarshalJSON(data []byte) error { 45 var err error 46 var v interface{} 47 if err = json.Unmarshal(data, &v); err != nil { 48 return err 49 } 50 switch x := v.(type) { 51 case bool: 52 b.Bool = x 53 case map[string]interface{}: 54 err = json.Unmarshal(data, &b.NullBool) 55 case nil: 56 b.Valid = false 57 return nil 58 default: 59 err = fmt.Errorf("json: cannot unmarshal %v into Go value of type zero.Bool", reflect.TypeOf(v).Name()) 60 } 61 b.Valid = (err == nil) && b.Bool 62 return err 63 } 64 65 // UnmarshalText implements encoding.TextUnmarshaler. 66 // It will unmarshal to a null Bool if the input is a false or not a bool. 67 // It will return an error if the input is not a float, blank, or "null". 68 func (b *Bool) UnmarshalText(text []byte) error { 69 str := string(text) 70 switch str { 71 case "", "null": 72 b.Valid = false 73 return nil 74 case "true": 75 b.Bool = true 76 case "false": 77 b.Bool = false 78 default: 79 b.Valid = false 80 return errors.New("invalid input:" + str) 81 } 82 b.Valid = b.Bool 83 return nil 84 } 85 86 // MarshalJSON implements json.Marshaler. 87 // It will encode null if this Bool is null. 88 func (b Bool) MarshalJSON() ([]byte, error) { 89 if !b.Valid || !b.Bool { 90 return []byte("false"), nil 91 } 92 return []byte("true"), nil 93 } 94 95 // MarshalText implements encoding.TextMarshaler. 96 // It will encode a zero if this Bool is null. 97 func (b Bool) MarshalText() ([]byte, error) { 98 if !b.Valid || !b.Bool { 99 return []byte("false"), nil 100 } 101 return []byte("true"), nil 102 } 103 104 // SetValid changes this Bool's value and also sets it to be non-null. 105 func (b *Bool) SetValid(v bool) { 106 b.Bool = v 107 b.Valid = true 108 } 109 110 // Ptr returns a poBooler to this Bool's value, or a nil poBooler if this Bool is null. 111 func (b Bool) Ptr() *bool { 112 if !b.Valid { 113 return nil 114 } 115 return &b.Bool 116 } 117 118 // IsZero returns true for null or zero Bools, for future omitempty support (Go 1.4?) 119 func (b Bool) IsZero() bool { 120 return !b.Valid || !b.Bool 121 }