diff --git a/rfx.go b/rfx.go index 05bc931..f9d370c 100644 --- a/rfx.go +++ b/rfx.go @@ -7,6 +7,7 @@ import ( "strconv" "strings" + "git.fsdpf.net/go/reflux/valuex" "github.com/spf13/cast" ) @@ -511,11 +512,20 @@ func (r *rfx) Keys() []string { return nil } -// Value 返回底层的 reflect.Value -func (r *rfx) Value() reflect.Value { +// Raw 返回底层的 reflect.Value +func (r *rfx) Raw() reflect.Value { return r.value } +// Lookup 根据路径查找并返回对应值的访问器 +func (r *rfx) Lookup(path string) (valuex.Accessor, bool) { + v := r.Get(path) + if v.Exists() { + return v, true + } + return valuex.Nil, false +} + // Ptr 返回指向当前值的指针 func (r *rfx) Ptr() any { v := r.value @@ -676,55 +686,151 @@ func (r *rfx) String() string { // StringMapString 将当前值转换为 map[string]string 类型 func (r *rfx) StringMapString() map[string]string { - result, err := cast.ToStringMapStringE(r.Any()) - if err != nil { - panic(fmt.Sprintf("rfx: failed to convert to map[string]string: %v", err)) + data := r.Any() + + // 首先尝试使用 cast 进行转换 + result, err := cast.ToStringMapStringE(data) + if err == nil { + return result } + + // cast 失败后,尝试自定义转换逻辑 + defer func() { + if p := recover(); p != nil { + panic(fmt.Sprintf("rfx: failed to convert to map[string]string, cast error: %v, custom conversion error: %v", err, p)) + } + }() + + result = make(map[string]string) + for _, k := range r.Keys() { + result[k] = r.Get(k).String() + } + return result } // StringMapStringSlice 将当前值转换为 map[string][]string 类型 func (r *rfx) StringMapStringSlice() map[string][]string { - result, err := cast.ToStringMapStringSliceE(r.Any()) - if err != nil { - panic(fmt.Sprintf("rfx: failed to convert to map[string][]string: %v", err)) + data := r.Any() + + // 首先尝试使用 cast 进行转换 + result, err := cast.ToStringMapStringSliceE(data) + if err == nil { + return result } + + // cast 失败后,尝试自定义转换逻辑 + defer func() { + if p := recover(); p != nil { + panic(fmt.Sprintf("rfx: failed to convert to map[string][]string, cast error: %v, custom conversion error: %v", err, p)) + } + }() + + result = make(map[string][]string) + for _, k := range r.Keys() { + result[k] = r.Get(k).StringSlice() + } + return result } // StringMapBool 将当前值转换为 map[string]bool 类型 func (r *rfx) StringMapBool() map[string]bool { - result, err := cast.ToStringMapBoolE(r.Any()) - if err != nil { - panic(fmt.Sprintf("rfx: failed to convert to map[string]bool: %v", err)) + data := r.Any() + + // 首先尝试使用 cast 进行转换 + result, err := cast.ToStringMapBoolE(data) + if err == nil { + return result } + + // cast 失败后,尝试自定义转换逻辑 + defer func() { + if p := recover(); p != nil { + panic(fmt.Sprintf("rfx: failed to convert to map[string]bool, cast error: %v, custom conversion error: %v", err, p)) + } + }() + + result = make(map[string]bool) + for _, k := range r.Keys() { + result[k] = r.Get(k).Bool() + } + return result } // StringMapInt 将当前值转换为 map[string]int 类型 func (r *rfx) StringMapInt() map[string]int { - result, err := cast.ToStringMapIntE(r.Any()) - if err != nil { - panic(fmt.Sprintf("rfx: failed to convert to map[string]int: %v", err)) + data := r.Any() + + // 首先尝试使用 cast 进行转换 + result, err := cast.ToStringMapIntE(data) + if err == nil { + return result } + + // cast 失败后,尝试自定义转换逻辑 + defer func() { + if p := recover(); p != nil { + panic(fmt.Sprintf("rfx: failed to convert to map[string]int, cast error: %v, custom conversion error: %v", err, p)) + } + }() + + result = make(map[string]int) + for _, k := range r.Keys() { + result[k] = r.Get(k).Int() + } + return result } // StringMapInt64 将当前值转换为 map[string]int64 类型 func (r *rfx) StringMapInt64() map[string]int64 { - result, err := cast.ToStringMapInt64E(r.Any()) - if err != nil { - panic(fmt.Sprintf("rfx: failed to convert to map[string]int64: %v", err)) + data := r.Any() + + // 首先尝试使用 cast 进行转换 + result, err := cast.ToStringMapInt64E(data) + if err == nil { + return result } + + // cast 失败后,尝试自定义转换逻辑 + defer func() { + if p := recover(); p != nil { + panic(fmt.Sprintf("rfx: failed to convert to map[string]int64, cast error: %v, custom conversion error: %v", err, p)) + } + }() + + result = make(map[string]int64) + for _, k := range r.Keys() { + result[k] = r.Get(k).Int64() + } + return result } // StringMap 将当前值转换为 map[string]any 类型 func (r *rfx) StringMap() map[string]any { - result, err := cast.ToStringMapE(r.Any()) - if err != nil { - panic(fmt.Sprintf("rfx: failed to convert to map[string]any: %v", err)) + data := r.Any() + + // 首先尝试使用 cast 进行转换 + result, err := cast.ToStringMapE(data) + if err == nil { + return result } + + // cast 失败后,尝试自定义转换逻辑 + defer func() { + if p := recover(); p != nil { + panic(fmt.Sprintf("rfx: failed to convert to map[string]any, cast error: %v, custom conversion error: %v", err, p)) + } + }() + + result = make(map[string]any) + for _, k := range r.Keys() { + result[k] = r.Get(k).Any() + } + return result } @@ -759,7 +865,7 @@ func (r *rfx) Slice() []any { // BoolSlice 将当前值转换为 []bool 切片 func (r *rfx) BoolSlice() []bool { - result, err := cast.ToBoolSliceE(r.Any()) + result, err := cast.ToBoolSliceE(r.Slice()) if err != nil { panic(fmt.Sprintf("rfx: failed to convert to []bool: %v", err)) } @@ -768,7 +874,7 @@ func (r *rfx) BoolSlice() []bool { // StringSlice 将当前值转换为 []string 切片 func (r *rfx) StringSlice() []string { - result, err := cast.ToStringSliceE(r.Any()) + result, err := cast.ToStringSliceE(r.Slice()) if err != nil { panic(fmt.Sprintf("rfx: failed to convert to []string: %v", err)) } @@ -777,7 +883,7 @@ func (r *rfx) StringSlice() []string { // IntSlice 将当前值转换为 []int 切片 func (r *rfx) IntSlice() []int { - result, err := cast.ToIntSliceE(r.Any()) + result, err := cast.ToIntSliceE(r.Slice()) if err != nil { panic(fmt.Sprintf("rfx: failed to convert to []int: %v", err)) }