Skip to content

Commit

Permalink
allow serialization of field having no group tag (liip#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
masseelch authored and kevinlynx committed Jul 28, 2021
1 parent c435f42 commit 0e83d19
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 2 deletions.
21 changes: 19 additions & 2 deletions sheriff.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ type Options struct {
// Specifying a since setting of "2" with the same API version specified,
// will not marshal the field.
ApiVersion *version.Version
// IncludeEmptyTag determines whether a field without the
// `groups` tag should be marshalled ot not.
// This option is false by default.
IncludeEmptyTag bool

// This is used internally so that we can propagate anonymous fields groups tag to all child field.
nestedGroupsMap map[string][]string
Expand Down Expand Up @@ -131,8 +135,21 @@ func Marshal(options *Options, data interface{}) (interface{}, error) {
if len(groups) == 0 && options.nestedGroupsMap[field.Name] != nil {
groups = append(groups, options.nestedGroupsMap[field.Name]...)
}
shouldShow := listContains(groups, options.Groups)
if !shouldShow || len(groups) == 0 {

// Marshall the field if
// - it has at least one of the requested groups
// or
// - it has no group and 'IncludeEmptyTag' is set to true
shouldShow := listContains(groups, options.Groups) || (len(groups) == 0 && options.IncludeEmptyTag)

// Prevent marshalling of the field if
// - it should not be shown (above)
// or
// - it has no groups and 'IncludeEmptyTag' is set to false
shouldHide := !shouldShow || (len(groups) == 0 && !options.IncludeEmptyTag)

if shouldHide {
// skip this field
continue
}
}
Expand Down
38 changes: 38 additions & 0 deletions sheriff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type TestGroupsModel struct {
OmitEmptyGroupTest string `json:"omit_empty_group_test,omitempty" groups:"test"`
SliceString []string `json:"slice_string,omitempty" groups:"test"`
MapStringStruct map[string]AModel `json:"map_string_struct,omitempty" groups:"test,test-other"`
IncludeEmptyTag string `json:"include_empty_tag"`
}

func TestMarshal_GroupsValidGroup(t *testing.T) {
Expand Down Expand Up @@ -141,6 +142,7 @@ func TestMarshal_GroupsNoGroups(t *testing.T) {
GroupTestAndOther: "GroupTestAndOther",
OmitEmpty: "OmitEmpty",
OmitEmptyGroupTest: "OmitEmptyGroupTest",
IncludeEmptyTag: "IncludeEmptyTag",
MapStringStruct: map[string]AModel{"firstModel": {true, true}},
}

Expand All @@ -165,6 +167,42 @@ func TestMarshal_GroupsNoGroups(t *testing.T) {
},
"omit_empty": "OmitEmpty",
"omit_empty_group_test": "OmitEmptyGroupTest",
"include_empty_tag": "IncludeEmptyTag",
})
assert.NoError(t, err)

assert.Equal(t, string(expected), string(actual))
}

func TestMarshal_GroupsValidGroupIncludeEmptyTag(t *testing.T) {
testModel := &TestGroupsModel{
DefaultMarshal: "DefaultMarshal",
OnlyGroupTest: "OnlyGroupTest",
GroupTestAndOther: "GroupTestAndOther",
OmitEmpty: "OmitEmpty",
OmitEmptyGroupTest: "",
SliceString: []string{"test", "bla"},
IncludeEmptyTag: "IncludeEmptyTag",
}

o := &Options{
IncludeEmptyTag: true,
Groups: []string{"test"},
}

actualMap, err := Marshal(o, testModel)
assert.NoError(t, err)

actual, err := json.Marshal(actualMap)
assert.NoError(t, err)

expected, err := json.Marshal(map[string]interface{}{
"default_marshal": "DefaultMarshal",
"only_group_test": "OnlyGroupTest",
"group_test_and_other": "GroupTestAndOther",
"omit_empty": "OmitEmpty",
"slice_string": []string{"test", "bla"},
"include_empty_tag": "IncludeEmptyTag",
})
assert.NoError(t, err)

Expand Down

0 comments on commit 0e83d19

Please sign in to comment.