/
custom_types.go
58 lines (48 loc) · 1.2 KB
/
custom_types.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
package myddlmaker
import (
"bytes"
"database/sql"
"database/sql/driver"
"encoding/json"
"fmt"
"io"
"strings"
)
var _ driver.Valuer = JSON[int]{}
var _ sql.Scanner = (*JSON[int])(nil)
// JSON[T] represents a MySQL JSON type tied to Go types.
// It is EXPERIMENTAL feature.
type JSON[T any] [1]T
// Get returns the value of v.
func (v JSON[T]) Get() T {
return v[0]
}
// Set sets v = u.
func (v *JSON[T]) Set(u T) {
v[0] = u
}
// Value implements [database/sql/driver.Valuer] interface.
func (v JSON[T]) Value() (driver.Value, error) {
return json.Marshal(v[0])
}
// Scan implements [database/sql.Scanner] interface.
func (v *JSON[T]) Scan(src any) error {
var r io.Reader
switch src := src.(type) {
case []byte:
r = bytes.NewReader(src)
case string:
r = strings.NewReader(src)
default:
return fmt.Errorf("myddlmaker: unsupported type: %T", src)
}
dec := json.NewDecoder(r)
return dec.Decode(&v[0])
}
type jsonMarker interface {
jsonMarker()
}
// jsonMarker is a marker for the reflect package.
// On Go 1.19, the reflect package can't handle generic types correctly.
// However, it can handle a interface implemented by generic types.
func (v JSON[T]) jsonMarker() { /* nothing to do */ }