Skip to content

Commit 8c61ec1

Browse files
Merge pull request #80 from rostislaved/feature-allow-unset-pointer
Feature allow unset pointer
2 parents df765f4 + 9ea3f2a commit 8c61ec1

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

mapstructure.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,12 @@ type DecoderConfig struct {
243243
// will affect all nested structs as well.
244244
ErrorUnset bool
245245

246+
// AllowUnsetPointer, if set to true, will prevent fields with pointer types
247+
// from being reported as unset, even if ErrorUnset is true and the field was
248+
// not present in the input data. This allows pointer fields to be optional
249+
// without triggering an error when they are missing.
250+
AllowUnsetPointer bool
251+
246252
// ZeroFields, if set to true, will zero fields before writing them.
247253
// For example, a map will be emptied before decoded values are put in
248254
// it. If this is false, a map will be merged.
@@ -1541,7 +1547,9 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
15411547
if !rawMapVal.IsValid() {
15421548
// There was no matching key in the map for the value in
15431549
// the struct. Remember it for potential errors and metadata.
1544-
targetValKeysUnused[fieldName] = struct{}{}
1550+
if !(d.config.AllowUnsetPointer && fieldValue.Kind() == reflect.Ptr) {
1551+
targetValKeysUnused[fieldName] = struct{}{}
1552+
}
15451553
continue
15461554
}
15471555
}

mapstructure_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,6 +1690,32 @@ func TestDecoder_ErrorUnset(t *testing.T) {
16901690
}
16911691
}
16921692

1693+
func TestDecoder_ErrorUnset_AllowUnsetPointer(t *testing.T) {
1694+
t.Parallel()
1695+
1696+
input := map[string]interface{}{
1697+
"vstring": "hello",
1698+
"foo": "bar",
1699+
}
1700+
1701+
var result BasicPointer
1702+
config := &DecoderConfig{
1703+
ErrorUnset: true,
1704+
AllowUnsetPointer: true,
1705+
Result: &result,
1706+
}
1707+
1708+
decoder, err := NewDecoder(config)
1709+
if err != nil {
1710+
t.Fatalf("err: %s", err)
1711+
}
1712+
1713+
err = decoder.Decode(input)
1714+
if err != nil {
1715+
t.Fatal("error not expected")
1716+
}
1717+
}
1718+
16931719
func TestMap(t *testing.T) {
16941720
t.Parallel()
16951721

0 commit comments

Comments
 (0)