json.go

 1package util
 2
 3import (
 4	"encoding/json"
 5	"math"
 6	"strconv"
 7	"time"
 8	"unsafe"
 9)
10
11type JSON struct{ Value any }
12
13func (j JSON) Scan(value any) error {
14	var buf []byte
15
16	switch v := value.(type) {
17	case []byte:
18		buf = v
19	case string:
20		buf = unsafe.Slice(unsafe.StringData(v), len(v))
21	case int64:
22		buf = strconv.AppendInt(nil, v, 10)
23	case float64:
24		buf = AppendNumber(nil, v)
25	case time.Time:
26		buf = append(buf, '"')
27		buf = v.AppendFormat(buf, time.RFC3339Nano)
28		buf = append(buf, '"')
29	case nil:
30		buf = []byte("null")
31	default:
32		panic(AssertErr())
33	}
34
35	return json.Unmarshal(buf, j.Value)
36}
37
38func AppendNumber(dst []byte, f float64) []byte {
39	switch {
40	case math.IsNaN(f):
41		dst = append(dst, "null"...)
42	case math.IsInf(f, 1):
43		dst = append(dst, "9.0e999"...)
44	case math.IsInf(f, -1):
45		dst = append(dst, "-9.0e999"...)
46	default:
47		return strconv.AppendFloat(dst, f, 'g', -1, 64)
48	}
49	return dst
50}