Skip to content

Commit f4fe206

Browse files
author
Tao Wen
committed
test []string
1 parent 0a4c85f commit f4fe206

File tree

6 files changed

+184
-31
lines changed

6 files changed

+184
-31
lines changed

gen/main.go

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"go/ast"
7+
"go/parser"
8+
"go/printer"
9+
"go/token"
10+
"os"
11+
"path/filepath"
12+
"strconv"
13+
"strings"
14+
)
15+
16+
var fset = token.NewFileSet()
17+
var lines = []byte{}
18+
var cwd string
19+
var indent = 0
20+
21+
func init() {
22+
var err error
23+
cwd, err = os.Getwd()
24+
if err != nil {
25+
reportError(err)
26+
return
27+
}
28+
}
29+
30+
func main() {
31+
appendLine(fmt.Sprintf("package %s", os.Getenv("GOPACKAGE")))
32+
appendNewLine()
33+
appendLine(`import jsoniter "github.com/json-iterator/tinygo"`)
34+
appendNewLine()
35+
typeSpec := locateTypeSpec()
36+
switch x := typeSpec.Type.(type) {
37+
case *ast.ArrayType:
38+
genArray(x)
39+
default:
40+
reportError(fmt.Errorf("unknown type of TypeSpec"))
41+
return
42+
}
43+
outputPath := filepath.Join(cwd, fmt.Sprintf("%s_json.go", typeSpec.Name.Name))
44+
os.WriteFile(outputPath, lines, 0644)
45+
}
46+
47+
func reportError(err error) {
48+
panic(err)
49+
}
50+
51+
func appendLine(line string) {
52+
for i := 0; i < indent; i++ {
53+
lines = append(lines, ' ')
54+
print(" ")
55+
}
56+
lines = append(lines, line...)
57+
lines = append(lines, '\n')
58+
println(line)
59+
}
60+
61+
func appendNewLine() {
62+
appendLine("")
63+
}
64+
65+
func enter(line string) {
66+
appendLine(line)
67+
indent += 4
68+
}
69+
70+
func exit(line string) {
71+
indent -= 4
72+
appendLine(line)
73+
}
74+
75+
func nodeToString(node ast.Node) string {
76+
buf := bytes.NewBuffer([]byte{})
77+
err := printer.Fprint(buf, fset, node)
78+
if err != nil {
79+
reportError(err)
80+
return ""
81+
}
82+
return buf.String()
83+
}
84+
85+
func escapeTypeName(typeName string) string {
86+
return strings.ReplaceAll(typeName, "[]", "array_")
87+
}
88+
89+
func genArray(arrayType *ast.ArrayType) {
90+
typeName := nodeToString(arrayType)
91+
enter(fmt.Sprintf("func jd_%s(iter *jsoniter.Iterator) %s {", escapeTypeName(typeName), typeName))
92+
appendLine(fmt.Sprintf("var val = %s{}", typeName))
93+
appendLine("if iter.Error != nil { return val }")
94+
enter("for iter.ReadArray() {")
95+
switch x := arrayType.Elt.(type) {
96+
case *ast.Ident:
97+
if x.Name == "string" {
98+
appendLine("val = append(val, iter.ReadString())")
99+
} else {
100+
reportError(fmt.Errorf("unknown element type of Array: %s", x.Name))
101+
return
102+
}
103+
default:
104+
reportError(fmt.Errorf("unknown element type of Array"))
105+
return
106+
}
107+
exit("}")
108+
appendLine("return val")
109+
exit("}")
110+
}
111+
112+
func locateTypeSpec() *ast.TypeSpec {
113+
goline, err := strconv.Atoi(os.Getenv("GOLINE"))
114+
if err != nil {
115+
reportError(err)
116+
return nil
117+
}
118+
f, err := parser.ParseFile(fset, os.Getenv("GOFILE"), nil, parser.ParseComments)
119+
if err != nil {
120+
reportError(err)
121+
return nil
122+
}
123+
var located *ast.TypeSpec
124+
ast.Inspect(f, func(n ast.Node) bool {
125+
switch x := n.(type) {
126+
case *ast.TypeSpec:
127+
if goline+1 == fset.Position(x.Pos()).Line {
128+
located = x
129+
}
130+
return false
131+
}
132+
return true
133+
})
134+
if located == nil {
135+
reportError(fmt.Errorf("%s:%s go generate should be marked just before type definition",
136+
os.Getenv("GOFILE"), os.Getenv("GOLINE")))
137+
return nil
138+
}
139+
return located
140+
}

go.mod

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
11
module github.com/json-iterator/tinygo
22

3-
go 1.12
4-
5-
require (
6-
)
3+
go 1.12

iter.go

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
// ValueType the type for JSON element
99
type ValueType int
1010

11+
type RawMessage []byte
12+
1113
const (
1214
// InvalidValue invalid JSON element
1315
InvalidValue ValueType = iota

tests/iter_test.go

-27
This file was deleted.

value_tests/ArrayOfString_json.go

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package main
2+
3+
import jsoniter "github.com/json-iterator/tinygo"
4+
5+
func jd_array_string(iter *jsoniter.Iterator) []string {
6+
var val = []string{}
7+
if iter.Error != nil { return val }
8+
for iter.ReadArray() {
9+
val = append(val, iter.ReadString())
10+
}
11+
return val
12+
}

value_tests/array_test.go

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
6+
jsoniter "github.com/json-iterator/tinygo"
7+
)
8+
9+
//go:generate go run github.com/json-iterator/tinygo/gen
10+
type ArrayOfString = []string
11+
12+
func Test_empty_array(t *testing.T) {
13+
iter := jsoniter.ParseBytes([]byte(`[]`))
14+
val := jd_array_string(iter)
15+
if len(val) != 0 {
16+
t.Fail()
17+
}
18+
}
19+
20+
func Test_one_element_array(t *testing.T) {
21+
iter := jsoniter.ParseBytes([]byte(`["hello"]`))
22+
val := jd_array_string(iter)
23+
if len(val) != 1 {
24+
t.Fail()
25+
}
26+
if val[0] != "hello" {
27+
t.Fail()
28+
}
29+
}

0 commit comments

Comments
 (0)