-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnull.go
123 lines (99 loc) · 2.29 KB
/
null.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
package just
import (
"database/sql"
"database/sql/driver"
"errors"
"github.com/goccy/go-yaml"
)
// NullVal represents the nullable value for this type.
// Deprecated: Use github.com/kazhuravlev/optional.
type NullVal[T any] struct {
Val T `json:"v"`
Valid bool `json:"ok"`
}
// UnmarshalYAML implements the interface for unmarshalling yaml.
func (nv *NullVal[T]) UnmarshalYAML(bb []byte) error {
if len(bb) == 0 {
nv.Valid = false
nv.Val = *new(T)
return nil
}
if err := yaml.Unmarshal(bb, &nv.Val); err != nil {
return err
}
nv.Valid = true
return nil
}
// MarshalYAML implements the interface for marshaling yaml.
func (nv NullVal[T]) MarshalYAML() ([]byte, error) {
if !nv.Valid {
return []byte("null"), nil
}
return yaml.Marshal(nv.Val)
}
// Scan implements the Scanner interface.
func (nv *NullVal[T]) Scan(value any) error {
if v, ok := any(&nv.Val).(sql.Scanner); ok {
if err := v.Scan(value); err != nil {
nv.Val, nv.Valid = *new(T), false
return err
}
nv.Valid = true
return nil
}
if value == nil {
nv.Val, nv.Valid = *new(T), true
return nil
}
v, ok := value.(T)
if !ok {
return errors.New("unexpected value type")
}
nv.Valid = true
nv.Val = v
return nil
}
// Value implements the driver Valuer interface.
func (nv NullVal[T]) Value() (driver.Value, error) {
if !nv.Valid {
return nil, nil
}
if v, ok := any(nv.Val).(driver.Valuer); ok {
return v.Value()
}
return nv.Val, nil
}
// ValueOk returns the NullVal.Val and NullVal.Valid.
func (nv NullVal[T]) ValueOk() (T, bool) {
return nv.Val, nv.Valid
}
// SetDefault set value `val` if NullVal.Valid == false.
func (nv *NullVal[T]) SetDefault(val T) bool {
if nv.Valid {
return false
}
nv.Val = val
return true
}
// Null returns NullVal for `val` type, which are `NullVal.Valid == true`.
func Null[T any](val T) NullVal[T] {
return NullVal[T]{
Val: val,
Valid: true,
}
}
// NullNull returns NullVal, which are `NullVal.Valid == false`.
func NullNull[T any]() NullVal[T] {
return NullVal[T]{
Val: *new(T),
Valid: false,
}
}
// NullDefaultFalse returns NullVal for this type with Valid=true only when
// `val` is not equal to default value of type T.
func NullDefaultFalse[T comparable](val T) NullVal[T] {
return NullVal[T]{
Val: val,
Valid: val != *new(T),
}
}