-
Notifications
You must be signed in to change notification settings - Fork 0
/
json.go
108 lines (93 loc) · 1.78 KB
/
json.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
package jj
import (
"fmt"
"reflect"
"strconv"
)
// Unmarshal source -> struct
func Unmarshal(source string, v any) error {
rv := reflect.ValueOf(v)
if rv.Kind() != reflect.Pointer || rv.IsNil() {
return fmt.Errorf("input value invalid")
}
ast, err := UnmarshalAst(source)
if err != nil {
return err
}
switch ast.Type() {
case ObjectType:
}
ref := reflect.TypeOf(v)
numField := ref.NumField()
for i := 0; i < numField; i++ {
field := ref.Field(i)
j := field.Tag.Get("json")
if j == "" {
continue
}
// rv.Index(i).Set()
}
return nil
}
// UnmarshalAst string -> element
func UnmarshalAst(source string) (Elem, error) {
scanner := NewScanner(source)
tokens, err := scanner.ScanTokens()
if err != nil {
return nil, err
}
parser := NewParser(tokens)
elem, err := parser.Parse()
if err != nil {
return nil, err
}
return elem, err
}
// Marshal element -> string
func Marshal(elem Elem, whitespace string) string {
switch v := elem.(type) {
case *StringElem:
return "\"" + v.val + "\""
case *BoolElem:
if v.val {
return "true"
} else {
return "false"
}
case *NumberElem:
return strconv.FormatFloat(v.val, 'f', -1, 64)
case *NullElem:
return "null"
case *ArrayElem:
s := "[\n"
a := v.val
for i := 0; i < len(a); i++ {
value := a[i]
s += whitespace + " " + Marshal(value, whitespace+" ")
if i < len(a)-1 {
s += ","
}
s += "\n"
}
return s + whitespace + "]"
case *ObjectElem:
s := "{\n"
values := v.val
i := 0
for key, value := range values {
s += whitespace + " " + "\"" + key +
"\": " + Marshal(value, whitespace+" ")
if i < len(values)-1 {
s += ","
}
s += "\n"
i++
}
return s + whitespace + "}"
}
return ""
}
// PreTouch 预热 TODO
func PreTouch(v any) error {
return nil
}