Skip to content

Commit

Permalink
Merge pull request #277 from radeksimko/ignore-untagged-fields
Browse files Browse the repository at this point in the history
DecoderConfig: Introduce `IgnoreUntaggedFields`
  • Loading branch information
mitchellh committed Apr 20, 2022
2 parents a6c3570 + b37a0d6 commit 7c5722f
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
8 changes: 8 additions & 0 deletions mapstructure.go
Expand Up @@ -259,6 +259,10 @@ type DecoderConfig struct {
// defaults to "mapstructure"
TagName string

// IgnoreUntaggedFields ignores all struct fields without explicit
// TagName, comparable to `mapstructure:"-"` as default behaviour.
IgnoreUntaggedFields bool

// MatchName is the function used to match the map key to the struct
// field name or tag. Defaults to `strings.EqualFold`. This can be used
// to implement case-sensitive tag values, support snake casing, etc.
Expand Down Expand Up @@ -906,6 +910,10 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re
tagValue := f.Tag.Get(d.config.TagName)
keyName := f.Name

if tagValue == "" && d.config.IgnoreUntaggedFields {
continue
}

// If Squash is set in the config, we squash the field down.
squash := d.config.Squash && v.Kind() == reflect.Struct && f.Anonymous

Expand Down
40 changes: 40 additions & 0 deletions mapstructure_test.go
Expand Up @@ -2580,6 +2580,46 @@ func TestDecoder_MatchName(t *testing.T) {
}
}

func TestDecoder_IgnoreUntaggedFields(t *testing.T) {
type Input struct {
UntaggedNumber int
TaggedNumber int `mapstructure:"tagged_number"`
UntaggedString string
TaggedString string `mapstructure:"tagged_string"`
}
input := &Input{
UntaggedNumber: 31,
TaggedNumber: 42,
UntaggedString: "hidden",
TaggedString: "visible",
}

actual := make(map[string]interface{})
config := &DecoderConfig{
Result: &actual,
IgnoreUntaggedFields: true,
}

decoder, err := NewDecoder(config)
if err != nil {
t.Fatalf("err: %s", err)
}

err = decoder.Decode(input)
if err != nil {
t.Fatalf("err: %s", err)
}

expected := map[string]interface{}{
"tagged_number": 42,
"tagged_string": "visible",
}

if !reflect.DeepEqual(expected, actual) {
t.Fatalf("Decode() expected: %#v\ngot: %#v", expected, actual)
}
}

func testSliceInput(t *testing.T, input map[string]interface{}, expected *Slice) {
var result Slice
err := Decode(input, &result)
Expand Down

0 comments on commit 7c5722f

Please sign in to comment.