-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbool.go
142 lines (129 loc) · 2.79 KB
/
bool.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package gomu
import (
"database/sql/driver"
"encoding/json"
"fmt"
"reflect"
)
// Bool is a nullable bool.
// If key is assigned and value is not null, Bool is specified value, Null is false, Valid is true.
// If value is null, Null is true.
// If key is not assigned, Valid is false.
type Bool struct {
Bool bool
Null bool
Valid bool
}
// NewBool creates a new Bool.
func NewBool(b bool, n bool, valid bool) Bool {
return Bool{
Bool: b,
Null: n,
Valid: valid,
}
}
// BoolFrom creates a new Bool that will always be valid
func BoolFrom(b bool) Bool {
return NewBool(b, false, true)
}
// BoolFromPtr creates a new Bool that will be null if b is nil
func BoolFromPtr(b *bool) Bool {
if b == nil {
return NewBool(false, true, true)
}
return NewBool(*b, false, true)
}
// UnmarshalJSON implements json.Unmarshaler.
func (b *Bool) UnmarshalJSON(data []byte) (err error) {
var v interface{}
if err = json.Unmarshal(data, &v); err != nil {
return
}
switch x := v.(type) {
case bool:
b.Bool = x
case nil:
b.Null = true
default:
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type gomu.Bool", reflect.TypeOf(v).Name())
}
b.Valid = err == nil
return
}
// UnmarshalText implements encoding.TextUnmarshaler.
func (b *Bool) UnmarshalText(text []byte) (err error) {
if text == nil {
return
}
switch string(text) {
case "", "null":
b.Null = true
case "true":
b.Bool = true
case "false":
b.Bool = false
default:
err = fmt.Errorf("invalid input: %s", string(text))
}
b.Valid = err == nil
return
}
// MarshalJSON implements json.Marshaler.
func (b Bool) MarshalJSON() ([]byte, error) {
if !b.Valid {
return []byte("null"), nil
}
if b.Null {
return []byte("null"), nil
}
if b.Bool {
return []byte("true"), nil
}
return []byte("false"), nil
}
// MarshalText implements encoding.TextMarshaler
func (b Bool) MarshalText() ([]byte, error) {
if !b.Valid {
return nil, nil
}
if b.Null {
return []byte("null"), nil
}
if b.Bool {
return []byte("true"), nil
}
return []byte("false"), nil
}
// SetValid changes Bool value and also sets Valid to be true
func (b *Bool) SetValid(v bool) {
b.Bool = v
b.Null = false
b.Valid = true
}
// Ptr returns a pointer to this Bool's value, or a nil pointer if this Bool is null or not valid.
func (b Bool) Ptr() *bool {
if !b.Valid || b.Null {
return nil
}
return &b.Bool
}
// Scan implements database/sql.Scanner.
func (b *Bool) Scan(value interface{}) (err error) {
switch x := value.(type) {
case bool:
b.Bool = x
case nil:
b.Null = true
default:
err = fmt.Errorf("gomu: cannot scan type %T into gomu.Bool: %v", value, value)
}
b.Valid = err == nil
return
}
// Value implements database/sql.Valuer.
func (b Bool) Value() (driver.Value, error) {
if !b.Valid || b.Null {
return nil, nil
}
return b.Bool, nil
}