Skip to content

Commit a4ee892

Browse files
authored
feature: add support of datastore struct tags in struct-tag rume (#1240)
1 parent 3cf67c5 commit a4ee892

File tree

4 files changed

+46
-10
lines changed

4 files changed

+46
-10
lines changed

rule/struct_tag.go

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

100100
const (
101-
keyASN1 = "asn1"
102-
keyBSON = "bson"
103-
keyDefault = "default"
104-
keyJSON = "json"
105-
keyProtobuf = "protobuf"
106-
keyRequired = "required"
107-
keyURL = "url"
108-
keyXML = "xml"
109-
keyYAML = "yaml"
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"
110111
)
111112

112113
func (w lintStructTagRule) checkTagNameIfNeed(tag *structtag.Tag) (string, bool) {
@@ -181,6 +182,11 @@ func (w lintStructTagRule) checkTaggedField(f *ast.Field) {
181182
if !ok {
182183
w.addFailure(f.Tag, msg)
183184
}
185+
case keyDatastore:
186+
msg, ok := w.checkDatastoreTag(tag.Options)
187+
if !ok {
188+
w.addFailure(f.Tag, msg)
189+
}
184190
case keyDefault:
185191
if !w.typeValueMatch(f.Type, tag.Name) {
186192
w.addFailure(f.Tag, "field's type and default value's type mismatch")
@@ -358,6 +364,21 @@ func (w lintStructTagRule) checkURLTag(options []string) (string, bool) {
358364
return "", true
359365
}
360366

367+
func (w lintStructTagRule) checkDatastoreTag(options []string) (string, bool) {
368+
for _, opt := range options {
369+
switch opt {
370+
case "flatten", "noindex", "omitempty":
371+
default:
372+
if w.isUserDefined(keyDatastore, opt) {
373+
continue
374+
}
375+
return fmt.Sprintf("unknown option '%s' in Datastore tag", opt), false
376+
}
377+
}
378+
379+
return "", true
380+
}
381+
361382
func (lintStructTagRule) typeValueMatch(t ast.Expr, val string) bool {
362383
tID, ok := t.(*ast.Ident)
363384
if !ok {

test/struct_tag_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@ func TestStructTag(t *testing.T) {
1313

1414
func TestStructTagWithUserOptions(t *testing.T) {
1515
testRule(t, "struct_tag_user_options", &rule.StructTagRule{}, &lint.RuleConfig{
16-
Arguments: []any{"json,inline,outline", "bson,gnu", "url,myURLOption"},
16+
Arguments: []any{
17+
"json,inline,outline",
18+
"bson,gnu",
19+
"url,myURLOption",
20+
"datastore,myDatastoreOption",
21+
},
1722
})
1823
}
1924

testdata/struct_tag.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,8 @@ type RequestQueryOption struct {
136136
Archived bool `url:"archived,myURLOption"` // MATCH /unknown option 'myURLOption' in URL tag/
137137
IDProperty string `url:"idProperty,omitempty"`
138138
}
139+
140+
type Fields struct {
141+
Field string `datastore:",noindex,flatten,omitempty"`
142+
OtherField string `datastore:",unknownOption"` // MATCH /unknown option 'unknownOption' in Datastore tag/
143+
}

testdata/struct_tag_user_options.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,8 @@ type RequestQueryOptions struct {
1919
CustomProperties []string `url:"-"`
2020
Archived bool `url:"archived,myURLOption"`
2121
}
22+
23+
type Fields struct {
24+
Field string `datastore:",noindex,flatten,omitempty,myDatastoreOption"`
25+
OtherField string `datastore:",unknownOption"` // MATCH /unknown option 'unknownOption' in Datastore tag/
26+
}

0 commit comments

Comments
 (0)