1 package pgtype
2
3 import (
4 "database/sql/driver"
5 "encoding/json"
6 "fmt"
7 "strconv"
8 )
9
10 type Bool struct {
11 Bool bool
12 Status Status
13 }
14
15 func (dst *Bool) Set(src interface{}) error {
16 if src == nil {
17 *dst = Bool{Status: Null}
18 return nil
19 }
20
21 if value, ok := src.(interface{ Get() interface{} }); ok {
22 value2 := value.Get()
23 if value2 != value {
24 return dst.Set(value2)
25 }
26 }
27
28 switch value := src.(type) {
29 case bool:
30 *dst = Bool{Bool: value, Status: Present}
31 case string:
32 bb, err := strconv.ParseBool(value)
33 if err != nil {
34 return err
35 }
36 *dst = Bool{Bool: bb, Status: Present}
37 case *bool:
38 if value == nil {
39 *dst = Bool{Status: Null}
40 } else {
41 return dst.Set(*value)
42 }
43 case *string:
44 if value == nil {
45 *dst = Bool{Status: Null}
46 } else {
47 return dst.Set(*value)
48 }
49 default:
50 if originalSrc, ok := underlyingBoolType(src); ok {
51 return dst.Set(originalSrc)
52 }
53 return fmt.Errorf("cannot convert %v to Bool", value)
54 }
55
56 return nil
57 }
58
59 func (dst Bool) Get() interface{} {
60 switch dst.Status {
61 case Present:
62 return dst.Bool
63 case Null:
64 return nil
65 default:
66 return dst.Status
67 }
68 }
69
70 func (src *Bool) AssignTo(dst interface{}) error {
71 switch src.Status {
72 case Present:
73 switch v := dst.(type) {
74 case *bool:
75 *v = src.Bool
76 return nil
77 default:
78 if nextDst, retry := GetAssignToDstType(dst); retry {
79 return src.AssignTo(nextDst)
80 }
81 return fmt.Errorf("unable to assign to %T", dst)
82 }
83 case Null:
84 return NullAssignTo(dst)
85 }
86
87 return fmt.Errorf("cannot decode %#v into %T", src, dst)
88 }
89
90 func (dst *Bool) DecodeText(ci *ConnInfo, src []byte) error {
91 if src == nil {
92 *dst = Bool{Status: Null}
93 return nil
94 }
95
96 if len(src) != 1 {
97 return fmt.Errorf("invalid length for bool: %v", len(src))
98 }
99
100 *dst = Bool{Bool: src[0] == 't', Status: Present}
101 return nil
102 }
103
104 func (dst *Bool) DecodeBinary(ci *ConnInfo, src []byte) error {
105 if src == nil {
106 *dst = Bool{Status: Null}
107 return nil
108 }
109
110 if len(src) != 1 {
111 return fmt.Errorf("invalid length for bool: %v", len(src))
112 }
113
114 *dst = Bool{Bool: src[0] == 1, Status: Present}
115 return nil
116 }
117
118 func (src Bool) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
119 switch src.Status {
120 case Null:
121 return nil, nil
122 case Undefined:
123 return nil, errUndefined
124 }
125
126 if src.Bool {
127 buf = append(buf, 't')
128 } else {
129 buf = append(buf, 'f')
130 }
131
132 return buf, nil
133 }
134
135 func (src Bool) EncodeBinary(ci *ConnInfo, buf []byte) ([]byte, error) {
136 switch src.Status {
137 case Null:
138 return nil, nil
139 case Undefined:
140 return nil, errUndefined
141 }
142
143 if src.Bool {
144 buf = append(buf, 1)
145 } else {
146 buf = append(buf, 0)
147 }
148
149 return buf, nil
150 }
151
152
153 func (dst *Bool) Scan(src interface{}) error {
154 if src == nil {
155 *dst = Bool{Status: Null}
156 return nil
157 }
158
159 switch src := src.(type) {
160 case bool:
161 *dst = Bool{Bool: src, Status: Present}
162 return nil
163 case string:
164 return dst.DecodeText(nil, []byte(src))
165 case []byte:
166 srcCopy := make([]byte, len(src))
167 copy(srcCopy, src)
168 return dst.DecodeText(nil, srcCopy)
169 }
170
171 return fmt.Errorf("cannot scan %T", src)
172 }
173
174
175 func (src Bool) Value() (driver.Value, error) {
176 switch src.Status {
177 case Present:
178 return src.Bool, nil
179 case Null:
180 return nil, nil
181 default:
182 return nil, errUndefined
183 }
184 }
185
186 func (src Bool) MarshalJSON() ([]byte, error) {
187 switch src.Status {
188 case Present:
189 if src.Bool {
190 return []byte("true"), nil
191 } else {
192 return []byte("false"), nil
193 }
194 case Null:
195 return []byte("null"), nil
196 case Undefined:
197 return nil, errUndefined
198 }
199
200 return nil, errBadStatus
201 }
202
203 func (dst *Bool) UnmarshalJSON(b []byte) error {
204 var v *bool
205 err := json.Unmarshal(b, &v)
206 if err != nil {
207 return err
208 }
209
210 if v == nil {
211 *dst = Bool{Status: Null}
212 } else {
213 *dst = Bool{Bool: *v, Status: Present}
214 }
215
216 return nil
217 }
218
View as plain text