-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathnull_string.go
170 lines (148 loc) · 3.66 KB
/
null_string.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
package typ
import (
"database/sql/driver"
"encoding/json"
)
// StringCommon represents a string that may be null.
type StringCommon struct {
P *string
Error error
}
// Set saves value into current struct
func (n *StringCommon) Set(value string) {
n.P = &value
}
// V returns value of underlying type if it was set, otherwise default value
func (n StringCommon) V() string {
if n.P == nil {
return ""
}
return *n.P
}
// Present determines whether a value has been set
func (n StringCommon) Present() bool {
return n.P != nil
}
// Valid determines whether a value has been valid
func (n StringCommon) Valid() bool {
return n.Err() == nil
}
// Value implements the sql driver Valuer interface.
func (n StringCommon) Value() (driver.Value, error) {
return n.V(), nil
}
// Scan implements the sql Scanner interface.
func (n *StringCommon) Scan(value interface{}) error {
n.P, n.Error = nil, nil
if value == nil {
return nil
}
if v, ok := value.([]byte); ok {
value = string(v)
}
v := Of(value).String()
n.Set(v.V())
n.Error = v.Err()
return v.Err()
}
// UnmarshalJSON implements the json Unmarshaler interface.
func (n *StringCommon) UnmarshalJSON(b []byte) error {
n.P, n.Error = nil, nil
var uv interface{}
if err := json.Unmarshal(b, &uv); err != nil {
n.Error = err
return err
}
if uv == nil {
return nil
}
v, ok := uv.(string)
if !ok {
n.Error = ErrConvert
return n.Err()
}
n.P = &v
return nil
}
// MarshalJSON implements the json Marshaler interface.
func (n StringCommon) MarshalJSON() ([]byte, error) {
return json.Marshal(n.V())
}
// Typ returns new instance with himself value.
// If current value is invalid, nil *Type returned
func (n StringCommon) Typ(options ...Option) *Type {
if n.Err() != nil {
return NewType(nil, n.Err())
}
return NewType(n.V(), n.Err(), options...)
}
// Err returns underlying error.
func (n StringCommon) Err() error {
return n.Error
}
// StringAccessor accessor of string type.
type StringAccessor interface {
Common
V() string
Set(value string)
Clone() StringAccessor
}
// NullString represents a string that may be null.
type NullString struct {
StringCommon
}
// Value implements the sql driver Valuer interface.
func (n NullString) Value() (driver.Value, error) {
if n.Err() != nil || !n.Present() {
return nil, n.Err()
}
return n.StringCommon.Value()
}
// MarshalJSON implements the json Marshaler interface.
func (n NullString) MarshalJSON() ([]byte, error) {
if n.Err() != nil || !n.Present() {
return json.Marshal(nil)
}
return n.StringCommon.MarshalJSON()
}
// Clone returns new instance of NullString with preserved value & error
func (n NullString) Clone() StringAccessor {
nv := &NullString{}
if n.Present() {
nv.Set(n.V())
}
nv.Error = n.Error
return nv
}
// NString returns NullString under StringAccessor from string
func NString(value string) StringAccessor {
return &NullString{StringCommon{P: &value}}
}
// NotNullString represents a string that may be null.
type NotNullString struct {
StringCommon
}
// Clone returns new instance of NotNullString with preserved value & error
func (n NotNullString) Clone() StringAccessor {
nv := &NotNullString{}
if n.Present() {
nv.Set(n.V())
}
nv.Error = n.Error
return nv
}
// NNString returns NullString under StringAccessor from string
func NNString(value string) StringAccessor {
return &NotNullString{StringCommon{P: &value}}
}
// StringSlice returns slice of string with filled values from slice of StringAccessor
func StringSlice(null []StringAccessor, valid bool) []string {
slice := make([]string, 0, len(null))
for _, v := range null {
if valid && v.Err() != nil {
continue
}
slice = append(slice, v.V())
}
return slice
}