From ef1c8b38f86fd55edf0a743431f6bcd2a65743ef Mon Sep 17 00:00:00 2001 From: Sinkerine Date: Mon, 11 Nov 2019 01:45:20 -0800 Subject: [PATCH 1/2] Add support for field name remapping hook --- mapstructure.go | 17 ++++++++++++++++- mapstructure_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/mapstructure.go b/mapstructure.go index 256ee63f..95cea80a 100644 --- a/mapstructure.go +++ b/mapstructure.go @@ -91,6 +91,12 @@ type DecoderConfig struct { // The tag name that mapstructure reads for field names. This // defaults to "mapstructure" TagName string + + // Extra transformation methods to match field name from map to struct. + // Options: + // - snake (snake_case: all characters in lower case and concatenating words by '_') + // - kebab (kebab-case: all characters in lower case and concatenating words by '-' ) + FieldNameTransFormMethod string } // A Decoder takes a raw interface value and turns it into structured @@ -1064,7 +1070,16 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e continue } - if strings.EqualFold(mK, fieldName) { + matched := strings.EqualFold(mK, fieldName) + + switch d.config.FieldNameTransFormMethod { + case "snake": + matched = matched || strings.EqualFold(strings.ReplaceAll(mK, "_", ""), fieldName) + case "kabab": + matched = matched || strings.EqualFold(strings.ReplaceAll(mK, "-", ""), fieldName) + } + + if matched { rawMapKey = dataValKey rawMapVal = dataVal.MapIndex(dataValKey) break diff --git a/mapstructure_test.go b/mapstructure_test.go index 27ac10eb..272fea13 100644 --- a/mapstructure_test.go +++ b/mapstructure_test.go @@ -906,6 +906,34 @@ func TestDecoder_ErrorUnused(t *testing.T) { } } +func TestDecode_FieldNameTransForm(t *testing.T) { + t.Parallel() + + input := map[string]interface{}{ + "v_string": "WHAT", + } + + var result Basic + config := &DecoderConfig{ + Result: &result, + FieldNameTransFormMethod: "snake", + } + + decoder, err := NewDecoder(config) + if err != nil { + t.Fatalf("err: %s", err) + } + + err = decoder.Decode(input) + if err != nil { + t.Fatalf("got an err: %s", err) + } + + if result.Vstring != "WHAT" { + t.Errorf("vstring should be WHAT: %#v", result.Vstring) + } +} + func TestMap(t *testing.T) { t.Parallel() From 8142b805abc14c4dcc94ca0652b6f36876f8c844 Mon Sep 17 00:00:00 2001 From: Sinkerine Date: Mon, 6 Apr 2020 22:25:59 -0700 Subject: [PATCH 2/2] Fix typo in field name transform config. --- mapstructure.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapstructure.go b/mapstructure.go index 95cea80a..9ab11aeb 100644 --- a/mapstructure.go +++ b/mapstructure.go @@ -1075,7 +1075,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e switch d.config.FieldNameTransFormMethod { case "snake": matched = matched || strings.EqualFold(strings.ReplaceAll(mK, "_", ""), fieldName) - case "kabab": + case "kebab": matched = matched || strings.EqualFold(strings.ReplaceAll(mK, "-", ""), fieldName) }