From c20aa09fb31e09819e8e5eca222b3de2049cbdf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Sun, 9 Jan 2022 22:46:39 +0100 Subject: Replace homegrown map-to-structure code by using package mapstructure. --- pkg/config/yaml.go | 56 ++++++++++++++++++------------------------------- pkg/config/yaml_test.go | 10 ++++----- 2 files changed, 25 insertions(+), 41 deletions(-) (limited to 'pkg') diff --git a/pkg/config/yaml.go b/pkg/config/yaml.go index a80c80d..3050825 100644 --- a/pkg/config/yaml.go +++ b/pkg/config/yaml.go @@ -4,9 +4,9 @@ import ( "errors" "fmt" "io" - "reflect" "strings" + "github.com/mitchellh/mapstructure" "gopkg.in/yaml.v3" "github.com/Necoro/feed2imap-go/pkg/log" @@ -139,50 +139,34 @@ func appTarget(target []string, app string) []string { } } -func buildOptions(globalFeedOptions *Options, options Map) (feedOptions Options, unknownFields []string) { +func buildOptions(globalFeedOptions *Options, options Map) (Options, []string) { + // copy global as default + feedOptions := *globalFeedOptions + if options == nil { // no options set for the feed: copy global options and be done - return *globalFeedOptions, unknownFields + return feedOptions, []string{} } - fv := reflect.ValueOf(&feedOptions).Elem() - gv := reflect.ValueOf(globalFeedOptions).Elem() - - n := gv.NumField() - for i := 0; i < n; i++ { - field := fv.Field(i) - f := fv.Type().Field(i) - - if f.PkgPath != "" && !f.Anonymous { - continue - } - - tag := f.Tag.Get("yaml") - if tag == "" { - continue - } - - name := strings.Split(tag, ",")[0] + var md mapstructure.Metadata + mapstructureConfig := mapstructure.DecoderConfig{ + TagName: "yaml", + Metadata: &md, + Result: &feedOptions, + } - set, ok := options[name] - if ok { // in the map -> copy and delete - value := reflect.ValueOf(set) - if !value.Type().AssignableTo(field.Type()) { - value = value.Convert(field.Type()) - } - field.Set(value) - delete(options, name) - } else { // not in the map -> copy from global - field.Set(gv.Field(i)) - } + var err error + dec, err := mapstructure.NewDecoder(&mapstructureConfig) + if err != nil { + panic(err) } - // remaining fields are unknown - for k := range options { - unknownFields = append(unknownFields, k) + err = dec.Decode(options) + if err != nil { + panic(err) } - return feedOptions, unknownFields + return feedOptions, md.Unused } // Fetch the group structure and populate the `targetStr` fields in the feeds diff --git a/pkg/config/yaml_test.go b/pkg/config/yaml_test.go index b02c4c4..b422c38 100644 --- a/pkg/config/yaml_test.go +++ b/pkg/config/yaml_test.go @@ -30,12 +30,12 @@ func TestBuildOptions(tst *testing.T) { out Options unknowns []string }{ - {"Empty", nil, Options{}, Options{}, nil}, - {"Simple copy", nil, Options{MinFreq: 75}, Options{MinFreq: 75}, nil}, + {"Empty", nil, Options{}, Options{}, []string{}}, + {"Simple copy", nil, Options{MinFreq: 75}, Options{MinFreq: 75}, []string{}}, {"Unknowns", Map{"foo": 1}, Options{}, Options{}, []string{"foo"}}, - {"Override", Map{"include-images": true}, Options{InclImages: false}, Options{InclImages: true}, nil}, - {"Non-Standard Type", Map{"body": "both"}, Options{}, Options{Body: "both"}, nil}, - {"Mixed", Map{"min-frequency": 24}, Options{MinFreq: 6, InclImages: true}, Options{MinFreq: 24, InclImages: true}, nil}, + {"Override", Map{"include-images": true}, Options{InclImages: false}, Options{InclImages: true}, []string{}}, + {"Non-Standard Type", Map{"body": "both"}, Options{}, Options{Body: "both"}, []string{}}, + {"Mixed", Map{"min-frequency": 24}, Options{MinFreq: 6, InclImages: true}, Options{MinFreq: 24, InclImages: true}, []string{}}, {"All", Map{"max-frequency": 12, "include-images": true, "ignore-hash": true, "obsolete": 54}, Options{MinFreq: 6, InclImages: true, IgnHash: false}, -- cgit v1.2.3