Skip to content

Commit c561096

Browse files
committed
feat: null string scanner and marshaller
0 parents  commit c561096

File tree

3 files changed

+121
-0
lines changed

3 files changed

+121
-0
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.idea
2+
.DS_STORE
3+
.vscode
4+
cmd/

string.go

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package null
2+
3+
import (
4+
"database/sql"
5+
"database/sql/driver"
6+
"encoding/json"
7+
)
8+
9+
type String struct {
10+
nullValue *sql.NullString
11+
}
12+
13+
func (s String) String() string {
14+
if s.nullValue != nil {
15+
return s.nullValue.String
16+
}
17+
18+
return ""
19+
}
20+
21+
func NewString(value string) String {
22+
return String{
23+
nullValue: &sql.NullString{
24+
Valid: value != "",
25+
String: value,
26+
},
27+
}
28+
}
29+
30+
func (s String) Get() string {
31+
if s.nullValue != nil {
32+
return s.nullValue.String
33+
}
34+
35+
return ""
36+
}
37+
38+
func (s *String) Value() (driver.Value, error) {
39+
if s.nullValue != nil {
40+
return s.nullValue.Value()
41+
}
42+
43+
return nil, nil
44+
}
45+
46+
func (s *String) Scan(value any) error {
47+
if err := s.nullValue.Scan(value); err != nil {
48+
return err
49+
}
50+
51+
return nil
52+
}
53+
54+
func (s *String) UnmarshalJSON(bytes []byte) error {
55+
s.nullValue = &sql.NullString{
56+
String: "",
57+
Valid: false,
58+
}
59+
60+
if len(bytes) > 0 {
61+
if err := json.Unmarshal(bytes, &s.nullValue.String); err != nil {
62+
return err
63+
}
64+
}
65+
66+
return nil
67+
}
68+
69+
func (s String) MarshalJSON() ([]byte, error) {
70+
if s.nullValue.Valid && s.nullValue.String != "" {
71+
return json.Marshal(s.nullValue.String)
72+
}
73+
74+
return json.Marshal(nil)
75+
}

string_test.go

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package null
2+
3+
import (
4+
"encoding/json"
5+
"reflect"
6+
"testing"
7+
)
8+
9+
func TestString(t *testing.T) {
10+
testCases := []struct {
11+
name string
12+
s String
13+
marshalledBytes []byte
14+
}{
15+
{
16+
name: "Not null marshaller",
17+
s: NewString("test"),
18+
marshalledBytes: []byte(`"test"`),
19+
},
20+
{
21+
name: "null marshaller",
22+
s: NewString(""),
23+
marshalledBytes: []byte(`null`),
24+
},
25+
}
26+
27+
for _, tc := range testCases {
28+
t.Run(tc.name, func(t *testing.T) {
29+
bytes, err := json.Marshal(tc.s)
30+
31+
if err != nil {
32+
t.Errorf("could not marshal: %v\n", err)
33+
t.FailNow()
34+
}
35+
36+
if !reflect.DeepEqual(bytes, tc.marshalledBytes) {
37+
t.Errorf("not equal values => got: %v, want: %v\n", string(bytes), string(tc.marshalledBytes))
38+
t.FailNow()
39+
}
40+
})
41+
}
42+
}

0 commit comments

Comments
 (0)