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}