-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstruct.go
132 lines (111 loc) · 2.85 KB
/
struct.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package textra
// Struct represents a single struct.
type Struct []Field
// ByTagName returns a slice of fields which contain given tag.
func (s Struct) ByTagName(tag string) Struct {
filtered := make(Struct, 0)
for _, field := range s {
for _, t := range field.Tags {
if t.Tag == tag {
filtered = append(filtered, field)
break
}
}
}
return filtered
}
// ByTagNameAny returns a slice of fields which contain at least one tag.
func (s Struct) ByTagNameAny(tags ...string) Struct {
filtered := make(Struct, 0)
tagsUnique := toUniqueMap(tags...)
for _, field := range s {
for _, t := range field.Tags {
if _, ok := tagsUnique[t.Tag]; ok {
filtered = append(filtered, field)
break
}
}
}
return filtered
}
// ByTagNameAll returns a slice of fields which contain all of the tags.
func (s Struct) ByTagNameAll(tags ...string) Struct {
filtered := make(Struct, 0)
tagsUnique := toUniqueMap(tags...)
shouldMatch := len(tags)
for _, field := range s {
matched := 0
for _, t := range field.Tags {
if _, ok := tagsUnique[t.Tag]; ok {
matched++
}
}
if matched != 0 && matched == shouldMatch {
filtered = append(filtered, field)
}
}
return filtered
}
// Field returns a field by name.
func (s Struct) Field(name string) (Field, bool) {
for _, field := range s {
if field.Name == name {
return field, true
}
}
return Field{}, false
}
// FilterFunc returns a slice of fields, filtered by fn(field) == true.
func (s Struct) FilterFunc(fn func(Field) bool) Struct {
filtered := make(Struct, 0)
for _, f := range s {
if fn(f) {
filtered = append(filtered, f)
}
}
return filtered
}
// RemoveEmpty removes any field from a Struct that has an empty "Tags" field.
func (s Struct) RemoveEmpty() Struct {
filtered := make(Struct, 0)
for _, field := range s {
if len(field.Tags) > 0 {
filtered = append(filtered, field)
}
}
return filtered
}
// RemoveFields removes fields by their names from a Struct and returns a new Struct.
func (s Struct) RemoveFields(fields ...string) Struct {
filtered := make(Struct, 0, len(s)-len(fields))
fieldsUnique := toUniqueMap(fields...)
for _, field := range s {
if _, ok := fieldsUnique[field.Name]; !ok {
filtered = append(filtered, field)
}
}
return filtered
}
// OnlyTag returns a slice of fields that match the given tag name.
// FieldTag is returned (instead of Struct like other filters) because the
// expected output is a slice of fields with only one tag.
func (s Struct) OnlyTag(name string) []FieldTag {
filtered := make([]FieldTag, 0)
for _, field := range s {
if tag, ok := field.Tags.ByName(name); ok {
filtered = append(filtered, FieldTag{
Name: field.Name,
Type: field.Type,
Tag: tag,
})
}
}
return filtered
}
func (s Struct) String() string {
var str string
for _, field := range s {
str += field.String()
}
return str
}