From 3324c3d305c1c1dc38dc72e0bb02af99003c6c06 Mon Sep 17 00:00:00 2001 From: Vadim Alekseev Date: Thu, 10 Aug 2023 17:44:58 +0300 Subject: [PATCH] "options" tag now can set target value in the config (#452) * Parameter tag can now set target value --- cfg/config.go | 16 +++++++++++++++- cfg/config_test.go | 20 +++++++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/cfg/config.go b/cfg/config.go index 486770d47..2b3e4ce20 100644 --- a/cfg/config.go +++ b/cfg/config.go @@ -362,10 +362,12 @@ func ParseField(v reflect.Value, vField reflect.Value, tField *reflect.StructFie return fmt.Errorf("options deals with strings only, but field %s has %s type", tField.Name, tField.Type.Name()) } + idx := -1 found := false - for _, part := range parts { + for i, part := range parts { if vField.String() == part { found = true + idx = i break } } @@ -373,6 +375,18 @@ func ParseField(v reflect.Value, vField reflect.Value, tField *reflect.StructFie if !found { return fmt.Errorf("field %s should be one of %s, got=%s", tField.Name, tag, vField.String()) } + + finalField := v.FieldByName(tField.Name + "_") + if finalField != (reflect.Value{}) { + switch finalField.Kind() { + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + finalField.SetInt(int64(idx)) + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + finalField.SetUint(uint64(idx)) + default: + return fmt.Errorf("final field must be an integer") + } + } } tag = tField.Tag.Get("parse") diff --git a/cfg/config_test.go b/cfg/config_test.go index 91cb52a65..ae6a3cacf 100644 --- a/cfg/config_test.go +++ b/cfg/config_test.go @@ -35,8 +35,16 @@ type strDefault struct { T string `default:"sync"` } +type PersistenceMode byte + +const ( + PersistenceModeAsync PersistenceMode = iota + PersistenceModeSync +) + type strOptions struct { - T string `default:"async" options:"async|sync"` + T string `default:"async" options:"async|sync"` + T_ PersistenceMode } type strExpression struct { @@ -122,10 +130,15 @@ func TestParseDuration(t *testing.T) { } func TestParseOptionsOk(t *testing.T) { + a := assert.New(t) + s := &strOptions{T: "async"} - err := Parse(s, nil) + a.NoError(Parse(s, nil)) + a.Equal(s.T_, PersistenceModeAsync) - assert.NoError(t, err, "shouldn't be an error") + s.T = "sync" + a.NoError(Parse(s, nil)) + a.Equal(s.T_, PersistenceModeSync) } func TestParseOptionsErr(t *testing.T) { @@ -133,6 +146,7 @@ func TestParseOptionsErr(t *testing.T) { err := Parse(s, nil) assert.NotNil(t, err, "should be an error") + assert.Equal(t, PersistenceMode(0), s.T_) } func TestParseExpressionMul(t *testing.T) {