fix: unmarshal problem on env vars for type env string (#5037)

Signed-off-by: kevin <wanjunfeng@gmail.com>
Signed-off-by: Kevin Wan <wanjunfeng@gmail.com>
This commit is contained in:
Kevin Wan
2025-07-30 18:09:25 +08:00
committed by GitHub
parent 25f37ca750
commit d505fae979
3 changed files with 112 additions and 9 deletions

View File

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