chore: optimize pr 4979 (#4988)

Signed-off-by: kevin <wanjunfeng@gmail.com>
This commit is contained in:
Kevin Wan
2025-07-09 23:55:24 +08:00
committed by GitHub
parent bca7bbc142
commit 95d5b81f44
2 changed files with 30 additions and 15 deletions

View File

@@ -30,7 +30,9 @@ var (
errValueNotSettable = errors.New("value is not settable") errValueNotSettable = errors.New("value is not settable")
errValueNotStruct = errors.New("value type is not struct") errValueNotStruct = errors.New("value type is not struct")
keyUnmarshaler = NewUnmarshaler(defaultKeyName) keyUnmarshaler = NewUnmarshaler(defaultKeyName)
boolType = reflect.TypeOf(false)
durationType = reflect.TypeOf(time.Duration(0)) durationType = reflect.TypeOf(time.Duration(0))
stringType = reflect.TypeOf("")
cacheKeys = make(map[string][]string) cacheKeys = make(map[string][]string)
cacheKeysLock sync.Mutex cacheKeysLock sync.Mutex
defaultCache = make(map[string]any) defaultCache = make(map[string]any)
@@ -765,24 +767,24 @@ func (u *Unmarshaler) processFieldWithEnvValue(fieldType reflect.Type, value ref
return err return err
} }
fieldKind := fieldType.Kind() derefType := Deref(fieldType)
switch true { switch derefType {
case fieldKind == reflect.Bool: case boolType:
val, err := strconv.ParseBool(envVal) val, err := strconv.ParseBool(envVal)
if err != nil { if err != nil {
return fmt.Errorf("unmarshal field %q with environment variable, %w", fullName, err) return fmt.Errorf("unmarshal field %q with environment variable, %w", fullName, err)
} }
value.SetBool(val) SetValue(fieldType, value, reflect.ValueOf(val))
return nil return nil
case fieldType == durationType: case durationType:
if err := fillDurationValue(fieldType, value, envVal); err != nil { if err := fillDurationValue(fieldType, value, envVal); err != nil {
return fmt.Errorf("unmarshal field %q with environment variable, %w", fullName, err) return fmt.Errorf("unmarshal field %q with environment variable, %w", fullName, err)
} }
return nil return nil
case fieldKind == reflect.String: case stringType:
value.SetString(envVal) SetValue(fieldType, value, reflect.ValueOf(envVal))
return nil return nil
default: default:
return u.processFieldPrimitiveWithJSONNumber(fieldType, value, json.Number(envVal), opts, fullName) return u.processFieldPrimitiveWithJSONNumber(fieldType, value, json.Number(envVal), opts, fullName)

View File

@@ -4801,20 +4801,33 @@ func TestUnmarshal_EnvBoolBad(t *testing.T) {
} }
func TestUnmarshal_EnvDuration(t *testing.T) { func TestUnmarshal_EnvDuration(t *testing.T) {
type Value struct {
Duration time.Duration `key:"duration,env=TEST_NAME_DURATION"`
}
const ( const (
envName = "TEST_NAME_DURATION" envName = "TEST_NAME_DURATION"
envVal = "1s" envVal = "1s"
) )
t.Setenv(envName, envVal) t.Setenv(envName, envVal)
t.Run("valid duration", func(t *testing.T) {
type Value struct {
Duration time.Duration `key:"duration,env=TEST_NAME_DURATION"`
}
var v Value var v Value
if assert.NoError(t, UnmarshalKey(emptyMap, &v)) { if assert.NoError(t, UnmarshalKey(emptyMap, &v)) {
assert.Equal(t, time.Second, v.Duration) assert.Equal(t, time.Second, v.Duration)
} }
})
t.Run("ptr of duration", func(t *testing.T) {
type Value struct {
Duration *time.Duration `key:"duration,env=TEST_NAME_DURATION"`
}
var v Value
if assert.NoError(t, UnmarshalKey(emptyMap, &v)) {
assert.Equal(t, time.Second, *v.Duration)
}
})
} }
func TestUnmarshal_EnvDurationBadValue(t *testing.T) { func TestUnmarshal_EnvDurationBadValue(t *testing.T) {