forked from zmitry/go2typings
-
Notifications
You must be signed in to change notification settings - Fork 0
/
field.go
89 lines (78 loc) · 2.19 KB
/
field.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
package go2types
import (
"bytes"
"fmt"
"reflect"
"text/template"
)
// some const
const (
DefaultFieldTemplate = `{{.Indent}}{{.Name}}{{if .IsOptional}}?{{end}}: {{.TsType}}{{if .CanBeNull}} | null{{end}};{{if .Doc}} // {{.Doc}}{{end}}`
)
// Field field of struct
type Field struct {
Template string //render template
Indent string
Anomynous bool
Omitted bool //is field ignored, name start with lower case OR json:"-"
Doc string
Name string `json:"name"`
TsType string `json:"type"`
CanBeNull bool `json:"canBeNull"`
IsOptional bool `json:"isOptional"` //Ptr type OR json omitempty
IsDate bool `json:"isDate"`
T reflect.Type
// for map[KeyType]ValType
KeyType string `json:"keyType,omitempty"`
ValType string `json:"valType,omitempty"`
}
// TagJSON .
type TagJSON struct {
Exists bool
Omitted bool
Omitempty bool
Name string
}
func (t TagJSON) defaultIfNameEmpty(name string) string {
if t.Name != "" {
return t.Name
}
return name
}
// ParseField return: parsed field, isAnomynous, isStruct
func ParseField(sf reflect.StructField, go2tsTypes map[reflect.Type]string, structType reflect.Type) *Field {
tagJSON := parseTagJSON(sf.Tag.Get("json"))
typ, kind := sf.Type, sf.Type.Kind()
f := Field{
Anomynous: sf.Anonymous,
T: typ,
Omitted: tagJSON.Omitted || hasLowerCasePrefix(sf.Name),
Name: tagJSON.defaultIfNameEmpty(sf.Name),
IsOptional: tagJSON.Exists && tagJSON.Omitempty,
CanBeNull: !tagJSON.Omitempty && (kind == reflect.Ptr || kind == reflect.Slice || kind == reflect.Map),
IsDate: isDate(typ),
Doc: structFieldTags(sf) + getDoc(structType.PkgPath(), structType.Name()+"."+sf.Name, docTypeStructField),
}
if v, ok := go2tsTypes[typ]; ok {
f.TsType = v
} else {
f.TsType = toTypescriptType(typ)
}
if !tagJSON.Exists {
f.TsType = sf.Name
}
return &f
}
// MustRender .
func (f *Field) MustRender() string {
t := f.Template
if t == "" {
t = DefaultFieldTemplate
}
buffer := bytes.NewBuffer(nil)
err := template.Must(template.New("field_tpl").Parse(t)).Execute(buffer, f)
if err != nil {
panic(fmt.Errorf("template execute error, %v", err))
}
return string(buffer.Bytes())
}