Skip to content

Commit 9291c3b

Browse files
authored
allow serialization of field having no group tag (#29)
1 parent 040b323 commit 9291c3b

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

sheriff.go

+19-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ type Options struct {
2323
// Specifying a since setting of "2" with the same API version specified,
2424
// will not marshal the field.
2525
ApiVersion *version.Version
26+
// IncludeEmptyTag determines whether a field without the
27+
// `groups` tag should be marshalled ot not.
28+
// This option is false by default.
29+
IncludeEmptyTag bool
2630

2731
// This is used internally so that we can propagate anonymous fields groups tag to all child field.
2832
nestedGroupsMap map[string][]string
@@ -131,8 +135,21 @@ func Marshal(options *Options, data interface{}) (interface{}, error) {
131135
if len(groups) == 0 && options.nestedGroupsMap[field.Name] != nil {
132136
groups = append(groups, options.nestedGroupsMap[field.Name]...)
133137
}
134-
shouldShow := listContains(groups, options.Groups)
135-
if !shouldShow || len(groups) == 0 {
138+
139+
// Marshall the field if
140+
// - it has at least one of the requested groups
141+
// or
142+
// - it has no group and 'IncludeEmptyTag' is set to true
143+
shouldShow := listContains(groups, options.Groups) || (len(groups) == 0 && options.IncludeEmptyTag)
144+
145+
// Prevent marshalling of the field if
146+
// - it should not be shown (above)
147+
// or
148+
// - it has no groups and 'IncludeEmptyTag' is set to false
149+
shouldHide := !shouldShow || (len(groups) == 0 && !options.IncludeEmptyTag)
150+
151+
if shouldHide {
152+
// skip this field
136153
continue
137154
}
138155
}

sheriff_test.go

+38
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type TestGroupsModel struct {
2626
OmitEmptyGroupTest string `json:"omit_empty_group_test,omitempty" groups:"test"`
2727
SliceString []string `json:"slice_string,omitempty" groups:"test"`
2828
MapStringStruct map[string]AModel `json:"map_string_struct,omitempty" groups:"test,test-other"`
29+
IncludeEmptyTag string `json:"include_empty_tag"`
2930
}
3031

3132
func TestMarshal_GroupsValidGroup(t *testing.T) {
@@ -141,6 +142,7 @@ func TestMarshal_GroupsNoGroups(t *testing.T) {
141142
GroupTestAndOther: "GroupTestAndOther",
142143
OmitEmpty: "OmitEmpty",
143144
OmitEmptyGroupTest: "OmitEmptyGroupTest",
145+
IncludeEmptyTag: "IncludeEmptyTag",
144146
MapStringStruct: map[string]AModel{"firstModel": {true, true}},
145147
}
146148

@@ -165,6 +167,42 @@ func TestMarshal_GroupsNoGroups(t *testing.T) {
165167
},
166168
"omit_empty": "OmitEmpty",
167169
"omit_empty_group_test": "OmitEmptyGroupTest",
170+
"include_empty_tag": "IncludeEmptyTag",
171+
})
172+
assert.NoError(t, err)
173+
174+
assert.Equal(t, string(expected), string(actual))
175+
}
176+
177+
func TestMarshal_GroupsValidGroupIncludeEmptyTag(t *testing.T) {
178+
testModel := &TestGroupsModel{
179+
DefaultMarshal: "DefaultMarshal",
180+
OnlyGroupTest: "OnlyGroupTest",
181+
GroupTestAndOther: "GroupTestAndOther",
182+
OmitEmpty: "OmitEmpty",
183+
OmitEmptyGroupTest: "",
184+
SliceString: []string{"test", "bla"},
185+
IncludeEmptyTag: "IncludeEmptyTag",
186+
}
187+
188+
o := &Options{
189+
IncludeEmptyTag: true,
190+
Groups: []string{"test"},
191+
}
192+
193+
actualMap, err := Marshal(o, testModel)
194+
assert.NoError(t, err)
195+
196+
actual, err := json.Marshal(actualMap)
197+
assert.NoError(t, err)
198+
199+
expected, err := json.Marshal(map[string]interface{}{
200+
"default_marshal": "DefaultMarshal",
201+
"only_group_test": "OnlyGroupTest",
202+
"group_test_and_other": "GroupTestAndOther",
203+
"omit_empty": "OmitEmpty",
204+
"slice_string": []string{"test", "bla"},
205+
"include_empty_tag": "IncludeEmptyTag",
168206
})
169207
assert.NoError(t, err)
170208

0 commit comments

Comments
 (0)