Skip to content

Commit 4f34235

Browse files
authored
feature: add suport of mapstructure struct tags in struct-tag rule (#1241)
1 parent a4ee892 commit 4f34235

File tree

4 files changed

+42
-10
lines changed

4 files changed

+42
-10
lines changed

rule/struct_tag.go

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -98,16 +98,17 @@ func (w lintStructTagRule) Visit(node ast.Node) ast.Visitor {
9898
}
9999

100100
const (
101-
keyASN1 = "asn1"
102-
keyBSON = "bson"
103-
keyDatastore = "datastore"
104-
keyDefault = "default"
105-
keyJSON = "json"
106-
keyProtobuf = "protobuf"
107-
keyRequired = "required"
108-
keyURL = "url"
109-
keyXML = "xml"
110-
keyYAML = "yaml"
101+
keyASN1 = "asn1"
102+
keyBSON = "bson"
103+
keyDatastore = "datastore"
104+
keyDefault = "default"
105+
keyJSON = "json"
106+
keyMapstructure = "mapstructure"
107+
keyProtobuf = "protobuf"
108+
keyRequired = "required"
109+
keyURL = "url"
110+
keyXML = "xml"
111+
keyYAML = "yaml"
111112
)
112113

113114
func (w lintStructTagRule) checkTagNameIfNeed(tag *structtag.Tag) (string, bool) {
@@ -196,6 +197,11 @@ func (w lintStructTagRule) checkTaggedField(f *ast.Field) {
196197
if !ok {
197198
w.addFailure(f.Tag, msg)
198199
}
200+
case keyMapstructure:
201+
msg, ok := w.checkMapstructureTag(tag.Options)
202+
if !ok {
203+
w.addFailure(f.Tag, msg)
204+
}
199205
case keyProtobuf:
200206
msg, ok := w.checkProtobufTag(tag)
201207
if !ok {
@@ -379,6 +385,21 @@ func (w lintStructTagRule) checkDatastoreTag(options []string) (string, bool) {
379385
return "", true
380386
}
381387

388+
func (w lintStructTagRule) checkMapstructureTag(options []string) (string, bool) {
389+
for _, opt := range options {
390+
switch opt {
391+
case "omitempty", "reminder", "squash":
392+
default:
393+
if w.isUserDefined(keyMapstructure, opt) {
394+
continue
395+
}
396+
return fmt.Sprintf("unknown option '%s' in Mapstructure tag", opt), false
397+
}
398+
}
399+
400+
return "", true
401+
}
402+
382403
func (lintStructTagRule) typeValueMatch(t ast.Expr, val string) bool {
383404
tID, ok := t.(*ast.Ident)
384405
if !ok {

test/struct_tag_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ func TestStructTagWithUserOptions(t *testing.T) {
1818
"bson,gnu",
1919
"url,myURLOption",
2020
"datastore,myDatastoreOption",
21+
"mapstructure,myMapstructureOption",
2122
},
2223
})
2324
}

testdata/struct_tag.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,8 @@ type Fields struct {
141141
Field string `datastore:",noindex,flatten,omitempty"`
142142
OtherField string `datastore:",unknownOption"` // MATCH /unknown option 'unknownOption' in Datastore tag/
143143
}
144+
145+
type MapStruct struct {
146+
Field1 string `mapstructure:",squash,reminder,omitempty"`
147+
OtherField string `mapstructure:",unknownOption"` // MATCH /unknown option 'unknownOption' in Mapstructure tag/
148+
}

testdata/struct_tag_user_options.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,8 @@ type Fields struct {
2424
Field string `datastore:",noindex,flatten,omitempty,myDatastoreOption"`
2525
OtherField string `datastore:",unknownOption"` // MATCH /unknown option 'unknownOption' in Datastore tag/
2626
}
27+
28+
type MapStruct struct {
29+
Field1 string `mapstructure:",squash,reminder,omitempty,myMapstructureOption"`
30+
OtherField string `mapstructure:",unknownOption"` // MATCH /unknown option 'unknownOption' in Mapstructure tag/
31+
}

0 commit comments

Comments
 (0)