...
1 package runtime
2
3 import (
4 "reflect"
5 "strings"
6 "unicode"
7 )
8
9 func getTag(field reflect.StructField) string {
10 return field.Tag.Get("json")
11 }
12
13 func IsIgnoredStructField(field reflect.StructField) bool {
14 if field.PkgPath != "" {
15 if field.Anonymous {
16 t := field.Type
17 if t.Kind() == reflect.Ptr {
18 t = t.Elem()
19 }
20 if t.Kind() != reflect.Struct {
21 return true
22 }
23 } else {
24
25 return true
26 }
27 }
28 tag := getTag(field)
29 return tag == "-"
30 }
31
32 type StructTag struct {
33 Key string
34 IsTaggedKey bool
35 IsOmitEmpty bool
36 IsString bool
37 Field reflect.StructField
38 }
39
40 type StructTags []*StructTag
41
42 func (t StructTags) ExistsKey(key string) bool {
43 for _, tt := range t {
44 if tt.Key == key {
45 return true
46 }
47 }
48 return false
49 }
50
51 func isValidTag(s string) bool {
52 if s == "" {
53 return false
54 }
55 for _, c := range s {
56 switch {
57 case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c):
58
59
60
61 case !unicode.IsLetter(c) && !unicode.IsDigit(c):
62 return false
63 }
64 }
65 return true
66 }
67
68 func StructTagFromField(field reflect.StructField) *StructTag {
69 keyName := field.Name
70 tag := getTag(field)
71 st := &StructTag{Field: field}
72 opts := strings.Split(tag, ",")
73 if len(opts) > 0 {
74 if opts[0] != "" && isValidTag(opts[0]) {
75 keyName = opts[0]
76 st.IsTaggedKey = true
77 }
78 }
79 st.Key = keyName
80 if len(opts) > 1 {
81 for _, opt := range opts[1:] {
82 switch opt {
83 case "omitempty":
84 st.IsOmitEmpty = true
85 case "string":
86 st.IsString = true
87 }
88 }
89 }
90 return st
91 }
92
View as plain text