From 182c5056a5f55cff990ef6e98090f963febcdb90 Mon Sep 17 00:00:00 2001 From: hz Date: Sat, 10 Feb 2024 10:08:58 +0800 Subject: [PATCH] update main codes to v1 --- 00_testcase_for_test.go | 27 +- 01_test.go | 38 +- 03_test.go | 18 +- ctrl.go | 39 +- ctrl_test.go | 11 +- cvts.go | 2350 ++++++++++++++++++++++++++++++++++++--- cvts_tool.go | 263 ++++- cvts_tool_go113_test.go | 12 +- cvts_tool_test.go | 96 +- deepcopy.go | 4 +- deepdiff.go | 6 +- deepequal.go | 4 +- ftor.go | 285 ++--- ftor_test.go | 22 +- params.go | 27 +- structiterator.go | 75 +- structiterator_test.go | 98 +- tag_test.go | 24 +- withopts.go | 55 +- 19 files changed, 2887 insertions(+), 567 deletions(-) diff --git a/00_testcase_for_test.go b/00_testcase_for_test.go index 87695b6..add4f91 100644 --- a/00_testcase_for_test.go +++ b/00_testcase_for_test.go @@ -5,13 +5,12 @@ import ( "reflect" "testing" - "github.com/hedzr/log" - "github.com/hedzr/evendeep/dbglog" "github.com/hedzr/evendeep/diff" "github.com/hedzr/evendeep/flags/cms" - "github.com/hedzr/evendeep/internal/tool" + "github.com/hedzr/evendeep/ref" "github.com/hedzr/evendeep/typ" + logz "github.com/hedzr/logg/slog" "gopkg.in/hedzr/errors.v3" ) @@ -72,17 +71,17 @@ func NewForTest() DeepCopier { var c1 = newCopier() WithStrategies(cms.SliceMerge, cms.MapMerge)(c1) if c1.flags.IsAnyFlagsOK(cms.ByOrdinal, cms.SliceMerge, cms.MapMerge, cms.OmitIfEmpty, cms.Default) == false { - log.Panicf("except flag set with optional values but not matched, 1") + logz.Panic("except flag set with optional values but not matched, 1") } c1 = newDeepCopier() WithStrategies(cms.SliceCopyAppend, cms.MapCopy)(c1) if c1.flags.IsAnyFlagsOK(cms.ByOrdinal, cms.SliceCopyAppend, cms.MapCopy, cms.OmitIfEmpty, cms.Default) == false { - log.Panicf("except flag set with optional values but not matched, 2") + logz.Panic("except flag set with optional values but not matched, 2") } c1 = newCloner() WithStrategies(cms.SliceCopy)(c1) if c1.flags.IsAnyFlagsOK(cms.ByOrdinal, cms.SliceCopy, cms.MapCopy, cms.OmitIfEmpty, cms.Default) == false { - log.Panicf("except flag set with optional values but not matched, 3") + logz.Panic("except flag set with optional values but not matched, 3") } copier = NewFlatDeepCopier( @@ -188,12 +187,12 @@ func DefaultDeepCopyTestRunner(ix int, tc TestCase, opts ...Opt) func(t *testing // t.Logf("\nexpect: %+v\n got: %+v.", tc.expect, tc.dst) if err = verifier(tc.Src, tc.Dst, tc.Expect, err); err == nil { - log.Printf("%3d. test passed", ix) + logz.Print("test passed", "pass-index", ix) return } - log.Errorf("%3d. Error: %v", ix, err) - t.Fatalf("%3d. %s FAILED, %+v", ix, tc.Description, err) + logz.Error("Error occurs", "index", ix, "error", err) + t.Fatal("FAILED", "index", ix, "desc", tc.Description, "error", err) } } @@ -219,11 +218,13 @@ func runTestCasesWithOpts(t *testing.T, cases []TestCase, opts ...Opt) { func DoTestCasesVerifier(t *testing.T) Verifier { return func(src, dst, expect typ.Any, e error) (err error) { a, b := reflect.ValueOf(dst), reflect.ValueOf(expect) - aa, _ := tool.Rdecode(a) - bb, _ := tool.Rdecode(b) + aa, _ := ref.Rdecode(a) + bb, _ := ref.Rdecode(b) av, bv := aa.Interface(), bb.Interface() - log.Printf("\nexpect: %+v (%v | %v)\n got: %+v (%v | %v)\n err: %v", - bv, tool.Typfmtv(&bb), aa.Type(), av, tool.Typfmtv(&aa), bb.Type(), e) + logz.Print("mismatched", + logz.Group("expect", "bv", bv, "typ", ref.Typfmtv(&bb), "t", aa.Type()), + logz.Group("got", "av", av, "typ", ref.Typfmtv(&aa), "t", bb.Type()), + "error", e) dif, equal := diff.New(expect, dst, diff.WithSliceOrderedComparison(false), diff --git a/01_test.go b/01_test.go index de88345..7a9d6ec 100644 --- a/01_test.go +++ b/01_test.go @@ -10,24 +10,24 @@ import ( "time" "unsafe" - "github.com/hedzr/log" - "gopkg.in/hedzr/errors.v3" - "github.com/hedzr/evendeep/dbglog" "github.com/hedzr/evendeep/internal/cl" - "github.com/hedzr/evendeep/internal/tool" + "github.com/hedzr/evendeep/ref" + logz "github.com/hedzr/logg/slog" + + "gopkg.in/hedzr/errors.v3" ) // TestLogNormal _ func TestLogNormal(t *testing.T) { - // config := log.NewLoggerConfigWith(true, "logrus", "trace") + // config := logz.NewLoggerConfigWith(true, "logrus", "trace") // logger := logrus.NewWithConfig(config) - log.Printf("hello") - log.Infof("hello info") - log.Warnf("hello warn") - log.Errorf("hello error") - log.Debugf("hello debug") - log.Tracef("hello trace") + logz.Print("hello") + logz.Info("hello info") + logz.Warn("hello warn") + logz.Error("hello error") + logz.Debug("hello debug") + logz.Trace("hello trace") dbglog.Log("but again") } @@ -75,7 +75,7 @@ func TestSliceLen(t *testing.T) { v = reflect.Append(v, reflect.ValueOf("ghi"), reflect.ValueOf("jkl")) fmt.Println("Our value is a type of :", v.Kind()) - fmt.Printf("len : %v, %v\n", v.Len(), tool.Typfmtv(&v)) + fmt.Printf("len : %v, %v\n", v.Len(), ref.Typfmtv(&v)) vSlice := v.Slice(0, v.Len()) vSliceElems := vSlice.Interface() @@ -140,25 +140,25 @@ func TestValueValid(t *testing.T) { var v reflect.Value - t.Logf("ival: %v (%v), isvalid/isnil/iszero: %v/%v/%v", tool.Valfmt(&v), tool.Typfmtv(&v), v.IsValid(), tool.IsNil(v), tool.IsZero(v)) + t.Logf("ival: %v (%v), isvalid/isnil/iszero: %v/%v/%v", ref.Valfmt(&v), ref.Typfmtv(&v), v.IsValid(), ref.IsNil(v), ref.IsZero(v)) v = reflect.ValueOf(ival) - t.Logf("ival: %v (%v), isvalid/isnil/iszero: %v/%v/%v", tool.Valfmt(&v), tool.Typfmtv(&v), v.IsValid(), tool.IsNil(v), tool.IsZero(v)) + t.Logf("ival: %v (%v), isvalid/isnil/iszero: %v/%v/%v", ref.Valfmt(&v), ref.Typfmtv(&v), v.IsValid(), ref.IsNil(v), ref.IsZero(v)) v = reflect.ValueOf(pival) - t.Logf("ival: %v (%v), isvalid/isnil/iszero: %v/%v/%v", tool.Valfmt(&v), tool.Typfmtv(&v), v.IsValid(), tool.IsNil(v), tool.IsZero(v)) + t.Logf("ival: %v (%v), isvalid/isnil/iszero: %v/%v/%v", ref.Valfmt(&v), ref.Typfmtv(&v), v.IsValid(), ref.IsNil(v), ref.IsZero(v)) v = reflect.ValueOf(aval) - t.Logf("ival: %v (%v), isvalid/isnil/iszero: %v/%v/%v", tool.Valfmt(&v), tool.Typfmtv(&v), v.IsValid(), tool.IsNil(v), tool.IsZero(v)) + t.Logf("ival: %v (%v), isvalid/isnil/iszero: %v/%v/%v", ref.Valfmt(&v), ref.Typfmtv(&v), v.IsValid(), ref.IsNil(v), ref.IsZero(v)) v = reflect.ValueOf(paval) - t.Logf("ival: %v (%v), isvalid/isnil/iszero: %v/%v/%v", tool.Valfmt(&v), tool.Typfmtv(&v), v.IsValid(), tool.IsNil(v), tool.IsZero(v)) + t.Logf("ival: %v (%v), isvalid/isnil/iszero: %v/%v/%v", ref.Valfmt(&v), ref.Typfmtv(&v), v.IsValid(), ref.IsNil(v), ref.IsZero(v)) var b bool v = reflect.ValueOf(b) - t.Logf("ival: %v (%v), isvalid/isnil/iszero: %v/%v/%v", tool.Valfmt(&v), tool.Typfmtv(&v), v.IsValid(), tool.IsNil(v), tool.IsZero(v)) + t.Logf("ival: %v (%v), isvalid/isnil/iszero: %v/%v/%v", ref.Valfmt(&v), ref.Typfmtv(&v), v.IsValid(), ref.IsNil(v), ref.IsZero(v)) b = true v = reflect.ValueOf(b) - t.Logf("ival: %v (%v), isvalid/isnil/iszero: %v/%v/%v", tool.Valfmt(&v), tool.Typfmtv(&v), v.IsValid(), tool.IsNil(v), tool.IsZero(v)) + t.Logf("ival: %v (%v), isvalid/isnil/iszero: %v/%v/%v", ref.Valfmt(&v), ref.Typfmtv(&v), v.IsValid(), ref.IsNil(v), ref.IsZero(v)) } diff --git a/03_test.go b/03_test.go index e6abe8c..c6658c6 100644 --- a/03_test.go +++ b/03_test.go @@ -5,11 +5,13 @@ import ( "reflect" "testing" - "gopkg.in/hedzr/errors.v3" + "github.com/hedzr/evendeep/ref" "github.com/hedzr/evendeep/flags" "github.com/hedzr/evendeep/flags/cms" "github.com/hedzr/evendeep/internal/tool" + + "gopkg.in/hedzr/errors.v3" ) func TestRegisterInitRoutines(t *testing.T) { @@ -72,7 +74,7 @@ func TestParamsBasics(t *testing.T) { a, expects := prepareAFT() v := reflect.ValueOf(&a) - v = tool.Rindirect(v) + v = ref.Rindirect(v) for i := 0; i < v.NumField(); i++ { fld := v.Type().Field(i) @@ -104,7 +106,7 @@ func TestParamsBasics3(t *testing.T) { } var a AFS1 v := reflect.ValueOf(&a) - v = tool.Rindirect(v) + v = ref.Rindirect(v) sf, _ := v.Type().FieldByName("wouldbe") // sf0, _ := v.Type().FieldByName("flags") // sf1, _ := v.Type().FieldByName("converter") @@ -210,7 +212,7 @@ func TestDeferCatchers(t *testing.T) { tgt1 := &BBB{X1: "no", X2: "longer", Y: "-1"} src, dst := reflect.ValueOf(&src1), reflect.ValueOf(&tgt1) - svv, dvv := tool.Rdecodesimple(src), tool.Rdecodesimple(dst) + svv, dvv := ref.Rdecodesimple(src), ref.Rdecodesimple(dst) sf1, df1 := svv.Field(1), dvv.Field(1) c := newCopier() @@ -241,7 +243,7 @@ func TestDeferCatchers(t *testing.T) { tgt1 := &BBB{X1: "no", X2: "longer", Y: "-1"} src, dst := reflect.ValueOf(&src1), reflect.ValueOf(&tgt1) - svv, dvv := tool.Rdecodesimple(src), tool.Rdecodesimple(dst) + svv, dvv := ref.Rdecodesimple(src), ref.Rdecodesimple(dst) // sf1, df1 := svv.Field(1), dvv.Field(1) c := newCopier() @@ -276,7 +278,7 @@ func TestDeferCatchers(t *testing.T) { tgt1 := &BBB{X1: "no", X2: "longer", Y: "-1"} src, dst := reflect.ValueOf(&src1), reflect.ValueOf(&tgt1) - svv, dvv := tool.Rdecodesimple(src), tool.Rdecodesimple(dst) + svv, dvv := ref.Rdecodesimple(src), ref.Rdecodesimple(dst) // sf1, df1 := svv.Field(1), dvv.Field(1) postCatcher(func() { _ = c.copyToInternal(nil, svv, dvv, func(c *cpController, params *Params, from, to reflect.Value) (err error) { @@ -295,7 +297,7 @@ func TestDeferCatchers(t *testing.T) { tgt1 := &BBB{X1: "no", X2: "longer", Y: "-1"} src, dst := reflect.ValueOf(&src1), reflect.ValueOf(&tgt1) - svv, dvv := tool.Rdecodesimple(src), tool.Rdecodesimple(dst) + svv, dvv := ref.Rdecodesimple(src), ref.Rdecodesimple(dst) // sf1, df1 := svv.Field(1), dvv.Field(1) t.Logf("src: %v, %v", src.IsValid(), svv.IsValid()) @@ -340,7 +342,7 @@ func TestDeferCatchers(t *testing.T) { tgt1 := &BBB{X1: "no", X2: "longer", Y: "-1"} src, dst := reflect.ValueOf(&src1), reflect.ValueOf(&tgt1) - svv, dvv := tool.Rindirect(src), tool.Rindirect(dst) + svv, dvv := ref.Rindirect(src), ref.Rindirect(dst) // sf1, df1 := svv.Field(1), dvv.Field(1) root := newParams(withOwners(c, nil, &svv, &dvv, &src, &dst)) diff --git a/ctrl.go b/ctrl.go index 3988123..ef56eee 100644 --- a/ctrl.go +++ b/ctrl.go @@ -1,18 +1,17 @@ package evendeep import ( - "github.com/hedzr/log" + "reflect" + "unsafe" "github.com/hedzr/evendeep/dbglog" "github.com/hedzr/evendeep/flags" "github.com/hedzr/evendeep/flags/cms" - "github.com/hedzr/evendeep/internal/tool" + "github.com/hedzr/evendeep/ref" "github.com/hedzr/evendeep/typ" + logz "github.com/hedzr/logg/slog" "gopkg.in/hedzr/errors.v3" - - "reflect" - "unsafe" ) type cpController struct { @@ -84,15 +83,15 @@ func (c *cpController) CopyTo(fromObjOrPtr, toObjPtr interface{}, opts ...Opt) ( var ( from0 = reflect.ValueOf(fromObjOrPtr) to0 = reflect.ValueOf(toObjPtr) - from = tool.Rindirect(from0) - to = tool.Rindirect(to0) + from = ref.Rindirect(from0) + to = ref.Rindirect(to0) root = newParams(withOwners(c, nil, &from0, &to0, &from, &to)) ) dbglog.Log(" flags: %v", c.flags) dbglog.Log("flags (verbose): %+v", c.flags) - dbglog.Log(" from.type: %v | input: %v", tool.Typfmtv(&from), tool.Typfmtv(&from0)) - dbglog.Log(" to.type: %v | input: %v", tool.Typfmtv(&to), tool.Typfmtv(&to0)) + dbglog.Log(" from.type: %v | input: %v", ref.Typfmtv(&from), ref.Typfmtv(&from0)) + dbglog.Log(" to.type: %v | input: %v", ref.Typfmtv(&to), ref.Typfmtv(&to0)) err = c.copyTo(root, from, to) return @@ -102,7 +101,7 @@ func (c *cpController) copyTo(params *Params, from, to reflect.Value) (err error err = c.copyToInternal(params, from, to, func(c *cpController, params *Params, from, to reflect.Value) (err error) { kind, pkgPath := from.Kind(), from.Type().PkgPath() - if c.sourceExtractor != nil && to.IsValid() && !tool.IsNil(to) { + if c.sourceExtractor != nil && to.IsValid() && !ref.IsNil(to) { // use tool.IsNil because we are checking for: // 1. to,IsNil() if 'to' is an addressable value (such as slice, map, or ptr) // 2. false if 'to' is not an addressable value (such as struct, int, ...) @@ -118,7 +117,7 @@ func (c *cpController) copyTo(params *Params, from, to reflect.Value) (err error } // source is primitive type, or in a reserved package such as time, os, ... - dbglog.Log(" - from.type: %v - fallback to copyDefaultHandler | to.type: %v", kind, tool.Typfmtv(&to)) + dbglog.Log(" - from.type: %v - fallback to copyDefaultHandler | to.type: %v", kind, ref.Typfmtv(&to)) err = copyDefaultHandler(c, params, from, to) return }) @@ -148,7 +147,7 @@ func (c *cpController) copyToInternal( //nolint:gocognit //yes, it is an integra } //nolint:lll,nestif //keep it - if from.CanAddr() && to.CanAddr() && tool.KindIs(from.Kind(), reflect.Array, reflect.Map, reflect.Slice, reflect.Struct) { + if from.CanAddr() && to.CanAddr() && ref.KindIs(from.Kind(), reflect.Array, reflect.Map, reflect.Slice, reflect.Struct) { addr1 := unsafe.Pointer(from.UnsafeAddr()) addr2 := unsafe.Pointer(to.UnsafeAddr()) if uintptr(addr1) > uintptr(addr2) { @@ -177,7 +176,7 @@ func (c *cpController) copyToInternal( //nolint:gocognit //yes, it is an integra defer func() { if e := recover(); e != nil { err = errors.New("[recovered] copyTo unsatisfied ([%v] -> [%v])", - tool.RindirectType(from.Type()), tool.RindirectType(to.Type())). + ref.RindirectType(from.Type()), ref.RindirectType(to.Type())). WithMaxObjectStringLength(maxObjectStringLen). WithData(e). WithTaggedData(errors.TaggedData{ @@ -185,12 +184,18 @@ func (c *cpController) copyToInternal( //nolint:gocognit //yes, it is an integra "target": to, }) - // skip go-lib frames and defer-recover frame, back to the point throwing panic - n := log.CalcStackFrames(1) // skip defer-recover frame at first + // // skip go-lib frames and defer-recover frame, back to the point throwing panic + // n := logz.CalcStackFrames(1) // skip defer-recover frame at first + // if c.rethrow { + // logz.Skip(n).Panicf("%+v", err) + // } else { + // logz.Skip(n).Errorf("%+v", err) + // } + if c.rethrow { - log.Skip(n).Panicf("%+v", err) + logz.Panic("[recovered] copyTo unsatisfied", "error", err) } else { - log.Skip(n).Errorf("%+v", err) + logz.Error("[recovered] copyTo unsatisfied", "error", err) } } }() diff --git a/ctrl_test.go b/ctrl_test.go index 9f526e5..bccc5d2 100644 --- a/ctrl_test.go +++ b/ctrl_test.go @@ -13,14 +13,15 @@ import ( "time" "unsafe" - "gopkg.in/hedzr/errors.v3" + "github.com/hedzr/evendeep/ref" "github.com/hedzr/evendeep" "github.com/hedzr/evendeep/dbglog" "github.com/hedzr/evendeep/diff" "github.com/hedzr/evendeep/flags/cms" - "github.com/hedzr/evendeep/internal/tool" "github.com/hedzr/evendeep/typ" + + "gopkg.in/hedzr/errors.v3" ) const ( @@ -981,10 +982,10 @@ func TestStructWithTargetSetter_map2struct(t *testing.T) { var f = s.FieldByName(fldName) if f.IsValid() { if value.Type().ConvertibleTo(f.Type()) { - dbglog.Log("struct.%q <- %v", fldName, tool.Valfmt(&value)) + dbglog.Log("struct.%q <- %v", fldName, ref.Valfmt(&value)) f.Set(value.Convert(f.Type())) } else { - dbglog.Log("struct.%q <- %v", fldName, tool.Valfmt(&value)) + dbglog.Log("struct.%q <- %v", fldName, ref.Valfmt(&value)) f.Set(value) } } @@ -994,7 +995,7 @@ func TestStructWithTargetSetter_map2struct(t *testing.T) { if value != nil { name := "Mo" + strings.Join(sourceNames, ".") setStructByName(reflect.ValueOf(tgt).Elem(), name, *value) - dbglog.Log("struct.%q <- %v", name, tool.Valfmt(value)) + dbglog.Log("struct.%q <- %v", name, ref.Valfmt(value)) } return // ErrShouldFallback to call the evendeep standard processing }), diff --git a/cvts.go b/cvts.go index 1e17652..5b0484a 100644 --- a/cvts.go +++ b/cvts.go @@ -9,127 +9,2138 @@ import ( "reflect" "strconv" "strings" + "sync" "time" - "github.com/hedzr/log" + "github.com/hedzr/evendeep/dbglog" + "github.com/hedzr/evendeep/flags" + "github.com/hedzr/evendeep/flags/cms" + "github.com/hedzr/evendeep/internal/syscalls" + "github.com/hedzr/evendeep/ref" + "github.com/hedzr/evendeep/typ" + + logz "github.com/hedzr/logg/slog" + + "gopkg.in/hedzr/errors.v3" +) + +const timeConstString = "time" + +// RegisterDefaultConverters registers the ValueConverter list into +// default converters registry. +// +// It takes effects on DefaultCopyController, MakeClone, DeepCopy, +// and New, .... +func RegisterDefaultConverters(ss ...ValueConverter) { + defValueConverters = append(defValueConverters, ss...) + lenValueConverters, lenValueCopiers = len(defValueConverters), len(defValueCopiers) + initGlobalOperators() +} + +// RegisterDefaultCopiers registers the ValueCopier list into +// default copiers registry. +// +// It takes effects on DefaultCopyController, MakeClone, DeepCopy, +// and New, .... +func RegisterDefaultCopiers(ss ...ValueCopier) { + defValueCopiers = append(defValueCopiers, ss...) + lenValueConverters, lenValueCopiers = len(defValueConverters), len(defValueCopiers) + initGlobalOperators() +} + +func initConverters() { + dbglog.Log("initializing default converters and copiers ...") + defValueConverters = ValueConverters{ // Transform() + &fromStringConverter{}, // the final choice here + &toStringConverter{}, + + // &toFuncConverter{}, + &fromFuncConverter{}, + + &toDurationConverter{}, + &fromDurationConverter{}, + &toTimeConverter{}, + &fromTimeConverter{}, + + &fromBytesBufferConverter{}, + &fromSyncPkgConverter{}, + &fromMapConverter{}, + } + defValueCopiers = ValueCopiers{ // CopyTo() + &fromStringConverter{}, // the final choice here + &toStringConverter{}, + + &toFuncConverter{}, + &fromFuncConverter{}, + + &toDurationConverter{}, + &fromDurationConverter{}, + &toTimeConverter{}, + &fromTimeConverter{}, + + &fromBytesBufferConverter{}, + &fromSyncPkgConverter{}, + &fromMapConverter{}, + } + + lenValueConverters, lenValueCopiers = len(defValueConverters), len(defValueCopiers) +} + +var defValueConverters ValueConverters //nolint:gochecknoglobals //i know that +var defValueCopiers ValueCopiers //nolint:gochecknoglobals //i know that +var lenValueConverters, lenValueCopiers int //nolint:gochecknoglobals //i know that + +func defaultValueConverters() ValueConverters { return defValueConverters } +func defaultValueCopiers() ValueCopiers { return defValueCopiers } + +// ValueConverter for internal used. +type ValueConverter interface { + Transform(ctx *ValueConverterContext, source reflect.Value, targetType reflect.Type) (target reflect.Value, err error) + Match(params *Params, source, target reflect.Type) (ctx *ValueConverterContext, yes bool) +} + +// ValueCopier for internal used. +type ValueCopier interface { + CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) + Match(params *Params, source, target reflect.Type) (ctx *ValueConverterContext, yes bool) +} + +// NameConverter for internal used. +type NameConverter interface { + ToGoName(ctx *NameConverterContext, fieldName string) (goName string) + ToFieldName(ctx *NameConverterContext, goName string) (fieldName string) +} + +// ValueConverters for internal used. +type ValueConverters []ValueConverter + +// ValueCopiers for internal used. +type ValueCopiers []ValueCopier + +// NameConverters for internal used. +type NameConverters []NameConverter + +// NameConverterContext for internal used. +type NameConverterContext struct { + *Params +} + +// ValueConverterContext for internal used. +type ValueConverterContext struct { + *Params +} + +// + +type CvtV struct { + Data any +} + +func (s *CvtV) String() string { + return anyToString(s.Data) +} + +// + +type Cvt struct{} + +func (s *Cvt) String(data any) string { return anyToString(data) } +func (s *Cvt) StringSlice(data any) []string { return anyToStringSlice(data) } +func (s *Cvt) StringMap(data any) map[string]string { return anyToStringMap(data) } + +func anyToStringSlice(data any) (ret []string) { + if data == nil { + return + } + + switch z := data.(type) { + case []string: + return z + + case []float64: + return zfToStringS(z) + case []float32: + return zfToStringS(z) + + case []int: + return zfToStringS(z) + case []int64: + return zfToStringS(z) + case []int32: + return zfToStringS(z) + case []int16: + return zfToStringS(z) + case []int8: + return zfToStringS(z) + case []uint: + return zfToStringS(z) + case []uint64: + return zfToStringS(z) + case []uint32: + return zfToStringS(z) + case []uint16: + return zfToStringS(z) + case []uint8: + return zfToStringS(z) + + case []bool: + return zfToStringS(z) + case []fmt.Stringer: + return zfToStringS(z) + default: + break + } + return +} + +func zfToStringS[T any](in []T) (out []string) { + out = make([]string, 0, len(in)) + for _, it := range in { + out = append(out, anyToString(it)) + } + return +} + +func zfToStringM(in map[string]any) (out map[string]string) { + out = make(map[string]string, len(in)) + for k, it := range in { + out[k] = anyToString(it) + } + return +} + +func anyToStringMap(data any) (ret map[string]string) { + if data == nil { + return + } + + switch z := data.(type) { + case map[string]string: + return z + case map[string]any: + return zfToStringM(z) + default: + break + } + return +} + +// + +func (s *Cvt) Bool(data any) bool { return anyToBool(data) } + +func anyToBool(data any) bool { + if data == nil { + return false + } + + switch z := data.(type) { + case bool: + return z + default: + return toBool(anyToString(data)) + } +} + +func toBool(s string) bool { + _, ok := stringToBoolMap[strings.ToLower(s)] + return ok +} + +var stringToBoolMap = map[string]struct{}{ + "1": {}, + "t": {}, + "male": {}, + "y": {}, + "yes": {}, + "true": {}, + "ok": {}, + "allow": {}, + "on": {}, + "open": {}, +} + +func (s *Cvt) BoolSlice(data any) []bool { return anyToBoolSlice(data) } + +func anyToBoolSlice(data any) (ret []bool) { + if data == nil { + return + } + + switch z := data.(type) { + case []bool: + return z + + case []float64: + return zfToBoolS(z) + case []float32: + return zfToBoolS(z) + + case []int: + return zfToBoolS(z) + case []int64: + return zfToBoolS(z) + case []int32: + return zfToBoolS(z) + case []int16: + return zfToBoolS(z) + case []int8: + return zfToBoolS(z) + case []uint: + return zfToBoolS(z) + case []uint64: + return zfToBoolS(z) + case []uint32: + return zfToBoolS(z) + case []uint16: + return zfToBoolS(z) + case []uint8: + return zfToBoolS(z) + + case []string: + return zfToBoolS(z) + case []fmt.Stringer: + return zfToBoolS(z) + default: + break + } + return +} + +func zfToBoolS[T any](in []T) (out []bool) { + out = make([]bool, 0, len(in)) + for _, it := range in { + out = append(out, anyToBool(it)) + } + return +} + +func (s *Cvt) BoolMap(data any) map[string]bool { return anyToBoolMap(data) } + +func zfToBoolM(in map[string]any) (out map[string]bool) { + out = make(map[string]bool, len(in)) + for k, it := range in { + out[k] = anyToBool(it) + } + return +} + +func anyToBoolMap(data any) (ret map[string]bool) { + if data == nil { + return + } + + switch z := data.(type) { + case map[string]bool: + return z + case map[string]any: + return zfToBoolM(z) + default: + break + } + return +} + +// + +func (s *Cvt) Int(data any) int64 { return anyToInt(data) } + +func anyToInt(data any) int64 { + if data == nil { + return 0 + } + + switch z := data.(type) { + case int: + return int64(z) + case int8: + return int64(z) + case int16: + return int64(z) + case int32: + return int64(z) + case int64: + return z + + case uint: + return int64(z) + case uint8: + return int64(z) + case uint16: + return int64(z) + case uint32: + return int64(z) + case uint64: + if z <= uint64(math.MaxInt64) { + return int64(z) + } + break + + case float32: + return int64(z) + case float64: + return int64(z) + + case complex64: + return int64(real(z)) + case complex128: + return int64(real(z)) + + case string: + return atoi(z) + + case time.Duration: + return int64(z) + case time.Time: + return z.UnixNano() + + default: + return atoi(fmt.Sprint(data)) + } + + // reflect approach + rv := reflect.ValueOf(data) + logz.Warn("[anyToInt]: unrecognized data type", + "typ", ref.Typfmtv(&rv), + "val", ref.Valfmt(&rv), + ) + return 0 +} + +// + +func (s *Cvt) Int64Slice(data any) []int64 { return anyToInt64Slice(data) } +func (s *Cvt) Int32Slice(data any) []int32 { return anyToInt32Slice(data) } +func (s *Cvt) Int16Slice(data any) []int16 { return anyToInt16Slice(data) } +func (s *Cvt) Int8Slice(data any) []int8 { return anyToInt8Slice(data) } +func (s *Cvt) IntSlice(data any) []int { return anyToIntSlice(data) } + +func anyToInt64Slice(data any) (ret []int64) { + if data == nil { + return + } + + switch z := data.(type) { + case []int64: + return z + + case []float64: + return zfToInt64S(z) + case []float32: + return zfToInt64S(z) + + case []int: + return zfToInt64S(z) + case []string: + return zfToInt64S(z) + case []int32: + return zfToInt64S(z) + case []int16: + return zfToInt64S(z) + case []int8: + return zfToInt64S(z) + case []uint: + return zfToInt64S(z) + case []uint64: + return zfToInt64S(z) + case []uint32: + return zfToInt64S(z) + case []uint16: + return zfToInt64S(z) + case []uint8: + return zfToInt64S(z) + + case []bool: + return zfToInt64S(z) + case []fmt.Stringer: + return zfToInt64S(z) + default: + break + } + return +} + +func anyToInt32Slice(data any) (ret []int32) { + if data == nil { + return + } + + switch z := data.(type) { + case []int32: + return z + + case []float64: + return zfToInt32S(z) + case []float32: + return zfToInt32S(z) + + case []int: + return zfToInt32S(z) + case []string: + return zfToInt32S(z) + case []int64: + return zfToInt32S(z) + case []int16: + return zfToInt32S(z) + case []int8: + return zfToInt32S(z) + case []uint: + return zfToInt32S(z) + case []uint64: + return zfToInt32S(z) + case []uint32: + return zfToInt32S(z) + case []uint16: + return zfToInt32S(z) + case []uint8: + return zfToInt32S(z) + + case []bool: + return zfToInt32S(z) + case []fmt.Stringer: + return zfToInt32S(z) + default: + break + } + return +} + +func anyToInt16Slice(data any) (ret []int16) { + if data == nil { + return + } + + switch z := data.(type) { + case []int16: + return z + + case []float64: + return zfToInt16S(z) + case []float32: + return zfToInt16S(z) + + case []int: + return zfToInt16S(z) + case []string: + return zfToInt16S(z) + case []int32: + return zfToInt16S(z) + case []int64: + return zfToInt16S(z) + case []int8: + return zfToInt16S(z) + case []uint: + return zfToInt16S(z) + case []uint64: + return zfToInt16S(z) + case []uint32: + return zfToInt16S(z) + case []uint16: + return zfToInt16S(z) + case []uint8: + return zfToInt16S(z) + + case []bool: + return zfToInt16S(z) + case []fmt.Stringer: + return zfToInt16S(z) + default: + break + } + return +} + +func anyToInt8Slice(data any) (ret []int8) { + if data == nil { + return + } + + switch z := data.(type) { + case []int8: + return z + + case []float64: + return zfToInt8S(z) + case []float32: + return zfToInt8S(z) + + case []int: + return zfToInt8S(z) + case []string: + return zfToInt8S(z) + case []int32: + return zfToInt8S(z) + case []int16: + return zfToInt8S(z) + case []int64: + return zfToInt8S(z) + case []uint: + return zfToInt8S(z) + case []uint64: + return zfToInt8S(z) + case []uint32: + return zfToInt8S(z) + case []uint16: + return zfToInt8S(z) + case []uint8: + return zfToInt8S(z) + + case []bool: + return zfToInt8S(z) + case []fmt.Stringer: + return zfToInt8S(z) + default: + break + } + return +} + +func anyToIntSlice(data any) (ret []int) { + if data == nil { + return + } + + switch z := data.(type) { + case []int: + return z + + case []float64: + return zfToIntS(z) + case []float32: + return zfToIntS(z) + + case []int64: + return zfToIntS(z) + case []string: + return zfToIntS(z) + case []int32: + return zfToIntS(z) + case []int16: + return zfToIntS(z) + case []int8: + return zfToIntS(z) + case []uint: + return zfToIntS(z) + case []uint64: + return zfToIntS(z) + case []uint32: + return zfToIntS(z) + case []uint16: + return zfToIntS(z) + case []uint8: + return zfToIntS(z) + + case []bool: + return zfToIntS(z) + case []fmt.Stringer: + return zfToIntS(z) + default: + break + } + return +} + +func zfToInt64S[T any](in []T) (out []int64) { + out = make([]int64, 0, len(in)) + for _, it := range in { + out = append(out, anyToInt(it)) + } + return +} + +func zfToInt32S[T any](in []T) (out []int32) { + out = make([]int32, 0, len(in)) + for _, it := range in { + out = append(out, int32(anyToInt(it))) + } + return +} + +func zfToInt16S[T any](in []T) (out []int16) { + out = make([]int16, 0, len(in)) + for _, it := range in { + out = append(out, int16(anyToInt(it))) + } + return +} + +func zfToInt8S[T any](in []T) (out []int8) { + out = make([]int8, 0, len(in)) + for _, it := range in { + out = append(out, int8(anyToInt(it))) + } + return +} + +func zfToIntS[T any](in []T) (out []int) { + out = make([]int, 0, len(in)) + for _, it := range in { + out = append(out, int(anyToInt(it))) + } + return +} + +// + +func (s *Cvt) Int64Map(data any) map[string]int64 { return anyToInt64Map(data) } +func (s *Cvt) Int32Map(data any) map[string]int32 { return anyToInt32Map(data) } +func (s *Cvt) Int16Map(data any) map[string]int16 { return anyToInt16Map(data) } +func (s *Cvt) Int8Map(data any) map[string]int8 { return anyToInt8Map(data) } +func (s *Cvt) IntMap(data any) map[string]int { return anyToIntMap(data) } + +func anyToInt64Map(data any) (ret map[string]int64) { + if data == nil { + return + } + + switch z := data.(type) { + case map[string]int64: + return z + case map[string]any: + return zfToInt64M(z) + default: + break + } + return +} + +func anyToInt32Map(data any) (ret map[string]int32) { + if data == nil { + return + } + + switch z := data.(type) { + case map[string]int32: + return z + case map[string]any: + return zfToInt32M(z) + default: + break + } + return +} + +func anyToInt16Map(data any) (ret map[string]int16) { + if data == nil { + return + } + + switch z := data.(type) { + case map[string]int16: + return z + case map[string]any: + return zfToInt16M(z) + default: + break + } + return +} + +func anyToInt8Map(data any) (ret map[string]int8) { + if data == nil { + return + } + + switch z := data.(type) { + case map[string]int8: + return z + case map[string]any: + return zfToInt8M(z) + default: + break + } + return +} + +func anyToIntMap(data any) (ret map[string]int) { + if data == nil { + return + } + + switch z := data.(type) { + case map[string]int: + return z + case map[string]any: + return zfToIntM(z) + default: + break + } + return +} + +func zfToInt64M(in map[string]any) (out map[string]int64) { + out = make(map[string]int64, len(in)) + for k, it := range in { + out[k] = anyToInt(it) + } + return +} + +func zfToInt32M(in map[string]any) (out map[string]int32) { + out = make(map[string]int32, len(in)) + for k, it := range in { + out[k] = int32(anyToInt(it)) + } + return +} + +func zfToInt16M(in map[string]any) (out map[string]int16) { + out = make(map[string]int16, len(in)) + for k, it := range in { + out[k] = int16(anyToInt(it)) + } + return +} + +func zfToInt8M(in map[string]any) (out map[string]int8) { + out = make(map[string]int8, len(in)) + for k, it := range in { + out[k] = int8(anyToInt(it)) + } + return +} + +func zfToIntM(in map[string]any) (out map[string]int) { + out = make(map[string]int, len(in)) + for k, it := range in { + out[k] = int(anyToInt(it)) + } + return +} + +// + +func (s *Cvt) Uint(data any) uint64 { return anyToUint(data) } + +func anyToUint(data any) uint64 { + if data == nil { + return 0 + } + + switch z := data.(type) { + case int: + return uint64(z) + case int8: + return uint64(z) + case int16: + return uint64(z) + case int32: + return uint64(z) + case int64: + return uint64(z) + + case uint: + return uint64(z) + case uint8: + return uint64(z) + case uint16: + return uint64(z) + case uint32: + return uint64(z) + case uint64: + return z + + case float32: + return uint64(z) + case float64: + return uint64(z) + + case complex64: + return uint64(real(z)) + case complex128: + return uint64(real(z)) + + case string: + return atou(z) + + case time.Duration: + return uint64(z) + case time.Time: + return uint64(z.UnixNano()) + + default: + return atou(fmt.Sprint(data)) + } +} + +func atoi(v string) int64 { + if i, err := strconv.ParseInt(v, 10, 64); err == nil { + return i + } + if f, err := strconv.ParseFloat(v, 64); err == nil { + return int64(f) + } + if u, err := strconv.ParseUint(v, 10, 64); err != nil { + return int64(u) + } + return 0 +} + +func atou(v string) uint64 { + if u, err := strconv.ParseUint(v, 10, 64); err != nil { + return u + } + if i, err := strconv.ParseInt(v, 10, 64); err == nil { + return uint64(i) + } + if f, err := strconv.ParseFloat(v, 64); err == nil { + return uint64(f) + } + return 0 +} + +// + +func (s *Cvt) Uint64Slice(data any) []uint64 { return anyToUint64Slice(data) } +func (s *Cvt) Uint32Slice(data any) []uint32 { return anyToUint32Slice(data) } +func (s *Cvt) Uint16Slice(data any) []uint16 { return anyToUint16Slice(data) } +func (s *Cvt) Uint8Slice(data any) []uint8 { return anyToUint8Slice(data) } +func (s *Cvt) UintSlice(data any) []uint { return anyToUintSlice(data) } + +func anyToUint64Slice(data any) (ret []uint64) { + if data == nil { + return + } + + switch z := data.(type) { + case []uint64: + return z + + case []float64: + return zfToUint64S(z) + case []float32: + return zfToUint64S(z) + + case []int: + return zfToUint64S(z) + case []string: + return zfToUint64S(z) + case []int32: + return zfToUint64S(z) + case []int16: + return zfToUint64S(z) + case []int8: + return zfToUint64S(z) + case []uint: + return zfToUint64S(z) + case []int64: + return zfToUint64S(z) + case []uint32: + return zfToUint64S(z) + case []uint16: + return zfToUint64S(z) + case []uint8: + return zfToUint64S(z) + + case []bool: + return zfToUint64S(z) + case []fmt.Stringer: + return zfToUint64S(z) + default: + break + } + return +} + +func anyToUint32Slice(data any) (ret []uint32) { + if data == nil { + return + } + + switch z := data.(type) { + case []uint32: + return z + + case []float64: + return zfToUint32S(z) + case []float32: + return zfToUint32S(z) + + case []int: + return zfToUint32S(z) + case []string: + return zfToUint32S(z) + case []int64: + return zfToUint32S(z) + case []int16: + return zfToUint32S(z) + case []int8: + return zfToUint32S(z) + case []uint: + return zfToUint32S(z) + case []uint64: + return zfToUint32S(z) + case []int32: + return zfToUint32S(z) + case []uint16: + return zfToUint32S(z) + case []uint8: + return zfToUint32S(z) + + case []bool: + return zfToUint32S(z) + case []fmt.Stringer: + return zfToUint32S(z) + default: + break + } + return +} + +func anyToUint16Slice(data any) (ret []uint16) { + if data == nil { + return + } + + switch z := data.(type) { + case []uint16: + return z + + case []float64: + return zfToUint16S(z) + case []float32: + return zfToUint16S(z) + + case []int: + return zfToUint16S(z) + case []string: + return zfToUint16S(z) + case []int32: + return zfToUint16S(z) + case []int64: + return zfToUint16S(z) + case []int8: + return zfToUint16S(z) + case []uint: + return zfToUint16S(z) + case []uint64: + return zfToUint16S(z) + case []uint32: + return zfToUint16S(z) + case []int16: + return zfToUint16S(z) + case []uint8: + return zfToUint16S(z) + + case []bool: + return zfToUint16S(z) + case []fmt.Stringer: + return zfToUint16S(z) + default: + break + } + return +} + +func anyToUint8Slice(data any) (ret []uint8) { + if data == nil { + return + } + + switch z := data.(type) { + case []uint8: + return z + + case []float64: + return zfToUint8S(z) + case []float32: + return zfToUint8S(z) + + case []int: + return zfToUint8S(z) + case []string: + return zfToUint8S(z) + case []int32: + return zfToUint8S(z) + case []int16: + return zfToUint8S(z) + case []int64: + return zfToUint8S(z) + case []uint: + return zfToUint8S(z) + case []uint64: + return zfToUint8S(z) + case []uint32: + return zfToUint8S(z) + case []uint16: + return zfToUint8S(z) + case []int8: + return zfToUint8S(z) + + case []bool: + return zfToUint8S(z) + case []fmt.Stringer: + return zfToUint8S(z) + default: + break + } + return +} + +func anyToUintSlice(data any) (ret []uint) { + if data == nil { + return + } + + switch z := data.(type) { + case []uint: + return z + + case []float64: + return zfToUintS(z) + case []float32: + return zfToUintS(z) + + case []int64: + return zfToUintS(z) + case []string: + return zfToUintS(z) + case []int32: + return zfToUintS(z) + case []int16: + return zfToUintS(z) + case []int8: + return zfToUintS(z) + case []int: + return zfToUintS(z) + case []uint64: + return zfToUintS(z) + case []uint32: + return zfToUintS(z) + case []uint16: + return zfToUintS(z) + case []uint8: + return zfToUintS(z) + + case []bool: + return zfToUintS(z) + case []fmt.Stringer: + return zfToUintS(z) + default: + break + } + return +} + +func zfToUint64S[T any](in []T) (out []uint64) { + out = make([]uint64, 0, len(in)) + for _, it := range in { + out = append(out, anyToUint(it)) + } + return +} + +func zfToUint32S[T any](in []T) (out []uint32) { + out = make([]uint32, 0, len(in)) + for _, it := range in { + out = append(out, uint32(anyToUint(it))) + } + return +} + +func zfToUint16S[T any](in []T) (out []uint16) { + out = make([]uint16, 0, len(in)) + for _, it := range in { + out = append(out, uint16(anyToUint(it))) + } + return +} + +func zfToUint8S[T any](in []T) (out []uint8) { + out = make([]uint8, 0, len(in)) + for _, it := range in { + out = append(out, uint8(anyToUint(it))) + } + return +} + +func zfToUintS[T any](in []T) (out []uint) { + out = make([]uint, 0, len(in)) + for _, it := range in { + out = append(out, uint(anyToUint(it))) + } + return +} + +// + +func (s *Cvt) Uint64Map(data any) map[string]uint64 { return anyToUint64Map(data) } +func (s *Cvt) Uint32Map(data any) map[string]uint32 { return anyToUint32Map(data) } +func (s *Cvt) Uint16Map(data any) map[string]uint16 { return anyToUint16Map(data) } +func (s *Cvt) Uint8Map(data any) map[string]uint8 { return anyToUint8Map(data) } +func (s *Cvt) UintMap(data any) map[string]uint { return anyToUintMap(data) } + +func anyToUint64Map(data any) (ret map[string]uint64) { + if data == nil { + return + } + + switch z := data.(type) { + case map[string]uint64: + return z + case map[string]any: + return zfToUint64M(z) + default: + break + } + return +} + +func anyToUint32Map(data any) (ret map[string]uint32) { + if data == nil { + return + } + + switch z := data.(type) { + case map[string]uint32: + return z + case map[string]any: + return zfToUint32M(z) + default: + break + } + return +} + +func anyToUint16Map(data any) (ret map[string]uint16) { + if data == nil { + return + } + + switch z := data.(type) { + case map[string]uint16: + return z + case map[string]any: + return zfToUint16M(z) + default: + break + } + return +} + +func anyToUint8Map(data any) (ret map[string]uint8) { + if data == nil { + return + } + + switch z := data.(type) { + case map[string]uint8: + return z + case map[string]any: + return zfToUint8M(z) + default: + break + } + return +} + +func anyToUintMap(data any) (ret map[string]uint) { + if data == nil { + return + } + + switch z := data.(type) { + case map[string]uint: + return z + case map[string]any: + return zfToUintM(z) + default: + break + } + return +} + +func zfToUint64M(in map[string]any) (out map[string]uint64) { + out = make(map[string]uint64, len(in)) + for k, it := range in { + out[k] = anyToUint(it) + } + return +} + +func zfToUint32M(in map[string]any) (out map[string]uint32) { + out = make(map[string]uint32, len(in)) + for k, it := range in { + out[k] = uint32(anyToUint(it)) + } + return +} + +func zfToUint16M(in map[string]any) (out map[string]uint16) { + out = make(map[string]uint16, len(in)) + for k, it := range in { + out[k] = uint16(anyToUint(it)) + } + return +} + +func zfToUint8M(in map[string]any) (out map[string]uint8) { + out = make(map[string]uint8, len(in)) + for k, it := range in { + out[k] = uint8(anyToUint(it)) + } + return +} + +func zfToUintM(in map[string]any) (out map[string]uint) { + out = make(map[string]uint, len(in)) + for k, it := range in { + out[k] = uint(anyToUint(it)) + } + return +} + +// + +// + +func anyToString(data any) string { + if data == nil { + return "" + } + rv := reflect.ValueOf(data) + if ref.IsZero(rv) { + return "" + } + + switch z := data.(type) { + case string: + return z + + case time.Duration: + return durationToString(z) + case time.Time: + return timeToString(z) + case []time.Time: + return timeSliceToString(z) + case []time.Duration: + return durationSliceToString(z) + + case error: + return z.Error() + + case fmt.Stringer: + return z.String() + + case bool: + return boolToString(z) + + case []byte: + return bytesToString(z) + + case []string: + return stringSliceToString(z) + + case []bool: + return boolSliceToString(z) + + case []int: + return intSliceToString(z) + case []int8: + return intSliceToString(z) + case []int16: + return intSliceToString(z) + case []int32: + return intSliceToString(z) + case []int64: + return intSliceToString(z) + + case int: + return intToString(z) + case int8: + return intToString(z) + case int16: + return intToString(z) + case int32: + return intToString(z) + case int64: + return intToString(z) + + case []uint: + return uintSliceToString(z) + // case []uint8: // = []byte + case []uint16: + return uintSliceToString(z) + case []uint32: + return uintSliceToString(z) + case []uint64: + return uintSliceToString(z) + + case uint: + return uintToString(z) + case uint8: + return uintToString(z) + case uint16: + return uintToString(z) + case uint32: + return uintToString(z) + case uint64: + return uintToString(z) + + case []float32: + return floatSliceToString(z) + case []float64: + return floatSliceToString(z) + + case float32: + return floatToString(z) + case float64: + return floatToString(z) + + case []complex64: + return complexSliceToString(z) + case []complex128: + return complexSliceToString(z) + + case complex64: + return complexToString(z) + case complex128: + return complexToString(z) + + default: + break + } + + // reflect approach + logz.Warn("[anyToString]: unrecognized data type", + "typ", ref.Typfmtv(&rv), + "val", ref.Valfmt(&rv), + ) + return ref.Valfmt(&rv) +} + +// + +func (s *Cvt) Float64(data any) float64 { return anyToFloat[float64](data) } +func (s *Cvt) Float32(data any) float32 { return anyToFloat[float32](data) } + +func anyToFloat[R Floats](data any) R { + if data == nil { + return 0 + } + + switch z := data.(type) { + case float64: + return R(z) + case float32: + return R(z) + + case int: + return R(z) + case int64: + return R(z) + case int32: + return R(z) + case int16: + return R(z) + case int8: + return R(z) + case uint: + return R(z) + case uint64: + return R(z) + case uint32: + return R(z) + case uint16: + return R(z) + case uint8: + return R(z) + + case string: + return R(mustParseFloat(z)) + case fmt.Stringer: + return R(mustParseFloat(z.String())) + + default: + str := fmt.Sprintf("%v", data) + return R(mustParseFloat(str)) + } +} + +func mustParseFloat(s string) (ret float64) { + ret, _ = strconv.ParseFloat(s, 64) + return +} + +func (s *Cvt) Float64Slice(data any) []float64 { return anyToFloatSlice[float64](data) } +func (s *Cvt) Float32Slice(data any) []float32 { return anyToFloatSlice[float32](data) } + +func zfToFloatS[T Floats, R Floats](in []T) (out []R) { + out = make([]R, 0, len(in)) + for _, it := range in { + out = append(out, R(it)) + } + return +} + +func anyToFloatSlice[R Floats](data any) (ret []R) { + if data == nil { + return + } + + switch z := data.(type) { + case []float64: + return zfToFloatS[float64, R](z) + case []float32: + return zfToFloatS[float32, R](z) + + case []int: + return zsToFloatS[int, R](z) + case []int64: + return zsToFloatS[int64, R](z) + case []int32: + return zsToFloatS[int32, R](z) + case []int16: + return zsToFloatS[int16, R](z) + case []int8: + return zsToFloatS[int8, R](z) + case []uint: + return zsToFloatS[uint, R](z) + case []uint64: + return zsToFloatS[uint64, R](z) + case []uint32: + return zsToFloatS[uint32, R](z) + case []uint16: + return zsToFloatS[uint16, R](z) + case []uint8: + return zsToFloatS[uint8, R](z) + + case []string: + ret = make([]R, 0, len(z)) + for _, it := range z { + ret = append(ret, R(mustParseFloat(it))) + } + return + case []fmt.Stringer: + ret = make([]R, 0, len(z)) + for _, it := range z { + ret = append(ret, R(mustParseFloat(it.String()))) + } + return + + default: + break + } + return +} + +func zsToFloatS[T Integers | Uintegers, R Floats](z []T) (ret []R) { + ret = make([]R, 0, len(z)) + for _, it := range z { + ret = append(ret, R(int64(it))) + } + return +} - "github.com/hedzr/evendeep/dbglog" - "github.com/hedzr/evendeep/flags" - "github.com/hedzr/evendeep/flags/cms" - "github.com/hedzr/evendeep/internal/syscalls" - "github.com/hedzr/evendeep/internal/tool" - "github.com/hedzr/evendeep/typ" +func (s *Cvt) Float64Map(data any) map[string]float64 { return anyToFloat64Map(data) } +func (s *Cvt) Float32Map(data any) map[string]float32 { return anyToFloat32Map(data) } - "gopkg.in/hedzr/errors.v3" -) +func anyToFloat64Map(data any) (ret map[string]float64) { + if data == nil { + return + } -const timeConstString = "time" + switch z := data.(type) { + case map[string]float64: + return z + case map[string]any: + return zfToFloat64M(z) + default: + break + } + return +} + +func anyToFloat32Map(data any) (ret map[string]float32) { + if data == nil { + return + } + + switch z := data.(type) { + case map[string]float32: + return z + case map[string]any: + return zfToFloat32M(z) + default: + break + } + return +} + +func zfToFloat64M(in map[string]any) (out map[string]float64) { + out = make(map[string]float64, len(in)) + for k, it := range in { + out[k] = anyToFloat[float64](it) + } + return +} + +func zfToFloat32M(in map[string]any) (out map[string]float32) { + out = make(map[string]float32, len(in)) + for k, it := range in { + out[k] = anyToFloat[float32](it) + } + return +} -// RegisterDefaultConverters registers the ValueConverter list into -// default converters registry. // -// It takes effects on DefaultCopyController, MakeClone, DeepCopy, -// and New, .... -func RegisterDefaultConverters(ss ...ValueConverter) { - defValueConverters = append(defValueConverters, ss...) - initGlobalOperators() + +func (s *Cvt) Complex128(data any) complex128 { return anyToComplex[complex128](data) } +func (s *Cvt) Complex64(data any) complex64 { return anyToComplex[complex64](data) } + +func anyToComplex[R Complexes](data any) R { + if data == nil { + return 0 + } + + switch z := data.(type) { + case complex128: + return R(z) + case complex64: + return R(z) + + case int: + return R(complex(float64(z), 0)) + case int64: + return R(complex(float64(z), 0)) + case int32: + return R(complex(float64(z), 0)) + case int16: + return R(complex(float64(z), 0)) + case int8: + return R(complex(float64(z), 0)) + case uint: + return R(complex(float64(z), 0)) + case uint64: + return R(complex(float64(z), 0)) + case uint32: + return R(complex(float64(z), 0)) + case uint16: + return R(complex(float64(z), 0)) + case uint8: + return R(complex(float64(z), 0)) + + case float64: + return R(complex(float64(z), 0)) + case float32: + return R(complex(float32(z), 0)) + + case string: + return R(mustParseComplex(z)) + case fmt.Stringer: + return R(mustParseComplex(z.String())) + + default: + str := fmt.Sprintf("%v", data) + return R(mustParseComplex(str)) + } +} + +func mustParseComplex(s string) (ret complex128) { + ret, _ = strconv.ParseComplex(s, 64) + return +} + +func (s *Cvt) Complex128Slice(data any) []complex128 { return anyToComplexSlice[complex128](data) } +func (s *Cvt) Complex64Slice(data any) []complex64 { return anyToComplexSlice[complex64](data) } + +func zfToComplexS[T Complexes, R Complexes](in []T) (out []R) { + out = make([]R, 0, len(in)) + for _, it := range in { + out = append(out, R(it)) + } + return +} + +func anyToComplexSlice[R Complexes](data any) (ret []R) { + if data == nil { + return + } + + switch z := data.(type) { + case []complex128: + return zfToComplexS[complex128, R](z) + case []complex64: + return zfToComplexS[complex64, R](z) + + case []float64: + return zsToComplexS[float64, R](z) + case []float32: + return zsToComplexS[float32, R](z) + + case []int: + return zsToComplexS[int, R](z) + case []int64: + return zsToComplexS[int64, R](z) + case []int32: + return zsToComplexS[int32, R](z) + case []int16: + return zsToComplexS[int16, R](z) + case []int8: + return zsToComplexS[int8, R](z) + case []uint: + return zsToComplexS[uint, R](z) + case []uint64: + return zsToComplexS[uint64, R](z) + case []uint32: + return zsToComplexS[uint32, R](z) + case []uint16: + return zsToComplexS[uint16, R](z) + case []uint8: + return zsToComplexS[uint8, R](z) + + case []string: + ret = make([]R, 0, len(z)) + for _, it := range z { + ret = append(ret, R(mustParseComplex(it))) + } + return + case []fmt.Stringer: + ret = make([]R, 0, len(z)) + for _, it := range z { + ret = append(ret, R(mustParseComplex(it.String()))) + } + return + + default: + break + } + return +} + +func zsToComplexS[T Integers | Uintegers | Floats, R Complexes](z []T) (ret []R) { + ret = make([]R, 0, len(z)) + for _, it := range z { + ret = append(ret, R(complex(float64(it), 0))) + } + return +} + +func (s *Cvt) Complex128Map(data any) map[string]complex128 { return anyToComplex128Map(data) } +func (s *Cvt) Complex64Map(data any) map[string]complex64 { return anyToComplex64Map(data) } + +func anyToComplex128Map(data any) (ret map[string]complex128) { + if data == nil { + return + } + + switch z := data.(type) { + case map[string]complex128: + return z + case map[string]any: + return zfToComplex128M(z) + default: + break + } + return +} + +func anyToComplex64Map(data any) (ret map[string]complex64) { + if data == nil { + return + } + + switch z := data.(type) { + case map[string]complex64: + return z + case map[string]any: + return zfToComplex64M(z) + default: + break + } + return +} + +func zfToComplex128M(in map[string]any) (out map[string]complex128) { + out = make(map[string]complex128, len(in)) + for k, it := range in { + out[k] = anyToComplex[complex128](it) + } + return +} + +func zfToComplex64M(in map[string]any) (out map[string]complex64) { + out = make(map[string]complex64, len(in)) + for k, it := range in { + out[k] = anyToComplex[complex64](it) + } + return } -// RegisterDefaultCopiers registers the ValueCopier list into -// default copiers registry. // -// It takes effects on DefaultCopyController, MakeClone, DeepCopy, -// and New, .... -func RegisterDefaultCopiers(ss ...ValueCopier) { - defValueCopiers = append(defValueCopiers, ss...) - initGlobalOperators() + +func (s *Cvt) Duration(data any) time.Duration { return anyToDuration(data) } + +func anyToDuration(data any) time.Duration { + if data == nil { + return 0 + } + + switch z := data.(type) { + case time.Duration: + return z + + case int: + return time.Duration(int64(z)) + case int64: + return time.Duration(int64(z)) + case int32: + return time.Duration(int64(z)) + case int16: + return time.Duration(int64(z)) + case int8: + return time.Duration(int64(z)) + case uint: + return time.Duration(int64(z)) + case uint64: + return time.Duration(int64(z)) + case uint32: + return time.Duration(int64(z)) + case uint16: + return time.Duration(int64(z)) + case uint8: + return time.Duration(int64(z)) + + case string: + return mustParseDuration(z) + case fmt.Stringer: + return mustParseDuration(z.String()) + + default: + str := fmt.Sprintf("%v", data) + return mustParseDuration(str) + } } -func initConverters() { - dbglog.Log("initializing default converters and copiers ...") - defValueConverters = ValueConverters{ // Transform() - &fromStringConverter{}, // the final choice here - &toStringConverter{}, +func (s *Cvt) DurationSlice(data any) []time.Duration { return anyToDurationSlice(data) } - // &toFuncConverter{}, - &fromFuncConverter{}, +func anyToDurationSlice(data any) (ret []time.Duration) { + if data == nil { + return + } - &toDurationConverter{}, - &fromDurationConverter{}, - &toTimeConverter{}, - &fromTimeConverter{}, + switch z := data.(type) { + case []time.Duration: + return z + + case []int: + return zsToDurationS(z) + case []int64: + return zsToDurationS(z) + case []int32: + return zsToDurationS(z) + case []int16: + return zsToDurationS(z) + case []int8: + return zsToDurationS(z) + case []uint: + return zsToDurationS(z) + case []uint64: + return zsToDurationS(z) + case []uint32: + return zsToDurationS(z) + case []uint16: + return zsToDurationS(z) + case []uint8: + return zsToDurationS(z) + + case []string: + ret = make([]time.Duration, 0, len(z)) + for _, it := range z { + ret = append(ret, mustParseDuration(it)) + } + return + case []fmt.Stringer: + ret = make([]time.Duration, 0, len(z)) + for _, it := range z { + ret = append(ret, mustParseDuration(it.String())) + } + return - &fromBytesBufferConverter{}, - &fromSyncPkgConverter{}, - &fromMapConverter{}, + default: + break } - defValueCopiers = ValueCopiers{ // CopyTo() - &fromStringConverter{}, // the final choice here - &toStringConverter{}, + return +} - &toFuncConverter{}, - &fromFuncConverter{}, +func mustParseDuration(s string) (dur time.Duration) { + dur, _ = time.ParseDuration(s) + return +} - &toDurationConverter{}, - &fromDurationConverter{}, - &toTimeConverter{}, - &fromTimeConverter{}, +func zsToDurationS[T Integers | Uintegers](z []T) (ret []time.Duration) { + ret = make([]time.Duration, 0, len(z)) + for _, it := range z { + ret = append(ret, time.Duration(int64(it))) + } + return +} - &fromBytesBufferConverter{}, - &fromSyncPkgConverter{}, - &fromMapConverter{}, +func (s *Cvt) DurationMap(data any) map[string]time.Duration { return anyToDurationMap(data) } + +func anyToDurationMap(data any) (ret map[string]time.Duration) { + if data == nil { + return } - lenValueConverters = len(defValueConverters) - lenValueCopiers = len(defValueCopiers) + switch z := data.(type) { + case map[string]time.Duration: + return z + case map[string]string: + ret = make(map[string]time.Duration, len(z)) + for k, v := range z { + ret[k] = mustParseDuration(v) + } + return + case map[string]fmt.Stringer: + ret = make(map[string]time.Duration, len(z)) + for k, v := range z { + ret[k] = mustParseDuration(v.String()) + } + return + case map[string]any: + ret = make(map[string]time.Duration, len(z)) + for k, v := range z { + ret[k] = anyToDuration(v) + } + return + + default: + break + } + return } -var defValueConverters ValueConverters //nolint:gochecknoglobals //i know that -var defValueCopiers ValueCopiers //nolint:gochecknoglobals //i know that -var lenValueConverters, lenValueCopiers int //nolint:gochecknoglobals //i know that +// -func defaultValueConverters() ValueConverters { return defValueConverters } -func defaultValueCopiers() ValueCopiers { return defValueCopiers } +func (s *Cvt) Time(data any) time.Time { return anyToTime(data) } -// ValueConverter for internal used. -type ValueConverter interface { - Transform(ctx *ValueConverterContext, source reflect.Value, targetType reflect.Type) (target reflect.Value, err error) - Match(params *Params, source, target reflect.Type) (ctx *ValueConverterContext, yes bool) +func anyToTime(data any) (tm time.Time) { + if data == nil { + return + } + + switch z := data.(type) { + case time.Time: + return z + case *time.Time: + return *z + + case int: + return time.Unix(int64(z), 0) + case int64: + return time.Unix(int64(z), 0) + case int32: + return time.Unix(int64(z), 0) + case int16: + return time.Unix(int64(z), 0) + case int8: + return time.Unix(int64(z), 0) + case uint: + return time.Unix(int64(z), 0) + case uint64: + return time.Unix(int64(z), 0) + case uint32: + return time.Unix(int64(z), 0) + case uint16: + return time.Unix(int64(z), 0) + case uint8: + return time.Unix(int64(z), 0) + + case string: + return mustSmartParseTime(z) + case fmt.Stringer: + return mustSmartParseTime(z.String()) + + default: + str := fmt.Sprintf("%v", data) + return mustSmartParseTime(str) + } } -// ValueCopier for internal used. -type ValueCopier interface { - CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) - Match(params *Params, source, target reflect.Type) (ctx *ValueConverterContext, yes bool) +// mustSmartParseTime parses a formatted string and returns the time value it represents. +func mustSmartParseTime(str string) (tm time.Time) { + tm, _ = smartParseTime(str) + return } -// NameConverter for internal used. -type NameConverter interface { - ToGoName(ctx *NameConverterContext, fieldName string) (goName string) - ToFieldName(ctx *NameConverterContext, goName string) (fieldName string) +func smartParseTime(str string) (tm time.Time, err error) { + for _, layout := range onceInitTimeFormats() { + if tm, err = time.Parse(layout, str); err == nil { + break + } + } + return } -// ValueConverters for internal used. -type ValueConverters []ValueConverter +var knownDateTimeFormats []string +var onceFormats sync.Once + +func onceInitTimeFormats() []string { + onceFormats.Do(func() { + knownDateTimeFormats = []string{ + "2006-01-02 15:04:05.999999999 -0700", + "2006-01-02 15:04:05.999999999Z07:00", + "2006-01-02 15:04:05.999999999", + "2006-01-02 15:04:05.999", + "2006-01-02 15:04:05", + "2006-01-02", + "2006/01/02", + "01/02/2006", + "01-02", + + "2006-1-2 15:4:5.999999999 -0700", + "2006-1-2 15:4:5.999999999Z07:00", + "2006-1-2 15:4:5.999999999", + "2006-1-2 15:4:5.999", + "2006-1-2 15:4:5", + "2006-1-2", + "2006/1/2", + "1/2/2006", + "1-2", + + "15:04:05.999999999", + "15:04.999999999", + "15:04:05.999", + "15:04.999", + "15:04:05", + "15:04", + + "15:4:5.999999999", + "15:4.999999999", + "15:4:5.999", + "15:4.999", + "15:4:5", + "15:4", + + time.RFC3339, + time.RFC3339Nano, + time.RFC1123Z, + time.RFC1123, + time.RFC850, + time.RFC822Z, + time.RFC822, + time.RubyDate, + time.UnixDate, + time.ANSIC, + } + }) + return knownDateTimeFormats +} -// ValueCopiers for internal used. -type ValueCopiers []ValueCopier +func (s *Cvt) TimeSlice(data any) []time.Time { return anyToTimeSlice(data) } -// NameConverters for internal used. -type NameConverters []NameConverter +func anyToTimeSlice(data any) (ret []time.Time) { + if data == nil { + return + } -// NameConverterContext for internal used. -type NameConverterContext struct { - *Params + switch z := data.(type) { + case []time.Time: + return z + case []*time.Time: + break // todo convert []*time.Time to []time.Time? + + case []int: + return zsToTimeS(z) + case []int64: + return zsToTimeS(z) + case []int32: + return zsToTimeS(z) + case []int16: + return zsToTimeS(z) + case []int8: + return zsToTimeS(z) + case []uint: + return zsToTimeS(z) + case []uint64: + return zsToTimeS(z) + case []uint32: + return zsToTimeS(z) + case []uint16: + return zsToTimeS(z) + case []uint8: + return zsToTimeS(z) + + case []string: + ret = make([]time.Time, 0, len(z)) + for _, it := range z { + ret = append(ret, mustSmartParseTime(it)) + } + return + case []fmt.Stringer: + ret = make([]time.Time, 0, len(z)) + for _, it := range z { + ret = append(ret, mustSmartParseTime(it.String())) + } + return + + case []any: + ret = make([]time.Time, 0, len(z)) + for _, it := range z { + ret = append(ret, anyToTime(it)) + } + return + + default: + break + } + return } -// ValueConverterContext for internal used. -type ValueConverterContext struct { - *Params +func zsToTimeS[T Integers | Uintegers](z []T) (ret []time.Time) { + ret = make([]time.Time, 0, len(z)) + for _, it := range z { + ret = append(ret, time.Unix(int64(it), 0)) + } + return +} + +func (s *Cvt) TimeMap(data any) map[string]time.Time { return anyToTimeMap(data) } + +func anyToTimeMap(data any) (ret map[string]time.Time) { + if data == nil { + return + } + + switch z := data.(type) { + case map[string]time.Time: + return z + case map[string]string: + ret = make(map[string]time.Time, len(z)) + for k, v := range z { + ret[k] = mustSmartParseTime(v) + } + return + case map[string]fmt.Stringer: + ret = make(map[string]time.Time, len(z)) + for k, v := range z { + ret[k] = mustSmartParseTime(v.String()) + } + return + case map[string]any: + ret = make(map[string]time.Time, len(z)) + for k, v := range z { + ret[k] = anyToTime(v) + } + return + + default: + break + } + return } // +// + +// + +// + +// + //nolint:lll //no why func (valueConverters ValueConverters) findConverters(params *Params, from, to reflect.Type, userDefinedOnly bool) (converter ValueConverter, ctx *ValueConverterContext) { var yes bool @@ -283,8 +2294,8 @@ func (c *cvtbase) safeType(tgt, tgtptr reflect.Value) reflect.Type { } return tgtptr.Type().Elem() } - log.Panicf("niltyp !! CANNOT fetch type: tgt = %v, tgtptr = %v", tool.Typfmtv(&tgt), tool.Typfmtv(&tgtptr)) - return tool.Niltyp + logz.Panic("niltyp !! CANNOT fetch type:", "tgt", ref.Typfmtv(&tgt), "tgtptr", ref.Typfmtv(&tgtptr)) + return ref.Niltyp } // processUnexportedField try to set newval into target if it's an unexported field. @@ -305,11 +2316,11 @@ func (c *cvtbase) checkSource(ctx *ValueConverterContext, source reflect.Value, if processed = ctx.isGroupedFlagOKDeeply(cms.Ignore); processed { return } - if processed = tool.IsNil(source) && ctx.isGroupedFlagOKDeeply(cms.OmitIfNil, cms.OmitIfEmpty); processed { + if processed = ref.IsNil(source) && ctx.isGroupedFlagOKDeeply(cms.OmitIfNil, cms.OmitIfEmpty); processed { target = reflect.Zero(targetType) return } - if processed = tool.IsZero(source) && ctx.isGroupedFlagOKDeeply(cms.OmitIfZero, cms.OmitIfEmpty); processed { + if processed = ref.IsZero(source) && ctx.isGroupedFlagOKDeeply(cms.OmitIfZero, cms.OmitIfEmpty); processed { target = reflect.Zero(targetType) } return @@ -317,13 +2328,32 @@ func (c *cvtbase) checkSource(ctx *ValueConverterContext, source reflect.Value, //nolint:lll //no why func (c *cvtbase) checkTarget(ctx *ValueConverterContext, target reflect.Value, targetType reflect.Type) (processed bool) { - if processed = !target.IsValid(); processed { + // if processed = !target.IsValid(); processed { + // return + // } + + if processed = c.checkTargetLite(ctx, target, targetType); processed { + return + } + + if processed = !ref.IsValid(target); processed { return } - if processed = tool.IsNil(target) && ctx.isGroupedFlagOKDeeply(cms.OmitIfTargetNil); processed { + + return +} + +//nolint:lll //no why +func (c *cvtbase) checkTargetLite(ctx *ValueConverterContext, target reflect.Value, targetType reflect.Type) (processed bool) { + // if processed = !target.IsValid(); processed { + // return + // } + + if processed = ref.IsNil(target) && ctx.isGroupedFlagOKDeeply(cms.OmitIfTargetNil); processed { return } - processed = tool.IsZero(target) && ctx.isGroupedFlagOKDeeply(cms.OmitIfTargetZero) + processed = ref.IsZero(target) && ctx.isGroupedFlagOKDeeply(cms.OmitIfTargetZero) + return } @@ -333,7 +2363,7 @@ type toConverterBase struct{ cvtbase } func (c *toConverterBase) fallback(target reflect.Value) (err error) { tgtType := reflect.TypeOf((*time.Duration)(nil)).Elem() - tool.Rindirect(target).Set(reflect.Zero(tgtType)) + ref.Rindirect(target).Set(reflect.Zero(tgtType)) return } @@ -394,10 +2424,10 @@ func (c *fromConverterBase) postCopyTo(ctx *ValueConverterContext, source, targe nv, err = c.convertToOrZeroTarget(ctx, source, target.Type()) if err == nil { if target.CanSet() { - dbglog.Log(" postCopyTo: set nv(%v) into target (%v)", tool.Valfmt(&nv), tool.Valfmt(&target)) + dbglog.Log(" postCopyTo: set nv(%v) into target (%v)", ref.Valfmt(&nv), ref.Valfmt(&target)) target.Set(nv) } else { - err = ErrCannotSet.FormatWith(tool.Valfmt(&target), tool.Typfmtv(&target), tool.Valfmt(&nv), tool.Typfmtv(&nv)) + err = ErrCannotSet.FormatWith(ref.Valfmt(&target), ref.Typfmtv(&target), ref.Valfmt(&nv), ref.Typfmtv(&nv)) } } return @@ -405,7 +2435,7 @@ func (c *fromConverterBase) postCopyTo(ctx *ValueConverterContext, source, targe func (c *fromConverterBase) convertToOrZeroTarget(ctx *ValueConverterContext, source reflect.Value, targetType reflect.Type) (target reflect.Value, err error) { - if tool.CanConvert(&source, targetType) { + if ref.CanConvert(&source, targetType) { nv := source.Convert(targetType) target = nv } else if ctx.isGroupedFlagOKDeeply(cms.ClearIfInvalid) { @@ -424,7 +2454,7 @@ type toStringConverter struct{ toConverterBase } func (c *toStringConverter) postCopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) { if source.IsValid() { - if tool.CanConvert(&source, target.Type()) { + if ref.CanConvert(&source, target.Type()) { nv := source.Convert(target.Type()) if c.processUnexportedField(ctx, target, nv) { return @@ -447,13 +2477,13 @@ func (c *toStringConverter) postCopyTo(ctx *ValueConverterContext, source, targe } func (c *toStringConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) { - tgt, tgtptr := tool.Rdecode(target) + tgt, tgtptr := ref.Rdecode(target) tgtType := c.safeType(tgt, tgtptr) // because tgt might be invalid, so we fetch tgt type via its pointer dbglog.Log(" target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v", - tool.Typfmtv(&target), tool.Typfmt(target.Type()), tool.Typfmtv(&tgtptr), - tool.Typfmtv(&tgt), tool.Typfmt(tgtType)) + ref.Typfmtv(&target), ref.Typfmt(target.Type()), ref.Typfmtv(&tgtptr), + ref.Typfmtv(&tgt), ref.Typfmt(tgtType)) - if processed := c.checkTarget(ctx, tgt, tgtType); processed { + if processed := c.checkTargetLite(ctx, tgt, tgtType); processed { return } @@ -461,7 +2491,7 @@ func (c *toStringConverter) CopyTo(ctx *ValueConverterContext, source, target re if c.processUnexportedField(ctx, target, ret) { return } - dbglog.Log(" set: %v (%v) <- %v", tool.Valfmt(&target), tool.Typfmtv(&target), tool.Valfmt(&ret)) + dbglog.Log(" set: %v (%v) <- %v", ref.Valfmt(&target), ref.Typfmtv(&target), ref.Valfmt(&ret)) tgtptr.Set(ret) } else { err = c.postCopyTo(ctx, source, target) @@ -574,13 +2604,13 @@ func tryMarshalling(source reflect.Value) (str string, processed bool, err error type fromStringConverter struct{ fromConverterBase } func (c *fromStringConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) { - tgt, tgtptr := tool.Rdecode(target) + tgt, tgtptr := ref.Rdecode(target) tgttyp := c.safeType(tgt, tgtptr) // because tgt might be invalid, so we fetch tgt type via its pointer dbglog.Log(" target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v", - tool.Typfmtv(&target), tool.Typfmt(target.Type()), tool.Typfmtv(&tgtptr), - tool.Typfmtv(&tgt), tool.Typfmt(tgttyp)) + ref.Typfmtv(&target), ref.Typfmt(target.Type()), ref.Typfmtv(&tgtptr), + ref.Typfmtv(&tgt), ref.Typfmt(tgttyp)) - if processed := c.checkTarget(ctx, tgt, tgttyp); processed { + if processed := c.checkTargetLite(ctx, tgt, tgttyp); processed { // target.Set(ret) return } @@ -595,9 +2625,9 @@ func (c *fromStringConverter) CopyTo(ctx *ValueConverterContext, source, target } else if tgt.CanSet() { tgt.Set(ret) } else { - err = ErrCannotSet.FormatWith(tool.Valfmt(&tgt), tool.Typfmtv(&tgt), tool.Valfmt(&ret), tool.Typfmtv(&ret)) + err = ErrCannotSet.FormatWith(ref.Valfmt(&tgt), ref.Typfmtv(&tgt), ref.Valfmt(&ret), ref.Typfmtv(&ret)) } - dbglog.Log(" tgt / ret transformed: %v / %v", tool.Valfmt(&tgt), tool.Valfmt(&ret)) + dbglog.Log(" tgt / ret transformed: %v / %v", ref.Valfmt(&tgt), ref.Valfmt(&ret)) return } @@ -683,13 +2713,13 @@ func (c *fromStringConverter) Match(params *Params, source, target reflect.Type) type fromMapConverter struct{ fromConverterBase } func (c *fromMapConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) { - tgt, tgtptr := tool.Rdecode(target) + tgt, tgtptr := ref.Rdecode(target) tgttyp := c.safeType(tgt, tgtptr) // because tgt might be invalid, so we fetch tgt type via its pointer dbglog.Log(" target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v", - tool.Typfmtv(&target), tool.Typfmt(target.Type()), tool.Typfmtv(&tgtptr), - tool.Typfmtv(&tgt), tool.Typfmt(tgttyp)) + ref.Typfmtv(&target), ref.Typfmt(target.Type()), ref.Typfmtv(&tgtptr), + ref.Typfmtv(&tgt), ref.Typfmt(tgttyp)) - if processed := c.checkTarget(ctx, tgt, tgttyp); processed { + if processed := c.checkTargetLite(ctx, tgt, tgttyp); processed { // target.Set(ret) return } @@ -716,9 +2746,9 @@ func (c *fromMapConverter) CopyTo(ctx *ValueConverterContext, source, target ref } else if tgt.CanSet() { tgt.Set(ret) } else { - err = ErrCannotSet.FormatWith(tool.Valfmt(&tgt), tool.Typfmtv(&tgt), tool.Valfmt(&ret), tool.Typfmtv(&ret)) + err = ErrCannotSet.FormatWith(ref.Valfmt(&tgt), ref.Typfmtv(&tgt), ref.Valfmt(&ret), ref.Typfmtv(&ret)) } - dbglog.Log(" tgt: %v (ret = %v)", tool.Valfmt(&tgt), tool.Valfmt(&ret)) + dbglog.Log(" tgt: %v (ret = %v)", ref.Valfmt(&tgt), ref.Valfmt(&ret)) } else if !errors.Is(e, strconv.ErrSyntax) && !errors.Is(e, strconv.ErrRange) { dbglog.Log(" Transform() failed: %v", e) dbglog.Log(" try running postCopyTo()") @@ -789,18 +2819,18 @@ func (c *fromMapConverter) toStructDirectly(ctx *ValueConverterContext, source, } // convert map key to string type - key, err = rToString(key, tool.StringType) + key, err = rToString(key, ref.StringType) if err != nil { continue // ignore non-string key } ks := key.String() - dbglog.Log(" key %q, src: %v (%v)", ks, tool.Valfmt(&src), tool.Typfmtv(&src)) + dbglog.Log(" key %q, src: %v (%v)", ks, ref.Valfmt(&src), ref.Typfmtv(&src)) if cc.targetSetter != nil { newtyp := src.Type() val := reflect.New(newtyp).Elem() err = ctx.controller.copyTo(ctx.Params, src, val) - dbglog.Log(" nv.%q: %v (%v) ", ks, tool.Valfmt(&val), tool.Typfmtv(&val)) + dbglog.Log(" nv.%q: %v (%v) ", ks, ref.Valfmt(&val), ref.Typfmtv(&val)) var processed bool if processed, err = preSetter(val, ks); err != nil || processed { ec.Attach(err) @@ -842,18 +2872,18 @@ func (c *fromMapConverter) toStruct(ctx *ValueConverterContext, source reflect.V } // convert map key to string type - key, err = rToString(key, tool.StringType) + key, err = rToString(key, ref.StringType) if err != nil { continue // ignore non-string key } ks := key.String() - dbglog.Log(" key %q, src: %v (%v)", ks, tool.Valfmt(&src), tool.Typfmtv(&src)) + dbglog.Log(" key %q, src: %v (%v)", ks, ref.Valfmt(&src), ref.Typfmtv(&src)) if cc.targetSetter != nil { newtyp := src.Type() val := reflect.New(newtyp).Elem() err = ctx.controller.copyTo(ctx.Params, src, val) - dbglog.Log(" nv.%q: %v (%v) ", ks, tool.Valfmt(&val), tool.Typfmtv(&val)) + dbglog.Log(" nv.%q: %v (%v) ", ks, ref.Valfmt(&val), ref.Typfmtv(&val)) var processed bool if processed, err = preSetter(val, ks); err != nil || processed { ec.Attach(err) @@ -875,7 +2905,7 @@ func (c *fromMapConverter) toStruct(ctx *ValueConverterContext, source reflect.V // tsft = tsft.Elem() fld = fld.Elem() } else if tsfk == reflect.Ptr { - dbglog.Log(" fld.%q: %v (%v)", ks, tool.Valfmt(&fld), tool.Typfmtv(&fld)) + dbglog.Log(" fld.%q: %v (%v)", ks, ref.Valfmt(&fld), ref.Typfmtv(&fld)) if fld.IsNil() { n := reflect.New(fld.Type().Elem()) target.FieldByName(ks).Set(n) @@ -883,11 +2913,11 @@ func (c *fromMapConverter) toStruct(ctx *ValueConverterContext, source reflect.V } // tsft = tsft.Elem() fld = fld.Elem() - dbglog.Log(" fld.%q: %v (%v)", ks, tool.Valfmt(&fld), tool.Typfmtv(&fld)) + dbglog.Log(" fld.%q: %v (%v)", ks, ref.Valfmt(&fld), ref.Typfmtv(&fld)) } err = ctx.controller.copyTo(ctx.Params, src, fld) - dbglog.Log(" nv.%q: %v (%v) ", ks, tool.Valfmt(&fld), tool.Typfmtv(&fld)) + dbglog.Log(" nv.%q: %v (%v) ", ks, ref.Valfmt(&fld), ref.Typfmtv(&fld)) ec.Attach(err) // var nv reflect.Value @@ -906,7 +2936,7 @@ func (c *fromMapConverter) toStruct(ctx *ValueConverterContext, source reflect.V // } // } } - dbglog.Log(" target: %v (%v) ", tool.Valfmt(&target), tool.Typfmtv(&target)) + dbglog.Log(" target: %v (%v) ", ref.Valfmt(&target), ref.Typfmtv(&target)) return } @@ -954,12 +2984,12 @@ func (c *fromSyncPkgConverter) Transform(ctx *ValueConverterContext, source refl type fromBytesBufferConverter struct{ fromConverterBase } func (c *fromBytesBufferConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) { - tgt, tgtptr := tool.Rdecode(target) + tgt, tgtptr := ref.Rdecode(target) tgtType := c.safeType(tgt, tgtptr) // because tgt might be invalid, so we fetch tgt type via its pointer // tgtType := target.Type() dbglog.Log(" target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v", - tool.Typfmtv(&target), tool.Typfmt(target.Type()), - tool.Typfmtv(&tgtptr), tool.Typfmtv(&tgt), tool.Typfmt(tgtType)) + ref.Typfmtv(&target), ref.Typfmt(target.Type()), + ref.Typfmtv(&tgtptr), ref.Typfmtv(&tgt), ref.Typfmt(tgtType)) if processed := c.checkTarget(ctx, tgt, tgtType); processed { // target.Set(ret) @@ -1022,13 +3052,13 @@ func (c *fromBytesBufferConverter) Match(params *Params, source, target reflect. type fromTimeConverter struct{ fromConverterBase } func (c *fromTimeConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) { - tgt, tgtptr := tool.Rdecode(target) + tgt, tgtptr := ref.Rdecode(target) tgtType := c.safeType(tgt, tgtptr) // because tgt might be invalid, so we fetch tgt type via its pointer dbglog.Log(" target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v", - tool.Typfmtv(&target), tool.Typfmt(target.Type()), tool.Typfmtv(&tgtptr), - tool.Typfmtv(&tgt), tool.Typfmt(tgtType)) + ref.Typfmtv(&target), ref.Typfmt(target.Type()), ref.Typfmtv(&tgtptr), + ref.Typfmtv(&tgt), ref.Typfmt(tgtType)) - if processed := c.checkTarget(ctx, tgt, tgtType); processed { + if processed := c.checkTargetLite(ctx, tgt, tgtType); processed { // tgtptr.Set(ret) return } @@ -1043,9 +3073,9 @@ func (c *fromTimeConverter) CopyTo(ctx *ValueConverterContext, source, target re } else if tgt.CanSet() { tgt.Set(ret) } else { - err = ErrCannotSet.FormatWith(tool.Valfmt(&tgt), tool.Typfmtv(&tgt), tool.Valfmt(&ret), tool.Typfmtv(&ret)) + err = ErrCannotSet.FormatWith(ref.Valfmt(&tgt), ref.Typfmtv(&tgt), ref.Valfmt(&ret), ref.Typfmtv(&ret)) } - dbglog.Log(" tgt: %v (ret = %v)", tool.Valfmt(&tgt), tool.Valfmt(&ret)) + dbglog.Log(" tgt: %v (ret = %v)", ref.Valfmt(&tgt), ref.Valfmt(&ret)) return } @@ -1065,7 +3095,7 @@ func (c *fromTimeConverter) Transform(ctx *ValueConverterContext, source reflect switch k := targetType.Kind(); k { //nolint:exhaustive //no need case reflect.Bool: - b := tool.IsNil(source) || tool.IsZero(source) + b := ref.IsNil(source) || ref.IsZero(source) target = reflect.ValueOf(b) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: tm := source.Interface().(time.Time) //nolint:errcheck //no need @@ -1162,13 +3192,13 @@ type toTimeConverter struct{ toConverterBase } func (c *toTimeConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) { // tgtType := target.Type() - tgt, tgtptr := tool.Rdecode(target) + tgt, tgtptr := ref.Rdecode(target) tgtType := c.safeType(tgt, tgtptr) // because tgt might be invalid, so we fetch tgt type via its pointer dbglog.Log(" target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v", - tool.Typfmtv(&target), tool.Typfmt(target.Type()), tool.Typfmtv(&tgtptr), - tool.Typfmtv(&tgt), tool.Typfmt(tgtType)) + ref.Typfmtv(&target), ref.Typfmt(target.Type()), ref.Typfmtv(&tgtptr), + ref.Typfmtv(&tgt), ref.Typfmt(tgtType)) - if processed := c.checkTarget(ctx, tgt, tgtType); processed { + if processed := c.checkTargetLite(ctx, tgt, tgtType); processed { // target.Set(ret) return } @@ -1222,12 +3252,12 @@ func (c *toTimeConverter) Transform(ctx *ValueConverterContext, source reflect.V target = reflect.ValueOf(tm) default: - err = ErrCannotConvertTo.FormatWith(source, tool.Typfmtv(&source), targetType, targetType.Kind()) + err = ErrCannotConvertTo.FormatWith(source, ref.Typfmtv(&source), targetType, targetType.Kind()) } } else if ctx.isGroupedFlagOKDeeply(cms.ClearIfInvalid) { target = reflect.Zero(targetType) } else { - err = errors.New("source (%v) is invalid", tool.Valfmt(&source)) + err = errors.New("source (%v) is invalid", ref.Valfmt(&source)) } return } @@ -1250,11 +3280,11 @@ func (c *toTimeConverter) Match(params *Params, source, target reflect.Type) (ct type fromDurationConverter struct{ fromConverterBase } func (c *fromDurationConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) { - tgt, tgtptr := tool.Rdecode(target) + tgt, tgtptr := ref.Rdecode(target) tgttyp := c.safeType(tgt, tgtptr) // because tgt might be invalid, so we fetch tgt type via its pointer dbglog.Log(" target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v", - tool.Typfmtv(&target), tool.Typfmt(target.Type()), tool.Typfmtv(&tgtptr), - tool.Typfmtv(&tgt), tool.Typfmt(tgttyp)) + ref.Typfmtv(&target), ref.Typfmt(target.Type()), ref.Typfmtv(&tgtptr), + ref.Typfmtv(&tgt), ref.Typfmt(tgttyp)) var processed bool if target, processed = c.checkSource(ctx, source, tgttyp); processed { @@ -1271,9 +3301,9 @@ func (c *fromDurationConverter) CopyTo(ctx *ValueConverterContext, source, targe } else if tgt.CanSet() { tgt.Set(ret) } else { - err = ErrCannotSet.FormatWith(tool.Valfmt(&tgt), tool.Typfmtv(&tgt), tool.Valfmt(&ret), tool.Typfmtv(&ret)) + err = ErrCannotSet.FormatWith(ref.Valfmt(&tgt), ref.Typfmtv(&tgt), ref.Valfmt(&ret), ref.Typfmtv(&ret)) } - dbglog.Log(" tgt: %v (ret = %v)", tool.Valfmt(&tgt), tool.Valfmt(&ret)) + dbglog.Log(" tgt: %v (ret = %v)", ref.Valfmt(&tgt), ref.Valfmt(&ret)) return } @@ -1358,13 +3388,13 @@ type toDurationConverter struct{ toConverterBase } func (c *toDurationConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) { // tgtType := target.Type() - tgt, tgtptr := tool.Rdecode(target) + tgt, tgtptr := ref.Rdecode(target) tgtType := c.safeType(tgt, tgtptr) // because tgt might be invalid, so we fetch tgt type via its pointer dbglog.Log(" target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v", - tool.Typfmtv(&target), tool.Typfmt(target.Type()), tool.Typfmtv(&tgtptr), - tool.Typfmtv(&tgt), tool.Typfmt(tgtType)) + ref.Typfmtv(&target), ref.Typfmt(target.Type()), ref.Typfmtv(&tgtptr), + ref.Typfmtv(&tgt), ref.Typfmt(tgtType)) - if processed := c.checkTarget(ctx, tgt, tgtType); processed { + if processed := c.checkTargetLite(ctx, tgt, tgtType); processed { // tgtptr.Set(ret) return } @@ -1427,12 +3457,12 @@ func (c *toDurationConverter) Transform(ctx *ValueConverterContext, source refle // reflect.Struct default: - err = ErrCannotConvertTo.FormatWith(source, tool.Typfmtv(&source), targetType, targetType.Kind()) + err = ErrCannotConvertTo.FormatWith(source, ref.Typfmtv(&source), targetType, targetType.Kind()) } } else if ctx.isGroupedFlagOKDeeply(cms.ClearIfInvalid) { target = reflect.Zero(targetType) } else { - err = errors.New("source (%v) is invalid", tool.Valfmt(&source)) + err = errors.New("source (%v) is invalid", ref.Valfmt(&source)) } return } @@ -1468,7 +3498,7 @@ func copyToFuncImpl(controller *cpController, source, target reflect.Value, targ res := target.Call(args) if len(res) > 0 { last := res[len(res)-1] - if tool.Iserrortype(targetType.Out(len(res)-1)) && !tool.IsNil(last) { + if ref.Iserrortype(targetType.Out(len(res)-1)) && !ref.IsNil(last) { err = last.Interface().(error) //nolint:errcheck //no need } } @@ -1493,7 +3523,7 @@ func (c *toFuncConverter) copyTo(ctx *ValueConverterContext, source, src, tgt, t } tgttyp := tgt.Type() - dbglog.Log(" copyTo: src: %v, tgt: %v,", tool.Typfmtv(&src), tool.Typfmt(tgttyp)) + dbglog.Log(" copyTo: src: %v, tgt: %v,", ref.Typfmtv(&src), ref.Typfmt(tgttyp)) if k := src.Kind(); k != reflect.Func && ctx.IsPassSourceToTargetFunction() { var controller *cpController @@ -1511,15 +3541,15 @@ func (c *toFuncConverter) copyTo(ctx *ValueConverterContext, source, src, tgt, t } func (c *toFuncConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) { - src := tool.Rdecodesimple(source) - tgt, tgtptr := tool.Rdecode(target) + src := ref.Rdecodesimple(source) + tgt, tgtptr := ref.Rdecode(target) tgtType := c.safeType(tgt, tgtptr) // because tgt might be invalid, so we fetch tgt type via its pointer // Log(" CopyTo: src: %v, tgt: %v,", typfmtv(&src), typfmt(tgtType)) dbglog.Log(" target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v", - tool.Typfmtv(&target), tool.Typfmt(target.Type()), tool.Typfmtv(&tgtptr), - tool.Typfmtv(&tgt), tool.Typfmt(tgtType)) + ref.Typfmtv(&target), ref.Typfmt(target.Type()), ref.Typfmtv(&tgtptr), + ref.Typfmtv(&tgt), ref.Typfmt(tgtType)) - if processed := c.checkTarget(ctx, tgt, tgtType); processed { + if processed := c.checkTargetLite(ctx, tgt, tgtType); processed { // tgtptr.Set(ret) return } @@ -1567,15 +3597,15 @@ func (c *fromFuncConverter) CopyTo(ctx *ValueConverterContext, source, target re // // in this case, tsetter represents 'a' and tgt represents // // 'decoded bool(a)'. // - src := tool.Rdecodesimple(source) - tgt, tgtptr := tool.Rdecode(target) + src := ref.Rdecodesimple(source) + tgt, tgtptr := ref.Rdecode(target) tgtType := c.safeType(tgt, tgtptr) // dbglog.Log(" CopyTo: src: %v, tgt: %v, tsetter: %v", typfmtv(&src), typfmt(tgttyp), typfmtv(&tsetter)) dbglog.Log(" target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v", - tool.Typfmtv(&target), tool.Typfmt(target.Type()), tool.Typfmtv(&tgtptr), - tool.Typfmtv(&tgt), tool.Typfmt(tgtType)) + ref.Typfmtv(&target), ref.Typfmt(target.Type()), ref.Typfmtv(&tgtptr), + ref.Typfmtv(&tgt), ref.Typfmt(tgtType)) - if processed := c.checkTarget(ctx, tgt, tgtType); processed { + if processed := c.checkTargetLite(ctx, tgt, tgtType); processed { // target.Set(ret) return } @@ -1621,7 +3651,7 @@ func (c *fromFuncConverter) funcResultToTarget(ctx *ValueConverterContext, sourc results := srcResults lastoutargtype := sourceType.Out(sourceType.NumOut() - 1) - ok = tool.Iserrortype(lastoutargtype) + ok = ref.Iserrortype(lastoutargtype) if ok { v := results[len(results)-1].Interface() err, _ = v.(error) diff --git a/cvts_tool.go b/cvts_tool.go index a5a429b..8af3e0e 100644 --- a/cvts_tool.go +++ b/cvts_tool.go @@ -7,11 +7,12 @@ import ( "reflect" "strconv" "strings" + "time" "github.com/hedzr/evendeep/dbglog" "github.com/hedzr/evendeep/internal/cl" "github.com/hedzr/evendeep/internal/syscalls" - "github.com/hedzr/evendeep/internal/tool" + "github.com/hedzr/evendeep/ref" "gopkg.in/hedzr/errors.v3" ) @@ -27,7 +28,7 @@ func rForBool(v reflect.Value) (ret reflect.Value) { func rToBool(v reflect.Value) (ret reflect.Value) { var b bool - if !v.IsValid() || tool.IsNil(v) || tool.IsZero(v) { + if !v.IsValid() || ref.IsNil(v) || ref.IsZero(v) { return reflect.ValueOf(b) } @@ -45,11 +46,11 @@ func rToBool(v reflect.Value) (ret reflect.Value) { c := v.Complex() b = math.Float64bits(real(c)) != 0 || math.Float64bits(imag(c)) != 0 case reflect.Array: - b = !tool.ArrayIsZero(v) + b = !ref.ArrayIsZero(v) case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer: - b = !tool.IsNil(v) + b = !ref.IsNil(v) case reflect.Struct: - b = !tool.StructIsZero(v) + b = !ref.StructIsZero(v) case reflect.String: b = internalToBool(v.String()) } @@ -72,7 +73,7 @@ func rForInteger(v reflect.Value) (ret reflect.Value) { if !v.IsValid() { v = reflect.Zero(int64typ) } else if k := v.Kind(); k < reflect.Int || k > reflect.Int64 { - if tool.CanConvert(&v, int64typ) { + if ref.CanConvert(&v, int64typ) { v = v.Convert(int64typ) } else { v = reflect.Zero(int64typ) @@ -130,7 +131,7 @@ func rForUInteger(v reflect.Value) (ret reflect.Value) { if !v.IsValid() { v = reflect.Zero(uint64typ) } else if k := v.Kind(); k < reflect.Uint || k > reflect.Uintptr { - if tool.CanConvert(&v, uint64typ) { + if ref.CanConvert(&v, uint64typ) { v = v.Convert(uint64typ) } else { v = reflect.Zero(uint64typ) @@ -214,7 +215,7 @@ func rForFloat(v reflect.Value) (ret reflect.Value) { if !v.IsValid() { v = reflect.Zero(float64typ) } else if k := v.Kind(); k < reflect.Float32 || k > reflect.Float64 { - if tool.CanConvert(&v, float64typ) { + if ref.CanConvert(&v, float64typ) { v = v.Convert(float64typ) } else { v = reflect.Zero(float64typ) @@ -326,12 +327,12 @@ func rToComplex(v reflect.Value, desiredType reflect.Type) (ret reflect.Value, e func toTypeConverter(v reflect.Value, desiredType reflect.Type, base int, converter func(str string, base int, bitSize int) (ret reflect.Value, err error), ) (ret reflect.Value, err error) { - if !v.IsValid() || tool.IsNil(v) || tool.IsZero(v) { + if !v.IsValid() || ref.IsNil(v) || ref.IsZero(v) { ret = reflect.Zero(desiredType) return } - if tool.CanConvert(&v, desiredType) { + if ref.CanConvert(&v, desiredType) { ret = v.Convert(desiredType) return } @@ -365,7 +366,7 @@ func tryStringerIt(source reflect.Value, desiredType reflect.Type) (target refle return } - if tool.CanConvert(&source, desiredType) { + if ref.CanConvert(&source, desiredType) { nv := source.Convert(desiredType) // target.Set(nv) target = nv @@ -422,7 +423,7 @@ func rToString(source reflect.Value, desiredType reflect.Type) (target reflect.V target, _, err = tryStringerIt(source, desiredType) } } else { - target = reflect.Zero(tool.StringType) + target = reflect.Zero(ref.StringType) } return } @@ -430,7 +431,7 @@ func rToString(source reflect.Value, desiredType reflect.Type) (target reflect.V //nolint:unused,deadcode,lll //reserved func rToArray(ctx *ValueConverterContext, sources reflect.Value, desiredType reflect.Type, targetLength int) (target reflect.Value, err error) { eltyp := desiredType.Elem() // length := desiredType.Len() - dbglog.Log(" desiredType: %v, el.type: %v", tool.Typfmt(desiredType), tool.Typfmt(eltyp)) + dbglog.Log(" desiredType: %v, el.type: %v", ref.Typfmt(desiredType), ref.Typfmt(eltyp)) count, length := sources.Len(), targetLength if length <= 0 { @@ -458,7 +459,7 @@ func rToArray(ctx *ValueConverterContext, sources reflect.Value, desiredType ref //nolint:unused,deadcode,lll //reserved func rToSlice(ctx *ValueConverterContext, sources reflect.Value, desiredType reflect.Type, targetLength int) (target reflect.Value, err error) { eltyp := desiredType.Elem() // length := desiredType.Len() - dbglog.Log(" desiredType: %v, el.type: %v", tool.Typfmt(desiredType), tool.Typfmt(eltyp)) + dbglog.Log(" desiredType: %v, el.type: %v", ref.Typfmt(desiredType), ref.Typfmt(eltyp)) count, length := sources.Len(), targetLength if length <= 0 { @@ -532,7 +533,7 @@ func rSetMapValue(ix int, target, key, srcVal reflect.Value, sTyp, dTyp reflect. } else { dstval := target.MapIndex(key) err = errors.New("cannot set map[%v] since transforming/converting failed: %v -> %v", - tool.Valfmt(&key), tool.Valfmt(&srcVal), tool.Valfmt(&dstval)) + ref.Valfmt(&key), ref.Valfmt(&srcVal), ref.Valfmt(&dstval)) } return } @@ -564,3 +565,235 @@ func rToStruct(ctx *ValueConverterContext, source reflect.Value, fromFuncType, d func rToFunc(ctx *ValueConverterContext, source reflect.Value, fromFuncType, desiredType reflect.Type) (target reflect.Value, err error) { return } + +// + +// + +// + +func intToString[T Integers](val T) string { + return intToStringEx(val, 10) +} + +func intToStringEx[T Integers](val T, base int) string { + return strconv.FormatInt(int64(val), base) +} + +func uintToString[T Uintegers](val T) string { + return uintToStringEx(val, 10) +} + +func uintToStringEx[T Uintegers](val T, base int) string { + return strconv.FormatUint(uint64(val), base) +} + +func floatToString[T Floats](val T) string { + return floatToStringEx(float64(val), 'f', -1, 64) +} + +func floatToStringEx[T Floats](val T, format byte, prec, bitSize int) string { + return strconv.FormatFloat(float64(val), format, prec, bitSize) +} + +func complexToString[T Complexes](val T) string { + return complexToStringEx(val, 'f', -1, 128) +} + +func complexToStringEx[T Complexes](val T, format byte, prec, bitSize int) string { + return strconv.FormatComplex(complex128(val), format, prec, bitSize) +} + +func boolToString(b bool) string { + return strconv.FormatBool(b) +} + +func timeToString(tm time.Time) string { + const layout = time.RFC3339Nano + return tm.Format(layout) +} + +func durationToString(dur time.Duration) string { + return dur.String() +} + +// + +func bytesToString(data []byte) string { + var b = make([]byte, 0, 3+len(data)*4) + b = append(b, data...) + b = append(b, []byte(" [")...) + for i := 0; i < len(data); { + if i > 0 { + b = append(b, ' ') + } + strconv.AppendInt(b, int64(data[i]), 16) + } + b = append(b, []byte("]")...) + return string(b) +} + +func intSliceToString[T Integers](val IntSlice[T]) string { + var b = make([]byte, 0, len(val)*8) // 8: assume integer need 8 runes + b = append(b, []byte("[")...) + for i := range val { + if i > 0 { + b = append(b, []byte(",")...) + } + b = strconv.AppendInt(b, int64(val[i]), 10) + } + b = append(b, []byte("]")...) + return string(b) +} + +func uintSliceToString[T Uintegers](val UintSlice[T]) string { + var b = make([]byte, 0, len(val)*8) // 8: assume unsigned integer need 8 runes + b = append(b, []byte("[")...) + for i := range val { + if i > 0 { + b = append(b, []byte(",")...) + } + b = strconv.AppendUint(b, uint64(val[i]), 10) + } + b = append(b, []byte("]")...) + return string(b) +} + +func floatSliceToString[T Floats](val FloatSlice[T]) string { + var b = make([]byte, 0, len(val)*16+2) // 8: assume floats need 16 runes + b = append(b, []byte("[")...) + for i := range val { + if i > 0 { + b = append(b, []byte(",")...) + } + b = strconv.AppendFloat(b, float64(val[i]), 'f', -1, 64) + } + b = append(b, []byte("]")...) + return string(b) +} + +func complexSliceToString[T Complexes](val ComplexSlice[T]) string { + var b = make([]byte, 0, len(val)*32+2) // 8: assume complex need 32 runes + b = append(b, []byte("[")...) + for i := range val { + if i > 0 { + b = append(b, []byte(",")...) + } + num := strconv.FormatComplex(complex128(val[i]), 'f', -1, 128) + b = append(b, []byte(num)...) + } + b = append(b, []byte("]")...) + return string(b) +} + +// func complexSliceToString[T Complexes](val ComplexSlice[T]) string { +// var b = make([]byte, 0, len(val)*32+2) // 8: assume complex need 32 runes +// b = append(b, []byte("[")...) +// for i := range val { +// if i > 0 { +// b = append(b, []byte(",")...) +// } +// b=strconv.AppendComplex(b, complex128(val[i]), 'f', -1, 128) +// } +// b = append(b, []byte("]")...) +// return string(b) +// } + +func stringSliceToString(val []string) string { + var b = make([]byte, 0, len(val)*32+2) // 8: assume integer need 32 runes + b = append(b, []byte("[")...) + for i := range val { + if i > 0 { + b = append(b, []byte(",")...) + } + b = strconv.AppendQuote(b, val[i]) + } + b = append(b, []byte("]")...) + return string(b) +} + +func boolSliceToString(val []bool) string { + var b = make([]byte, 0, len(val)*8) // 8: assume bool need 5 runes + b = append(b, []byte("[")...) + for i := range val { + if i > 0 { + b = append(b, []byte(",")...) + } + b = strconv.AppendBool(b, val[i]) + } + b = append(b, []byte("]")...) + return string(b) +} + +func timeSliceToString(val []time.Time) string { + var b = make([]byte, 0, len(val)*32+2) // 8: assume time need 24 runes + b = append(b, []byte("[")...) + for i := range val { + if i > 0 { + b = append(b, []byte(",")...) + } + b = strconv.AppendQuote(b, val[i].Format(time.RFC3339Nano)) + } + b = append(b, []byte("]")...) + return string(b) +} + +func durationSliceToString(val []time.Duration) string { + var b = make([]byte, 0, len(val)*16+2) // 8: assume duration need 16 runes + b = append(b, []byte("[")...) + for i := range val { + if i > 0 { + b = append(b, []byte(",")...) + } + b = strconv.AppendQuote(b, val[i].String()) + } + b = append(b, []byte("]")...) + return string(b) +} + +// + +type Stringer interface { + String() string +} + +type ToString interface { + ToString(args ...any) string +} + +type Integers interface { + int | int8 | int16 | int32 | int64 +} + +type Uintegers interface { + uint | uint8 | uint16 | uint32 | uint64 +} + +type Floats interface { + float32 | float64 +} + +type Complexes interface { + complex64 | complex128 +} + +type Numerics interface { + Integers | Uintegers | Floats | Complexes +} + +type IntSlice[T Integers] []T +type UintSlice[T Uintegers] []T +type FloatSlice[T Floats] []T +type ComplexSlice[T Complexes] []T +type StringSlice[T string] []T +type BoolSlice[T bool] []T + +type Slice[T Integers | Uintegers | Floats] []T + +// const ( +// TimeNoNano = "15:04:05Z07:00" +// TimeNano = "15:04:05.000000Z07:00" +// DateTime = "2006-01-0215:04:05Z07:00" +// RFC3339Nano = "2006-01-02T15:04:05.000000Z07:00" +// RFC3339NanoOrig = "2006-01-02T15:04:05.999999999Z07:00" +// ) diff --git a/cvts_tool_go113_test.go b/cvts_tool_go113_test.go index d2c68a3..15ba1a3 100644 --- a/cvts_tool_go113_test.go +++ b/cvts_tool_go113_test.go @@ -7,10 +7,10 @@ import ( "reflect" "testing" - "gopkg.in/hedzr/errors.v3" - "github.com/hedzr/evendeep/dbglog" - "github.com/hedzr/evendeep/internal/tool" + "github.com/hedzr/evendeep/ref" + + "gopkg.in/hedzr/errors.v3" ) func TestFromFuncConverterGo113AndHigher(t *testing.T) { @@ -80,9 +80,9 @@ func TestFromFuncConverterGo113AndHigher(t *testing.T) { if fnCase.fn != nil { //nolint:gocritic //nestingReduce: invert if cond, replace body with `continue`, move old body after the statement fnv := reflect.ValueOf(&fnCase.fn) tgtv := reflect.ValueOf(&fnCase.target) - ff, tt := tool.Rdecodesimple(fnv), tool.Rdecodesimple(tgtv) - dbglog.Log("---- CASE %d. %v -> %v", ix, tool.Typfmtv(&ff), tool.Typfmtv(&tt)) - t.Logf("---- CASE %d. %v -> %v", ix, tool.Typfmtv(&ff), tool.Typfmtv(&tt)) + ff, tt := ref.Rdecodesimple(fnv), ref.Rdecodesimple(tgtv) + dbglog.Log("---- CASE %d. %v -> %v", ix, ref.Typfmtv(&ff), ref.Typfmtv(&tt)) + t.Logf("---- CASE %d. %v -> %v", ix, ref.Typfmtv(&ff), ref.Typfmtv(&tt)) c := fromFuncConverter{} ctx := newValueConverterContextForTest(nil) diff --git a/cvts_tool_test.go b/cvts_tool_test.go index 5e03b07..f96c5ec 100644 --- a/cvts_tool_test.go +++ b/cvts_tool_test.go @@ -14,7 +14,7 @@ import ( "github.com/hedzr/evendeep/dbglog" "github.com/hedzr/evendeep/flags/cms" "github.com/hedzr/evendeep/internal/cl" - "github.com/hedzr/evendeep/internal/tool" + "github.com/hedzr/evendeep/ref" "github.com/hedzr/evendeep/typ" ) @@ -83,9 +83,9 @@ func TestToBool(t *testing.T) { "famale", } { v1 := reflect.ValueOf(vi) - v2, _ := tool.Rdecode(v1) + v2, _ := ref.Rdecode(v1) if rToBool(v2).Interface() != false { - t.Fatalf("for %v (%v) toBool failed", vi, tool.Typfmtv(&v2)) + t.Fatalf("for %v (%v) toBool failed", vi, ref.Typfmtv(&v2)) } } @@ -106,9 +106,9 @@ func TestToBool(t *testing.T) { "male", } { v1 := reflect.ValueOf(vi) - v2, _ := tool.Rdecode(v1) + v2, _ := ref.Rdecode(v1) if rToBool(v2).Interface() != true { - t.Fatalf("for %v (%v) toBool failed", vi, tool.Typfmtv(&v2)) + t.Fatalf("for %v (%v) toBool failed", vi, ref.Typfmtv(&v2)) } } @@ -120,7 +120,7 @@ func TestForInteger(t *testing.T) { uint(13579), } { v1 := reflect.ValueOf(src) - v1 = tool.Rdecodesimple(v1) + v1 = ref.Rdecodesimple(v1) if rForInteger(v1).Interface() != "13579" { t.Fail() } @@ -128,14 +128,14 @@ func TestForInteger(t *testing.T) { var z typ.Any v1 := reflect.ValueOf(z) - v1 = tool.Rdecodesimple(v1) + v1 = ref.Rdecodesimple(v1) if x := rForInteger(v1).Interface(); x != "0" { t.Fatalf("failed, x = %v", x) } z = "bug" //nolint:goconst v1 = reflect.ValueOf(z) - v1 = tool.Rdecodesimple(v1) + v1 = ref.Rdecodesimple(v1) if x := rForInteger(v1).Interface(); x != "0" { t.Fatalf("failed, x = %v", x) } @@ -174,7 +174,7 @@ func TestForUInteger(t *testing.T) { uint(13579), } { v1 := reflect.ValueOf(src) - v1 = tool.Rdecodesimple(v1) + v1 = ref.Rdecodesimple(v1) if rForUInteger(v1).Interface() != "13579" { t.Fail() } @@ -182,14 +182,14 @@ func TestForUInteger(t *testing.T) { var z typ.Any v1 := reflect.ValueOf(z) - v1 = tool.Rdecodesimple(v1) + v1 = ref.Rdecodesimple(v1) if x := rForUInteger(v1).Interface(); x != "0" { t.Fatalf("failed, x = %v", x) } z = "bug" v1 = reflect.ValueOf(z) - v1 = tool.Rdecodesimple(v1) + v1 = ref.Rdecodesimple(v1) if x := rForUInteger(v1).Interface(); x != "0" { t.Fatalf("failed, x = %v", x) } @@ -235,21 +235,21 @@ func TestForUIntegerHex(t *testing.T) { var z typ.Any v1 := reflect.ValueOf(z) - v1 = tool.Rdecodesimple(v1) + v1 = ref.Rdecodesimple(v1) if x := rForUInteger(v1).Interface(); x != "0" { t.Fatalf("failed, x = %v", x) } z = "bug" v1 = reflect.ValueOf(z) - v1 = tool.Rdecodesimple(v1) + v1 = ref.Rdecodesimple(v1) if x := rForUInteger(v1).Interface(); x != "0" { t.Fatalf("failed, x = %v", x) } z = "0x3e59" v1 = reflect.ValueOf(z) - v1 = tool.Rdecodesimple(v1) + v1 = ref.Rdecodesimple(v1) uintptrType := reflect.TypeOf(uintptr(0)) if x := uintptr(rToUIntegerHex(v1, uintptrType).Uint()); x != uintptr(0x3e59) { t.Fatalf("failed, x = %v", x) @@ -270,7 +270,7 @@ func TestForFloat(t *testing.T) { uint(13579), } { v1 := reflect.ValueOf(src) - v1 = tool.Rdecodesimple(v1) + v1 = ref.Rdecodesimple(v1) if rForFloat(v1).Interface() != "13579" { t.Fail() } @@ -278,14 +278,14 @@ func TestForFloat(t *testing.T) { var z typ.Any v1 := reflect.ValueOf(z) - v1 = tool.Rdecodesimple(v1) + v1 = ref.Rdecodesimple(v1) if x := rForFloat(v1).Interface(); x != "0" { t.Fatalf("failed, x = %v", x) } z = "bug" v1 = reflect.ValueOf(z) - v1 = tool.Rdecodesimple(v1) + v1 = ref.Rdecodesimple(v1) if x := rForFloat(v1).Interface(); x != "0" { t.Fatalf("failed, x = %v", x) } @@ -325,7 +325,7 @@ func TestForComplex(t *testing.T) { -8.5 - 7.13i: "(-8.5-7.13i)", } { v1 := reflect.ValueOf(src) - v1 = tool.Rdecodesimple(v1) + v1 = ref.Rdecodesimple(v1) if x := rForComplex(v1).Interface(); x != exp { t.Fatalf("failed, x = %v, expect = %v", x, exp) } @@ -333,14 +333,14 @@ func TestForComplex(t *testing.T) { var z typ.Any v1 := reflect.ValueOf(z) - v1 = tool.Rdecodesimple(v1) + v1 = ref.Rdecodesimple(v1) if x := rForComplex(v1).Interface(); x != "(0+0i)" { t.Fatalf("failed, x = %v", x) } z = "bug" v1 = reflect.ValueOf(z) - v1 = tool.Rdecodesimple(v1) + v1 = ref.Rdecodesimple(v1) if x := rForComplex(v1).Interface(); x != "(0+0i)" { t.Fatalf("failed, x = %v", x) } @@ -425,7 +425,7 @@ func TestToStringConverter_Transform(t *testing.T) { var tgtstr = "1" tgt = reflect.ValueOf(&tgtstr).Elem() - dbglog.Log("target/; %v %v", tool.Valfmt(&tgt), tool.Typfmtv(&tgt)) + dbglog.Log("target/; %v %v", ref.Valfmt(&tgt), ref.Typfmtv(&tgt)) err = bbc.CopyTo(nil, svv, tgt) if err != nil { t.Fatalf("err: %v", err) @@ -494,7 +494,7 @@ func TestFromStringConverter_Transform(t *testing.T) { } if x := tgt.Interface(); x != exp { - t.Fatalf("convert failed, want %v but got %v (%v)", exp, x, tool.Typfmt(tgt.Type())) + t.Fatalf("convert failed, want %v but got %v (%v)", exp, x, ref.Typfmt(tgt.Type())) } tgt = reflect.New(tgtType).Elem() @@ -503,7 +503,7 @@ func TestFromStringConverter_Transform(t *testing.T) { t.Fatalf("err: %v", err) } if x := tgt.Interface(); x != exp { - t.Fatalf("convert failed, want %v but got %v (%v)", exp, x, tool.Typfmt(tgt.Type())) + t.Fatalf("convert failed, want %v but got %v (%v)", exp, x, ref.Typfmt(tgt.Type())) } } } @@ -515,7 +515,7 @@ func TestToDurationConverter_Transform(t *testing.T) { var dur = 3 * time.Second var v = reflect.ValueOf(dur) - t.Logf("dur: %v (%v, kind: %v, name: %v, pkgpath: %v)", dur, tool.Typfmtv(&v), v.Kind(), v.Type().Name(), v.Type().PkgPath()) + t.Logf("dur: %v (%v, kind: %v, name: %v, pkgpath: %v)", dur, ref.Typfmtv(&v), v.Kind(), v.Type().Name(), v.Type().PkgPath()) tgtType := reflect.TypeOf((*time.Duration)(nil)).Elem() @@ -525,7 +525,7 @@ func TestToDurationConverter_Transform(t *testing.T) { if err != nil { t.Fatalf("err: %v", err) } - t.Logf("res: %v (%v)", tgt.Interface(), tool.Typfmtv(&tgt)) + t.Logf("res: %v (%v)", tgt.Interface(), ref.Typfmtv(&tgt)) t.Run("toDurationConverter = pre", func(t *testing.T) { @@ -582,9 +582,9 @@ func TestToDurationConverter_Transform(t *testing.T) { t.Fatalf("err: %v", err) } if reflect.DeepEqual(tgt.Interface(), cas.expect) == false { - t.Fatalf("err transform: expect %v but got %v (%v)", cas.expect, tgt.Interface(), tool.Typfmt(tgt.Type())) + t.Fatalf("err transform: expect %v but got %v (%v)", cas.expect, tgt.Interface(), ref.Typfmt(tgt.Type())) } - t.Logf("res #%d: %v (%v)", ix, tgt.Interface(), tool.Typfmt(tgt.Type())) + t.Logf("res #%d: %v (%v)", ix, tgt.Interface(), ref.Typfmt(tgt.Type())) } }) @@ -613,9 +613,9 @@ func TestToDurationConverter_Transform(t *testing.T) { t.Fatalf("err: %v", err) } if reflect.DeepEqual(tgt.Interface(), cas.expect) == false { - t.Fatalf("err transform: expect %v but got %v (%v)", cas.expect, tgt.Interface(), tool.Typfmt(tgt.Type())) + t.Fatalf("err transform: expect %v but got %v (%v)", cas.expect, tgt.Interface(), ref.Typfmt(tgt.Type())) } - t.Logf("res #%d: %v (%v)", ix, tgt.Interface(), tool.Typfmt(tgt.Type())) + t.Logf("res #%d: %v (%v)", ix, tgt.Interface(), ref.Typfmt(tgt.Type())) } }) @@ -709,9 +709,9 @@ func TestToTimeConverter_Transform(t *testing.T) { t.Fatalf("err: %v", err) } if reflect.DeepEqual(tgt.Interface(), cas.expect) == false { - t.Fatalf("err transform: expect %v but got %v (%v)", cas.expect, tgt.Interface(), tool.Typfmt(tgt.Type())) + t.Fatalf("err transform: expect %v but got %v (%v)", cas.expect, tgt.Interface(), ref.Typfmt(tgt.Type())) } - t.Logf("res #%d: %v (%v)", ix, tgt.Interface(), tool.Typfmt(tgt.Type())) + t.Logf("res #%d: %v (%v)", ix, tgt.Interface(), ref.Typfmt(tgt.Type())) } }) @@ -742,9 +742,9 @@ func TestToTimeConverter_Transform(t *testing.T) { } got := tgt.Interface().(time.Time).UTC().Format(layout) if reflect.DeepEqual(got, cas.expect) == false { - t.Fatalf("err transform: expect %v but got %v (%v)", cas.expect, got, tool.Typfmt(tgt.Type())) + t.Fatalf("err transform: expect %v but got %v (%v)", cas.expect, got, ref.Typfmt(tgt.Type())) } - t.Logf("res #%d: %v (%v)", ix, got, tool.Typfmt(tgt.Type())) + t.Logf("res #%d: %v (%v)", ix, got, ref.Typfmt(tgt.Type())) } }) @@ -762,7 +762,7 @@ func TestFromStringConverter_defaultTypes(t *testing.T) { if err != nil { t.Fatalf("err: %v", err) } - t.Logf("ret: %v (%v)", tool.Valfmt(&ret), tool.Typfmtv(&ret)) + t.Logf("ret: %v (%v)", ref.Valfmt(&ret), ref.Typfmtv(&ret)) } func TestFromStringConverter_postCopyTo(t *testing.T) { @@ -779,7 +779,7 @@ func TestFromStringConverter_postCopyTo(t *testing.T) { if err != nil { t.Fatalf("err: %v", err) } - t.Logf("ret: %v (%v)", dst, tool.Typfmtv(&dvv)) + t.Logf("ret: %v (%v)", dst, ref.Typfmtv(&dvv)) } func TestToStringConverter_postCopyTo(t *testing.T) { @@ -792,8 +792,8 @@ func TestToStringConverter_postCopyTo(t *testing.T) { }{} var svv = reflect.ValueOf(&src) var dvv = reflect.ValueOf(&dst) - var sf1 = tool.Rindirect(svv).Field(0) - var df1 = tool.Rindirect(dvv).Field(0) + var sf1 = ref.Rindirect(svv).Field(0) + var df1 = ref.Rindirect(dvv).Field(0) // var sft = reflect.TypeOf(src).Field(0) ctx := &ValueConverterContext{ @@ -822,7 +822,7 @@ func TestToStringConverter_postCopyTo(t *testing.T) { if dst.fval != "3.3" { t.Fatalf("want '3.3' but got %v", dst.fval) } - t.Logf("ret: %v (%v)", dst, tool.Typfmtv(&dvv)) + t.Logf("ret: %v (%v)", dst, ref.Typfmtv(&dvv)) } type si1 struct{} @@ -835,11 +835,11 @@ func TestHasStringer(t *testing.T) { var i2 si2 v := reflect.ValueOf(i1) - t.Logf("si1: %v", tool.HasStringer(&v)) + t.Logf("si1: %v", ref.HasStringer(&v)) v = reflect.ValueOf(i2) - t.Logf("si2: %v", tool.HasStringer(&v)) + t.Logf("si2: %v", ref.HasStringer(&v)) v = reflect.ValueOf(&i2) - t.Logf("*si2: %v", tool.HasStringer(&v)) + t.Logf("*si2: %v", ref.HasStringer(&v)) } func TestNameToMapKey(t *testing.T) { @@ -868,14 +868,14 @@ func TestNameToMapKey(t *testing.T) { for _, m := range mapslice { mv := reflect.ValueOf(&m) // nolint:gosec // G601: Implicit memory aliasing in for loop - mvind := tool.Rdecodesimple(mv) - t.Logf(" target map is %v", tool.Typfmtv(&mvind)) - mt := tool.Rdecodetypesimple(mvind.Type()) + mvind := ref.Rdecodesimple(mv) + t.Logf(" target map is %v", ref.Typfmtv(&mvind)) + mt := ref.Rdecodetypesimple(mvind.Type()) key, err := nameToMapKey(name, mt) if err != nil { t.Errorf("nameToMapKey, has error: %v", err) } else { - t.Logf("for target map %v, got key from nameToMapKey: %v %v", tool.Typfmt(mt), tool.Valfmt(&key), tool.Typfmt(key.Type())) + t.Logf("for target map %v, got key from nameToMapKey: %v %v", ref.Typfmt(mt), ref.Valfmt(&key), ref.Typfmt(key.Type())) } } } @@ -968,9 +968,9 @@ func TestFromFuncConverter(t *testing.T) { if fnCase.fn != nil { //nolint:gocritic //nestingReduce: invert if cond, replace body with `continue`, move old body after the statement fnv := reflect.ValueOf(&fnCase.fn) tgtv := reflect.ValueOf(&fnCase.target) - ff, tt := tool.Rdecodesimple(fnv), tool.Rdecodesimple(tgtv) - dbglog.Log("---- CASE %d. %v -> %v", ix, tool.Typfmtv(&ff), tool.Typfmtv(&tt)) - t.Logf("---- CASE %d. %v -> %v", ix, tool.Typfmtv(&ff), tool.Typfmtv(&tt)) + ff, tt := ref.Rdecodesimple(fnv), ref.Rdecodesimple(tgtv) + dbglog.Log("---- CASE %d. %v -> %v", ix, ref.Typfmtv(&ff), ref.Typfmtv(&tt)) + t.Logf("---- CASE %d. %v -> %v", ix, ref.Typfmtv(&ff), ref.Typfmtv(&tt)) c := fromFuncConverter{} ctx := newValueConverterContextForTest(nil) diff --git a/deepcopy.go b/deepcopy.go index 32ff65b..ec6cf28 100644 --- a/deepcopy.go +++ b/deepcopy.go @@ -4,7 +4,7 @@ import ( "github.com/hedzr/evendeep/dbglog" "github.com/hedzr/evendeep/flags" "github.com/hedzr/evendeep/flags/cms" - "github.com/hedzr/evendeep/internal/tool" + "github.com/hedzr/evendeep/ref" "reflect" ) @@ -68,7 +68,7 @@ func MakeClone(fromObj interface{}) (result interface{}) { var ( from = reflect.ValueOf(fromObj) fromTyp = from.Type() - findTyp = tool.Rdecodetypesimple(fromTyp) + findTyp = ref.Rdecodetypesimple(fromTyp) toPtr = reflect.New(findTyp) toPtrObj = toPtr.Interface() ) diff --git a/deepdiff.go b/deepdiff.go index cc6845d..dbf0efc 100644 --- a/deepdiff.go +++ b/deepdiff.go @@ -7,9 +7,9 @@ import ( // DeepDiff compares a and b deeply inside. // -// delta, equal := evendeep.DeepDiff(a, b) -// fmt.Println(delta) -// fmt.Println(delta.PrettyPrint()) +// delta, equal := evendeep.DeepDiff(a, b) +// fmt.Println(delta) +// fmt.Println(delta.PrettyPrint()) func DeepDiff(a, b typ.Any, opts ...diff.Opt) (delta diff.Diff, equal bool) { return diff.New(a, b, opts...) } diff --git a/deepequal.go b/deepequal.go index 284877d..2c1dfdd 100644 --- a/deepequal.go +++ b/deepequal.go @@ -7,8 +7,8 @@ import ( // DeepEqual compares a and b deeply inside. // -// equal := evendeep.DeepEqual(a, b) -// fmt.Println(equal) +// equal := evendeep.DeepEqual(a, b) +// fmt.Println(equal) func DeepEqual(a, b typ.Any, opts ...diff.Opt) (equal bool) { _, equal = diff.New(a, b, opts...) return diff --git a/ftor.go b/ftor.go index 958a326..fb07611 100644 --- a/ftor.go +++ b/ftor.go @@ -4,21 +4,22 @@ package evendeep // import ( - "github.com/hedzr/log" - "github.com/hedzr/log/color" + "reflect" + "strconv" + "strings" + "unsafe" "github.com/hedzr/evendeep/dbglog" "github.com/hedzr/evendeep/flags/cms" "github.com/hedzr/evendeep/internal/cl" "github.com/hedzr/evendeep/internal/tool" + "github.com/hedzr/evendeep/ref" "github.com/hedzr/evendeep/typ" + "github.com/hedzr/is" + "github.com/hedzr/is/term/color" + logz "github.com/hedzr/logg/slog" "gopkg.in/hedzr/errors.v3" - - "reflect" - "strconv" - "strings" - "unsafe" ) func copyPointer(c *cpController, params *Params, from, to reflect.Value) (err error) { @@ -32,8 +33,8 @@ func copyPointer(c *cpController, params *Params, from, to reflect.Value) (err e } } - src := tool.Rindirect(from) - tgt := tool.Rindirect(to) + src := ref.Rindirect(from) + tgt := ref.Rindirect(to) paramsChild := newParams(withOwners(c, params, &from, &to, nil, nil)) defer paramsChild.revoke() @@ -46,12 +47,12 @@ func copyPointer(c *cpController, params *Params, from, to reflect.Value) (err e // pointer - src is nil - set tgt to nil too newtyp := to.Type() zv := reflect.Zero(newtyp) - dbglog.Log(" pointer - zv: %v (%v), to: %v (%v)", tool.Valfmt(&zv), tool.Typfmt(newtyp), tool.Valfmt(&to), tool.Typfmtv(&to)) + dbglog.Log(" pointer - zv: %v (%v), to: %v (%v)", ref.Valfmt(&zv), ref.Typfmt(newtyp), ref.Valfmt(&to), ref.Typfmtv(&to)) to.Set(zv) // err = newobj(c, params, src, to, tgt) } } else { - dbglog.Log(" pointer - tgt is invalid/cannot-be-set/ignored: src: (%v) -> tgt: (%v)", tool.Typfmtv(&src), tool.Typfmtv(&to)) + dbglog.Log(" pointer - tgt is invalid/cannot-be-set/ignored: src: (%v) -> tgt: (%v)", ref.Typfmtv(&src), ref.Typfmtv(&to)) err = newObj(c, paramsChild, fromType, src, to, tgt) } return @@ -64,7 +65,7 @@ func newObj(c *cpController, params *Params, fromType reflect.Type, src, to, tgt } // create new object and pointer toobjcopyptrv := reflect.New(newtyp) - dbglog.Log(" toobjcopyptrv: %v", tool.Typfmtv(&toobjcopyptrv)) + dbglog.Log(" toobjcopyptrv: %v", ref.Typfmtv(&toobjcopyptrv)) if err = c.copyTo(params, src, toobjcopyptrv.Elem()); err == nil { val := toobjcopyptrv if to.Type() == fromType { @@ -77,7 +78,7 @@ func newObj(c *cpController, params *Params, fromType reflect.Type, src, to, tgt } func copyInterface(c *cpController, params *Params, from, to reflect.Value) (err error) { - if tool.IsNil(from) { + if ref.IsNil(from) { if params.isGroupedFlagOKDeeply(cms.OmitIfNil, cms.OmitIfEmpty) { return } @@ -93,7 +94,7 @@ func copyInterface(c *cpController, params *Params, from, to reflect.Value) (err goto badReturn } - if tool.IsZero(from) { + if ref.IsZero(from) { if params.isGroupedFlagOKDeeply(cms.OmitIfZero, cms.OmitIfEmpty) { return } @@ -112,7 +113,7 @@ func copyInterface(c *cpController, params *Params, from, to reflect.Value) (err return badReturn: - err = ErrCannotSet.FormatWith(tool.Valfmt(&from), tool.Typfmtv(&from), tool.Valfmt(&to), tool.Typfmtv(&to)) + err = ErrCannotSet.FormatWith(ref.Valfmt(&from), ref.Typfmtv(&from), ref.Valfmt(&to), ref.Typfmtv(&to)) return } @@ -121,15 +122,15 @@ func copyInterfaceImpl(c *cpController, params *Params, from, to reflect.Value) defer paramsChild.revoke() // unbox the interface{} to original data type - toind, toptr := tool.Rdecode(to) // c.skip(to, reflect.Interface, reflect.Pointer) + toind, toptr := ref.Rdecode(to) // c.skip(to, reflect.Interface, reflect.Pointer) dbglog.Log("from.type: %v, decode to: %v", from.Type().Kind(), paramsChild.srcDecoded.Kind()) dbglog.Log(" to.type: %v, decode to: %v (ptr: %v) | CanSet: %v/%v, CanAddr: %v", to.Type().Kind(), toind.Kind(), toptr.Kind(), toind.CanSet(), toptr.CanSet(), toind.CanAddr()) - if !tool.KindIs(toind.Kind(), reflect.Map, reflect.Slice, reflect.Chan) { + if !ref.KindIs(toind.Kind(), reflect.Map, reflect.Slice, reflect.Chan) { if !toind.CanSet() && !toptr.CanSet() { - // log.Panicf("[copyInterface] toind.CanSet() is false!") + // logz.Panicf("[copyInterface] toind.CanSet() is false!") // valid ptr pointed to an invalid source object, // valid ptr pointed to an invalid target object: @@ -192,19 +193,19 @@ func copyStructInternal( //nolint:gocognit //keep it // .WithData(e) will collect e if it's an error object else store it simply ec.Attach(errors.New("[recovered] copyStruct unsatisfied ([%v] -> [%v]), causes: %v", - tool.Typfmtv(ff), tool.Typfmtptr(tft), e). + ref.Typfmtv(ff), ref.Typfmtptr(tft), e). WithMaxObjectStringLength(maxObjectStringLen). WithData(e). WithTaggedData(errors.TaggedData{ // record the sites "source-field": ff, "target-field": tf, - "source": tool.Valfmt(ff), - "target": tool.Valfmt(tf), + "source": ref.Valfmt(ff), + "target": ref.Valfmt(tf), })) - // n := log.CalcStackFrames(1) // skip defer-recover frame at first - // log.Skip(n).Errorf("%v", err) // skip golib frames and defer-recover frame, back to the point throwing panic + // n := logz.CalcStackFrames(1) // skip defer-recover frame at first + // logz.Skip(n).Errorf("%v", err) // skip golib frames and defer-recover frame, back to the point throwing panic // if c.rethrow { - // log.Panicf("%+v", ec) + // logz.Panicf("%+v", ec) // } else { // dbglog.Err("copyStructInternal will return error: %+v", ec) // } @@ -235,7 +236,7 @@ func copyStructInternal( //nolint:gocognit //keep it } else if paramsChild.isGroupedFlagOKDeeply(cms.SliceCopyAppend, cms.SliceMerge) { err = cpStructToNewSliceElem0(paramsChild) } else { - err = ErrCannotCopy.FormatWith(tool.Valfmt(&from), tool.Typfmtv(&from), tool.Valfmt(&to), tool.Typfmtv(&to)) + err = ErrCannotCopy.FormatWith(ref.Valfmt(&from), ref.Typfmtv(&from), ref.Valfmt(&to), ref.Typfmtv(&to)) } ec.Attach(err) return @@ -245,7 +246,7 @@ func copyStructInternal( //nolint:gocognit //keep it if paramsChild.dstDecoded.Len() > 0 { err = c.copyTo(paramsChild, *paramsChild.srcOwner, paramsChild.dstDecoded.Index(0)) } else { - err = ErrCannotCopy.FormatWith(tool.Valfmt(&from), tool.Typfmtv(&from), tool.Valfmt(&to), tool.Typfmtv(&to)) + err = ErrCannotCopy.FormatWith(ref.Valfmt(&from), ref.Typfmtv(&from), ref.Valfmt(&to), ref.Typfmtv(&to)) } ec.Attach(err) return @@ -259,10 +260,10 @@ func copyStructInternal( //nolint:gocognit //keep it paramsChild.dstDecoded.Set(target) } else { err = ErrCannotSet.FormatWith( - tool.Valfmt(paramsChild.srcDecoded), - tool.Typfmtv(paramsChild.srcDecoded), - tool.Valfmt(paramsChild.dstDecoded), - tool.Typfmtv(paramsChild.dstDecoded)) + ref.Valfmt(paramsChild.srcDecoded), + ref.Typfmtv(paramsChild.srcDecoded), + ref.Valfmt(paramsChild.dstDecoded), + ref.Typfmtv(paramsChild.dstDecoded)) } } return @@ -275,7 +276,7 @@ func copyStructInternal( //nolint:gocognit //keep it func cpStructToNewSliceElem0(params *Params) (err error) { eltyp := params.dstType.Elem() - et, _ := tool.Rdecodetype(eltyp) + et, _ := ref.Rdecodetype(eltyp) elnew := reflect.New(et) slice, tgtptr, el := *params.dstDecoded, params.dstOwner, elnew.Elem() if eltyp != et { @@ -438,28 +439,28 @@ func forEachSourceField(params *Params, ec errors.Error, i, amount *int, padding dstfieldname := params.accessor.StructFieldName() // log.VDebugf will be tuned and stripped off in normal build. - dbglog.Colored(color.LightMagenta, "%d. fld %q (%v) -> %s (%v) | (%v) -> (%v)", *i, - fn, tool.Typfmtv(srcval), dstfieldname, tool.Typfmt(*params.accessor.FieldType()), - tool.Valfmt(srcval), tool.Valfmt(dstval)) + dbglog.Colored(color.FgLightMagenta, "%d. fld %q (%v) -> %s (%v) | (%v) -> (%v)", *i, + fn, ref.Typfmtv(srcval), dstfieldname, ref.Typfmt(*params.accessor.FieldType()), + ref.Valfmt(srcval), ref.Valfmt(dstval)) // The following if clause will be stripped off completely // in normal build. // It's only available when using `-tags=verbose`. - // The first condition 'log.VerboseEnabled' do circuit to + // The first condition 'logz.VerboseEnabled' do circuit to // be optimized by compiler. - if log.VerboseEnabled && !ec.IsEmpty() { - log.Warnf(" ERR-CONTAINER NOT EMPTY: %+v", ec.Error()) + if is.VerboseModeEnabled() && !ec.IsEmpty() { + logz.Warn(" ERR-CONTAINER NOT EMPTY:", "error", ec.Error()) } if srcval != nil && dstval != nil { typ := params.accessor.FieldType() // target type - if typ != nil && !tool.KindIs((*typ).Kind(), reflect.Chan, reflect.Func, reflect.Interface, reflect.UnsafePointer, reflect.Ptr, reflect.Slice) { - if tool.IsNil(*dstval) || !(*dstval).IsValid() { - if !tool.IsNil(*srcval) { - dbglog.Log(" create new: dstval = nil/invalid, type: %v (%v -> nil/inalid)", tool.Typfmt(*typ), tool.Valfmt(srcval)) + if typ != nil && !ref.KindIs((*typ).Kind(), reflect.Chan, reflect.Func, reflect.Interface, reflect.UnsafePointer, reflect.Ptr, reflect.Slice) { + if ref.IsNil(*dstval) || !(*dstval).IsValid() { + if !ref.IsNil(*srcval) { + dbglog.Log(" create new: dstval = nil/invalid, type: %v (%v -> nil/inalid)", ref.Typfmt(*typ), ref.Valfmt(srcval)) _, elem := newFromTypeEspSlice(*typ) dstval.Set(elem) - dbglog.Log(" create new: dstval created: %v", tool.Typfmtv(dstval)) + dbglog.Log(" create new: dstval created: %v", ref.Typfmtv(dstval)) } } } @@ -469,7 +470,7 @@ func forEachSourceField(params *Params, ec errors.Error, i, amount *int, padding ec.Attach(err) dbglog.Err(" %d. fld %q error: %v", *i, fn, err) } else { - dbglog.Log(" %d. fld %q copied. from-to: %v -> %v", *i, fn, tool.Valfmt(srcval), tool.Valfmt(dstval)) + dbglog.Log(" %d. fld %q copied. from-to: %v -> %v", *i, fn, ref.Valfmt(srcval), ref.Valfmt(dstval)) } } continue @@ -516,11 +517,11 @@ func forEachSourceFieldCheckMergeMode(params *Params, srcval *reflect.Value, c := params.controller typ := params.accessor.FieldType() - dbglog.Log(" new object for %v", tool.Typfmt(*typ)) + dbglog.Log(" new object for %v", ref.Typfmt(*typ)) // create new object and pointer toobjcopyptrv := reflect.New(*typ).Elem() - dbglog.Log(" toobjcopyptrv: %v", tool.Typfmtv(&toobjcopyptrv)) + dbglog.Log(" toobjcopyptrv: %v", ref.Typfmtv(&toobjcopyptrv)) //nolint:gocritic // no need to switch to 'switch' clause if err = invokeStructFieldTransformer(c, params, srcval, &toobjcopyptrv, typ, padding); err != nil { @@ -539,7 +540,7 @@ func forEachSourceFieldCheckMergeMode(params *Params, srcval *reflect.Value, } func dbgFrontOfStruct(params *Params, padding string, logger func(msg string, args ...interface{})) { - if log.VerboseEnabled { + if is.VerboseModeEnabled() { if params == nil { return } @@ -555,7 +556,7 @@ func dbgFrontOfStruct(params *Params, padding string, logger func(msg string, ar // Log(" %s %d, %d, %d", padding, params.index, params.srcOffset, params.dstOffset) // fq := dbgMakeInfoString(fromT, params.owner, true, logger) // dq := dbgMakeInfoString(toT, params.owner, false, logger) - logger(" %s- src (%v) -> dst (%v)", padding1, tool.Typfmtv(params.srcDecoded), tool.Typfmtv(params.dstDecoded)) + logger(" %s- src (%v) -> dst (%v)", padding1, ref.Typfmtv(params.srcDecoded), ref.Typfmtv(params.dstDecoded)) // logger(" %s %s -> %s", padding, fq, dq) } } @@ -582,7 +583,7 @@ func invokeStructFieldTransformer( if fftk == reflect.Struct && ff.NumField() == 0 { // never get into here because tableRecordsT.getAllFields skip empty struct - log.Warnf("should never get into here, might be algor wrong ?") + logz.Warn("should never get into here, might be algor wrong ?") } if dftk == reflect.Struct && df.NumField() == 0 { // structIterable.Next() might return an empty struct accessor @@ -593,8 +594,8 @@ func invokeStructFieldTransformer( if fv && dv { dbglog.Log(` c.copyTo: ff -> df`) err = c.copyTo(params, *ff, *df) // or, use internal standard implementation version - dbglog.Log(` c.copyTo.end: ff -> df. err = %v, df = %v`, err, tool.Valfmt(df)) - if log.VerboseEnabled { + dbglog.Log(` c.copyTo.end: ff -> df. err = %v, df = %v`, err, ref.Valfmt(df)) + if is.VerboseModeEnabled() { if df.CanInterface() { switch k := df.Kind(); k { case reflect.Map, reflect.Slice: @@ -612,26 +613,26 @@ func invokeStructFieldTransformer( //nolint:lll //keep it func forInvalidValues(c *cpController, params *Params, ff *reflect.Value, fft, dft reflect.Type, fftk, dftk reflect.Kind, fv bool) (err error) { if !fv { - dbglog.Log(" ff is invalid: %v", tool.Typfmtv(ff)) + dbglog.Log(" ff is invalid: %v", ref.Typfmtv(ff)) nv := reflect.New(fft).Elem() ff = &nv } if dftk == reflect.Interface { dft, dftk = fft, fftk } - dbglog.Log(" dft: %v", tool.Typfmt(dft)) + dbglog.Log(" dft: %v", ref.Typfmt(dft)) if dftk == reflect.Ptr { nv := reflect.New(dft.Elem()) tt := nv.Elem() - dbglog.Log(" nv.tt: %v", tool.Typfmtv(&tt)) - ff1 := tool.Rindirect(*ff) + dbglog.Log(" nv.tt: %v", ref.Typfmtv(&tt)) + ff1 := ref.Rindirect(*ff) err = c.copyTo(params, ff1, tt) // use user-defined copy-n-merger to merge or copy source to destination if err == nil && !params.accessor.IsStruct() { params.accessor.Set(tt) } } else { nv := reflect.New(dft) - ff1 := tool.Rindirect(*ff) + ff1 := ref.Rindirect(*ff) err = c.copyTo(params, ff1, nv.Elem()) // use user-defined copy-n-merger to merge or copy source to destination if err == nil && !params.accessor.IsStruct() { params.accessor.Set(nv.Elem()) @@ -649,10 +650,10 @@ func dtypzz(df *reflect.Value, deftyp *reflect.Type) reflect.Type { //nolint:goc } func checkOmitEmptyOpt(params *Params, ff, df *reflect.Value, dft reflect.Type) (processed bool) { - if tool.IsNilv(ff) && params.isGroupedFlagOKDeeply(cms.OmitIfNil, cms.OmitIfEmpty) { + if ref.IsNilv(ff) && params.isGroupedFlagOKDeeply(cms.OmitIfNil, cms.OmitIfEmpty) { processed = true } - if tool.IsZerov(ff) && params.isGroupedFlagOKDeeply(cms.OmitIfZero, cms.OmitIfEmpty) { + if ref.IsZerov(ff) && params.isGroupedFlagOKDeeply(cms.OmitIfZero, cms.OmitIfEmpty) { processed = true } return @@ -696,7 +697,7 @@ func tryConverters(c *cpController, params *Params, //nolint:lll //keep it func findAndApplyCopiers(c *cpController, params *Params, ff, df *reflect.Value, fft, dft reflect.Type, userDefinedOnly bool) (processed bool, err error) { if cvt, ctx := c.valueCopiers.findCopiers(params, fft, dft, userDefinedOnly); ctx != nil { //nolint:nestif //keep it - dbglog.Colored(color.DarkColor, "-> using Copier %v", reflect.ValueOf(cvt).Type()) + dbglog.Colored(color.FgDarkColor, "-> using Copier %v", reflect.ValueOf(cvt).Type()) if df.IsValid() { if err = cvt.CopyTo(ctx, *safeFF(ff, fft), *df); err == nil { // use user-defined copy-n-merger to merge or copy source to destination @@ -708,7 +709,7 @@ func findAndApplyCopiers(c *cpController, params *Params, ff, df *reflect.Value, if dft.Kind() == reflect.Interface { dft = fft } - dbglog.Log(" dft: %v", tool.Typfmt(dft)) + dbglog.Log(" dft: %v", ref.Typfmt(dft)) nv := reflect.New(dft) err = cvt.CopyTo(ctx, *safeFF(ff, fft), nv) // use user-defined copy-n-merger to merge or copy source to destination if err == nil && !params.accessor.IsStruct() { @@ -722,7 +723,7 @@ func findAndApplyCopiers(c *cpController, params *Params, ff, df *reflect.Value, //nolint:lll //keep it func findAndApplyConverters(c *cpController, params *Params, ff, df *reflect.Value, fft, dft reflect.Type, userDefinedOnly bool) (processed bool, err error) { if cvt, ctx := c.valueConverters.findConverters(params, fft, dft, userDefinedOnly); ctx != nil { - dbglog.Colored(color.DarkColor, "-> using Converter %v", reflect.ValueOf(cvt).Type()) + dbglog.Colored(color.FgDarkColor, "-> using Converter %v", reflect.ValueOf(cvt).Type()) var result reflect.Value result, err = cvt.Transform(ctx, *safeFF(ff, fft), dft) // use user-defined value converter to transform from source to destination @@ -752,32 +753,32 @@ func copySlice(c *cpController, params *Params, from, to reflect.Value) (err err } var tgt, tgtptr reflect.Value - tgt, tgtptr = tool.Rdecode(to) + tgt, tgtptr = ref.Rdecode(to) if to != tgtptr { //nolint:govet //how should i do //TODO needs checked-review err = c.copyTo(params, from, tgtptr) // unwrap the pointer return } - if !tool.KindIs(tgt.Kind(), reflect.Map, reflect.Slice, reflect.Chan) && !tgt.CanSet() { - log.Panicf("[copySlice] tgtptr cannot be set") + if !ref.KindIs(tgt.Kind(), reflect.Map, reflect.Slice, reflect.Chan) && !tgt.CanSet() { + logz.Panic("[copySlice] tgtptr cannot be set") } if params.controller != c { - log.Panicf("[copySlice] c *cpController != params.controller, what's up??") + logz.Panic("[copySlice] c *cpController != params.controller, what's up??") } tk, typ := tgt.Kind(), tgt.Type() if tk != reflect.Slice { - dbglog.Log("[copySlice] from slice -> %v", tool.Typfmt(typ)) + dbglog.Log("[copySlice] from slice -> %v", ref.Typfmt(typ)) var processed bool if processed, err = tryConverters(c, params, &from, &tgt, &typ, false); !processed { - // log.Panicf("[copySlice] unsupported transforming: from slice -> %v,", typfmtv(&tgt)) + // logz.Panicf("[copySlice] unsupported transforming: from slice -> %v,", typfmtv(&tgt)) //nolint:lll //keep it - err = ErrCannotCopy.WithErrors(err).FormatWith(tool.Valfmt(&from), tool.Typfmtv(&from), tool.Valfmt(&tgt), tool.Typfmtv(&tgt)) + err = ErrCannotCopy.WithErrors(err).FormatWith(ref.Valfmt(&from), ref.Typfmtv(&from), ref.Valfmt(&tgt), ref.Typfmtv(&tgt)) } return } - if tool.IsNil(tgt) && params.isGroupedFlagOKDeeply(cms.OmitIfTargetZero, cms.OmitIfTargetEmpty) { + if ref.IsNil(tgt) && params.isGroupedFlagOKDeeply(cms.OmitIfTargetZero, cms.OmitIfTargetEmpty) { return } @@ -798,15 +799,15 @@ func copySliceInternal(c *cpController, params *Params, from, to, tgt, tgtptr re for _, flag := range []cms.CopyMergeStrategy{cms.SliceMerge, cms.SliceCopyAppend, cms.SliceCopy} { if params.isGroupedFlagOKDeeply(flag) { //nolint:nestif,gocritic // nestingReduce: invert if cond, replace body with `continue`, move old body after the statement dbglog.Log("Using slice merge mode: %v", flag) - dbglog.Log(" from.type: %v, value: %v", tool.Typfmtv(&from), tool.Valfmt(&from)) - dbglog.Log(" to.type: %v, value: %v | canAddr: %v, canSet: %v", tool.Typfmtv(&to), tool.Valfmt(&to), to.CanAddr(), to.CanSet()) + dbglog.Log(" from.type: %v, value: %v", ref.Typfmtv(&from), ref.Valfmt(&from)) + dbglog.Log(" to.type: %v, value: %v | canAddr: %v, canSet: %v", ref.Typfmtv(&to), ref.Valfmt(&to), to.CanAddr(), to.CanSet()) // Log(" src.type: %v, len: %v, cap: %v, srcptr.canAddr: %v", src.Type().Kind(), src.Len(), src.Cap(), srcptr.CanAddr()) - dbglog.Log(" tgt.type: %v, tgtptr: %v .canAddr: %v", tool.Typfmtv(&tgt), tool.Typfmtv(&tgtptr), tgtptr.CanAddr()) + dbglog.Log(" tgt.type: %v, tgtptr: %v .canAddr: %v", ref.Typfmtv(&tgt), ref.Typfmtv(&tgtptr), tgtptr.CanAddr()) if fn, ok := getSliceOperations()[flag]; ok { if result, err = fn(c, params, from, tgt); err == nil { - dbglog.Log(" result: got %v (%v)", tool.Valfmt(result), tool.Typfmtv(result)) - dbglog.Log(" tgt: contains %v (%v) | tgtptr: %v, .canset: %v", tool.Valfmt(&tgt), tool.Typfmtv(&tgt), tool.Typfmtv(&tgtptr), tgtptr.CanSet()) + dbglog.Log(" result: got %v (%v)", ref.Valfmt(result), ref.Typfmtv(result)) + dbglog.Log(" tgt: contains %v (%v) | tgtptr: %v, .canset: %v", ref.Valfmt(&tgt), ref.Typfmtv(&tgt), ref.Typfmtv(&tgtptr), tgtptr.CanSet()) if tk := tgtptr.Kind(); tk == reflect.Ptr { //nolint:gocritic //keep it tgtptr.Elem().Set(*result) @@ -816,8 +817,8 @@ func copySliceInternal(c *cpController, params *Params, from, to, tgt, tgtptr re tgtptr.Set(*result) } } else { - dbglog.Log(" error: cannot make copy for a slice, the target ptr is cannot be set: tgtptr.typ = %v", tool.Typfmtv(&tgtptr)) - ec.Attach(errors.New("cannot make copy for a slice, the target ptr is cannot be set: tgtptr.typ = %v", tool.Typfmtv(&tgtptr))) + dbglog.Log(" error: cannot make copy for a slice, the target ptr is cannot be set: tgtptr.typ = %v", ref.Typfmtv(&tgtptr)) + ec.Attach(errors.New("cannot make copy for a slice, the target ptr is cannot be set: tgtptr.typ = %v", ref.Typfmtv(&tgtptr))) } } else { dbglog.Log(" error: ec.Attach(e), e: %v", err) @@ -944,7 +945,7 @@ func _sliceCopyOne(c *cpController, params *Params, ecTotal errors.Error, slice ecTotal.Attach(ec) continue // ignore invalid element } - } else if tool.CanConvert(&el, tgtelemtype) { + } else if ref.CanConvert(&el, tgtelemtype) { enew = el.Convert(tgtelemtype) // elv = enew.Interface() } @@ -953,7 +954,7 @@ func _sliceCopyOne(c *cpController, params *Params, ecTotal errors.Error, slice if el.Type() == tgtelemtype { //nolint:nestif //keep it slice = reflect.Append(slice, el) } else { - if tool.CanConvert(&el, tgtelemtype) { + if ref.CanConvert(&el, tgtelemtype) { slice = reflect.Append(slice, enew) } else { enew = reflect.New(tgtelemtype) @@ -1016,7 +1017,7 @@ func _sliceMergeOperation(c *cpController, params *Params, src, tgt reflect.Valu } else { cvtok, elv = true, enew.Interface() } - } else if tool.CanConvert(&el, tgtelemtype) { + } else if ref.CanConvert(&el, tgtelemtype) { enew = el.Convert(tgtelemtype) cvtok, elv = true, enew.Interface() } @@ -1046,12 +1047,12 @@ func _sliceMergeOperation(c *cpController, params *Params, src, tgt reflect.Valu } func copyArray(c *cpController, params *Params, from, to reflect.Value) (err error) { - if tool.IsZero(from) && params.isGroupedFlagOKDeeply(cms.OmitIfZero, cms.OmitIfEmpty) { + if ref.IsZero(from) && params.isGroupedFlagOKDeeply(cms.OmitIfZero, cms.OmitIfEmpty) { return } - src := tool.Rindirect(from) - tgt, tgtptr := tool.Rdecode(to) + src := ref.Rindirect(from) + tgt, tgtptr := ref.Rdecode(to) // if !to.CanAddr() && params != nil { // if !params.isStruct() { @@ -1075,12 +1076,12 @@ func copyArray(c *cpController, params *Params, from, to reflect.Value) (err err if processed, err = tryConverters(c, params, &from, &tgt, &tgttyp, false); processed { return } - // log.Panicf("[copySlice] unsupported transforming: from slice -> %v,", typfmtv(&tgt)) - err = ErrCannotCopy.FormatWith(tool.Valfmt(&src), tool.Typfmtv(&src), tool.Valfmt(&tgt), tool.Typfmtv(&tgt)) + // logz.Panicf("[copySlice] unsupported transforming: from slice -> %v,", typfmtv(&tgt)) + err = ErrCannotCopy.FormatWith(ref.Valfmt(&src), ref.Typfmtv(&src), ref.Valfmt(&tgt), ref.Typfmtv(&tgt)) return } - if tool.IsZero(tgt) && params.isGroupedFlagOKDeeply(cms.OmitIfTargetZero, cms.OmitIfTargetEmpty) { + if ref.IsZero(tgt) && params.isGroupedFlagOKDeeply(cms.OmitIfTargetZero, cms.OmitIfTargetEmpty) { return } @@ -1095,7 +1096,7 @@ func copyArray(c *cpController, params *Params, from, to reflect.Value) (err err for i := 0; i < cnt; i++ { se := src.Index(i) setyp := se.Type() - dbglog.Log("src.el.typ: %v, tgt.el.typ: %v", tool.Typfmt(setyp), eltyp) + dbglog.Log("src.el.typ: %v, tgt.el.typ: %v", ref.Typfmt(setyp), eltyp) if se.IsValid() { if setyp.AssignableTo(eltyp) { tgt.Index(i).Set(se) @@ -1127,7 +1128,7 @@ func copyMap(c *cpController, params *Params, from, to reflect.Value) (err error } var tgt, tgtptr reflect.Value - tgt, tgtptr = tool.Rdecode(to) + tgt, tgtptr = ref.Rdecode(to) if to != tgtptr { //nolint:govet //how should i do //TODO needs checked-review err = c.copyTo(params, from, tgtptr) // unwrap the pointer return @@ -1135,17 +1136,17 @@ func copyMap(c *cpController, params *Params, from, to reflect.Value) (err error tk, typ := tgt.Kind(), tgt.Type() if tk != reflect.Map { - dbglog.Log("from map -> %v", tool.Typfmt(typ)) + dbglog.Log("from map -> %v", ref.Typfmt(typ)) // copy map to String, Slice, Struct var processed bool if processed, err = tryConverters(c, params, &from, &tgt, &typ, false); !processed { err = ErrCannotCopy.WithErrors(err). - FormatWith(tool.Valfmt(&from), tool.Typfmtv(&from), tool.Valfmt(&tgt), tool.Typfmtv(&tgt)) + FormatWith(ref.Valfmt(&from), ref.Typfmtv(&from), ref.Valfmt(&tgt), ref.Typfmtv(&tgt)) } return } - tgtNil := tool.IsNil(tgt) + tgtNil := ref.IsNil(tgt) if tgtNil && params.isGroupedFlagOKDeeply(cms.OmitIfTargetZero, cms.OmitIfTargetEmpty) { return } @@ -1156,7 +1157,7 @@ func copyMap(c *cpController, params *Params, from, to reflect.Value) (err error // By default, the nested copyTo() cannot print log msg via dbglog.Log // so we get clearer logging lines for debugging. // To enabled them, use build tags 'moremaplog'. - defer dbglog.DisableLog()() + defer dbglog.DisableLogAndDefer()() for _, flag := range []cms.CopyMergeStrategy{cms.MapMerge, cms.MapCopy} { if params.isGroupedFlagOKDeeply(flag) { @@ -1239,7 +1240,7 @@ func mapMergePreSetter(c *cpController, ck, cv reflect.Value) (processed bool, e func mergeOneKeyInMap(c *cpController, params *Params, src, tgt, tgtptr, key reflect.Value) (err error) { var processed bool - dbglog.Colored(color.LightMagenta, " copying key '%v': (%v) -> (?)", tool.Valfmt(&key), tool.Valfmtv(src.MapIndex(key))) + dbglog.Colored(color.FgLightMagenta, " copying key '%v': (%v) -> (?)", ref.Valfmt(&key), ref.Valfmtv(src.MapIndex(key))) var ck reflect.Value if ck, err = cloneMapKey(c, params, tgt, key); err != nil { @@ -1253,7 +1254,7 @@ func mergeOneKeyInMap(c *cpController, params *Params, src, tgt, tgtptr, key ref return } if newelemcreated { - cv := tool.Rindirect(tgtval) + cv := ref.Rindirect(tgtval) if processed, err = mapMergePreSetter(c, ck, cv); processed { return } @@ -1261,21 +1262,21 @@ func mergeOneKeyInMap(c *cpController, params *Params, src, tgt, tgtptr, key ref if err = c.copyTo(params, originalValue, tgtval); err != nil { return } - dbglog.Log(" original item value: m[%v] => %v", tool.Valfmtptr(&ck), tool.Valfmt(&cv)) + dbglog.Log(" original item value: m[%v] => %v", ref.Valfmtptr(&ck), ref.Valfmt(&cv)) return } - dbglog.Log(" duplicated/gotten: %v", tool.Valfmtptr(&tgtval)) + dbglog.Log(" duplicated/gotten: %v", ref.Valfmtptr(&tgtval)) eltyp := tgt.Type().Elem() // get map value type - eltypind, _ := tool.Rskiptype(eltyp, reflect.Ptr) + eltypind, _ := ref.Rskiptype(eltyp, reflect.Ptr) var ptrToCopyValue, cv reflect.Value if eltypind.Kind() == reflect.Interface { //nolint:nestif //keep it var tt reflect.Type - tgtvalind, _ := tool.Rdecode(tgtval) - if !tgtval.IsValid() || tool.IsZero(tgtval) { + tgtvalind, _ := ref.Rdecode(tgtval) + if !tgtval.IsValid() || ref.IsZero(tgtval) { srcval := src.MapIndex(ck) - if !srcval.IsValid() || tool.IsZero(srcval) { + if !srcval.IsValid() || ref.IsZero(srcval) { tgtvalind = srcval tt = tgtvalind.Type() } else { @@ -1284,7 +1285,7 @@ func mergeOneKeyInMap(c *cpController, params *Params, src, tgt, tgtptr, key ref } else { tt = tgtvalind.Type() } - dbglog.Log(" tgtval: [%v] %v, ind: %v | tt: %v", tool.Typfmtv(&tgtval), tool.Valfmt(&tgtval), tool.Typfmtv(&tgtvalind), tool.Typfmt(tt)) + dbglog.Log(" tgtval: [%v] %v, ind: %v | tt: %v", ref.Typfmtv(&tgtval), ref.Valfmt(&tgtval), ref.Typfmtv(&tgtvalind), ref.Typfmt(tt)) ptrToCopyValue, cv = newFromType(tt) if processed, err = mapMergePreSetter(c, ck, cv); processed { return @@ -1311,7 +1312,7 @@ func mergeOneKeyInMap(c *cpController, params *Params, src, tgt, tgtptr, key ref // }() } - dbglog.Log(" ptrToCopyValue.type: %v, eltypind: %v", tool.Typfmtv(&ptrToCopyValue), tool.Typfmt(eltypind)) + dbglog.Log(" ptrToCopyValue.type: %v, eltypind: %v", ref.Typfmtv(&ptrToCopyValue), ref.Typfmt(eltypind)) if err = c.copyTo(params, tgtval, ptrToCopyValue); err != nil { return } @@ -1324,17 +1325,17 @@ func mergeOneKeyInMap(c *cpController, params *Params, src, tgt, tgtptr, key ref func matchTypeAndSetMapIndex(c *cpController, params *Params, m, key, val reflect.Value) { ve := m.Type().Elem() - cv := tool.Rindirect(val) + cv := ref.Rindirect(val) if cv.Type() == ve { trySetMapIndex(c, params, m, key, cv) - dbglog.Log(" map.item set to val.ind: %v -> %v", tool.Valfmt(&key), tool.Valfmt(&cv)) + dbglog.Log(" map.item set to val.ind: %v -> %v", ref.Valfmt(&key), ref.Valfmt(&cv)) } else if val.Type() == ve { trySetMapIndex(c, params, m, key, val) - dbglog.Log(" map.item set to val: %v -> %v", tool.Valfmt(&key), tool.Valfmt(&val)) + dbglog.Log(" map.item set to val: %v -> %v", ref.Valfmt(&key), ref.Valfmt(&val)) } else if val.Kind() == reflect.Ptr && val.Type().Elem() == ve { // tgtval is ptr to elem? such as tgtval got *bool, and the map[ck] => bool trySetMapIndex(c, params, m, key, val.Elem()) - dbglog.Log(" map.item set to val.elem: %v -> %v", tool.Valfmt(&key), tool.Valfmtv(val.Elem())) - dbglog.Log(" map: %v", tool.Valfmt(&m)) + dbglog.Log(" map.item set to val.elem: %v -> %v", ref.Valfmt(&key), ref.Valfmtv(val.Elem())) + dbglog.Log(" map: %v", ref.Valfmt(&m)) } else if ve.Kind() == reflect.Interface { // the map is map[key]interface{} ?, so the val can be anything. if val.Kind() == reflect.Ptr { trySetMapIndex(c, params, m, key, val.Elem()) @@ -1342,18 +1343,18 @@ func matchTypeAndSetMapIndex(c *cpController, params *Params, m, key, val reflec trySetMapIndex(c, params, m, key, val) } } else { - log.Warnf("cannot setMapIndex for key '%v' since val type mismatched: desired elem typ = %v, real tgt val.typ = %v.", tool.Valfmt(&key), tool.Typfmt(ve), tool.Typfmtv(&val)) + logz.Warn("cannot setMapIndex for key since val type mismatched:", "key", ref.Valfmt(&key), "desired-elem-typ", ref.Typfmt(ve), "real-tgt-val.typ", ref.Typfmtv(&val)) } } func trySetMapIndex(c *cpController, params *Params, m, key, val reflect.Value) { - // dbglog.Colored(color.LightMagenta, " setting map index: %v -> %v", tool.Valfmt(&key), tool.Valfmt(&val)) + // dbglog.Colored(color.FgLightMagenta, " setting map index: %v -> %v", tool.Valfmt(&key), tool.Valfmt(&val)) if params != nil && params.controller != nil && params.accessor != nil && params.controller.copyUnexportedFields { if fld := params.accessor.StructField(); fld != nil { // in a struct - if !tool.IsExported(fld) { + if !ref.IsExported(fld) { dbglog.Log(" unexported field %q (typ: %v): key '%v' => val '%v'", - fld.Name, tool.Typfmt(fld.Type), tool.Valfmt(&key), tool.Valfmt(&val)) + fld.Name, ref.Typfmt(fld.Type), ref.Valfmt(&key), ref.Valfmt(&val)) cl.SetUnexportedFieldIfMap(m, key, val) return } @@ -1376,7 +1377,7 @@ func newFromType(typ reflect.Type) (valptr, val reflect.Value) { ptr, _ := newFromType(typ.Elem()) v.Set(ptr) valptr, val = vp, v // .Elem() - dbglog.Log("creating new object for type %v: %+v", tool.Typfmt(typ), tool.Valfmt(&valptr)) + dbglog.Log("creating new object for type %v: %+v", ref.Typfmt(typ), ref.Valfmt(&valptr)) } else if k == reflect.Slice { valptr = reflect.MakeSlice(typ, 0, 0) val = valptr @@ -1422,12 +1423,12 @@ func ensureMapPtrValue(c *cpController, params *Params, m, key, originalValue re val = m.MapIndex(key) vk := val.Kind() if vk == reflect.Ptr { //nolint:nestif //keep it - if tool.IsNil(val) { + if ref.IsNil(val) { typOfValueOfMap := m.Type().Elem() // make new instance of type pointed by pointer val, _ = newFromType(typOfValueOfMap) // trySetMapIndex(c, params, m, key, val) // and set the new pointer into map ptr = true // - dbglog.Log(" ensureMapPtrValue:val.typ: %v, key.typ: %v | '%v' -> %v", tool.Typfmt(typOfValueOfMap), tool.Typfmtv(&key), tool.Valfmt(&key), tool.Valfmtptr(&val)) + dbglog.Log(" ensureMapPtrValue:val.typ: %v, key.typ: %v | '%v' -> %v", ref.Typfmt(typOfValueOfMap), ref.Typfmtv(&key), ref.Valfmt(&key), ref.Valfmtptr(&val)) } else { // dbglog.Log(" ensureMapPtrValue: do nothing because val's is not nil") } @@ -1436,14 +1437,14 @@ func ensureMapPtrValue(c *cpController, params *Params, m, key, originalValue re if typOfValueOfMap.Kind() != reflect.Interface { var valelem reflect.Value val, valelem = newFromType(typOfValueOfMap) - dbglog.Log(" ensureMapPtrValue:val.typ: %v, key.typ: %v | '%v' -> %v", tool.Typfmt(typOfValueOfMap), tool.Typfmtv(&key), tool.Valfmt(&key), tool.Valfmtptr(&valelem)) + dbglog.Log(" ensureMapPtrValue:val.typ: %v, key.typ: %v | '%v' -> %v", ref.Typfmt(typOfValueOfMap), ref.Typfmtv(&key), ref.Valfmt(&key), ref.Valfmtptr(&valelem)) trySetMapIndex(c, params, m, key, valelem) ptr = true // val = vind - } else if originalValue.IsValid() && !tool.IsZero(originalValue) { // if original value is zero, no copying needed. - typ := tool.Rdecodesimple(originalValue).Type() + } else if originalValue.IsValid() && !ref.IsZero(originalValue) { // if original value is zero, no copying needed. + typ := ref.Rdecodesimple(originalValue).Type() val, _ = newFromTypeEspSlice(typ) ptr = true - dbglog.Log(" ensureMapPtrValue:val.typ: %v, key.typ: %v | '%v' -> %v", tool.Typfmt(typ), tool.Typfmtv(&key), tool.Valfmt(&key), tool.Valfmtptr(&val)) + dbglog.Log(" ensureMapPtrValue:val.typ: %v, key.typ: %v | '%v' -> %v", ref.Typfmt(typ), ref.Typfmtv(&key), ref.Valfmt(&key), ref.Valfmtptr(&val)) if err = c.copyTo(params, originalValue, val); err != nil { return } @@ -1452,7 +1453,7 @@ func ensureMapPtrValue(c *cpController, params *Params, m, key, originalValue re return } trySetMapIndex(c, params, m, key, val) - dbglog.Log(" ensureMapPtrValue:val.typ: %v, key.typ: %v | '%v' -> %v | DONE", tool.Typfmt(typ), tool.Typfmtv(&key), tool.Valfmt(&key), tool.Valfmtptr(&val)) + dbglog.Log(" ensureMapPtrValue:val.typ: %v, key.typ: %v | '%v' -> %v | DONE", ref.Typfmt(typ), ref.Typfmtv(&key), ref.Valfmt(&key), ref.Valfmtptr(&val)) } else { // dbglog.Log(" ensureMapPtrValue: do nothing because val and src-val are both invalid, so needn't copy.") } @@ -1463,16 +1464,16 @@ func ensureMapPtrValue(c *cpController, params *Params, m, key, originalValue re func cloneMapKey(c *cpController, params *Params, tgt, key reflect.Value) (ck reflect.Value, err error) { keyType := tgt.Type().Key() ptrToCopyKey := reflect.New(keyType) - dbglog.Log(" cloneMapKey(%v): tgt(map).type: %v, tgt.key.type: %v, ptrToCopyKey.type: %v", tool.Valfmt(&key), tool.Typfmtv(&tgt), tool.Typfmt(keyType), tool.Typfmtv(&ptrToCopyKey)) + dbglog.Log(" cloneMapKey(%v): tgt(map).type: %v, tgt.key.type: %v, ptrToCopyKey.type: %v", ref.Valfmt(&key), ref.Typfmtv(&tgt), ref.Typfmt(keyType), ref.Typfmtv(&ptrToCopyKey)) ck = ptrToCopyKey.Elem() emptyParams := newParams() // use an empty params for just copying map key so the current processing struct fields won't be cared in this special child copier if err = c.copyTo(emptyParams, key, ck); err != nil { - dbglog.Err(" cloneMapKey(%v) error on copyTo: %+v", tool.Valfmt(&key), err) // early break-point here + dbglog.Err(" cloneMapKey(%v) error on copyTo: %+v", ref.Valfmt(&key), err) // early break-point here return } - dbglog.Log(" cloned: '%v'", tool.Valfmtptr(&ck)) + dbglog.Log(" cloned: '%v'", ref.Valfmtptr(&ck)) return } @@ -1483,24 +1484,24 @@ func cloneMapKey(c *cpController, params *Params, tgt, key reflect.Value) (ck re // func copyUintptr(c *cpController, params *Params, from, to reflect.Value) (err error) { - tgt := tool.Rindirect(to) + tgt := ref.Rindirect(to) if tgt.CanSet() { tgt.Set(from) } else { // to.SetPointer(from.Pointer()) dbglog.Log(" copy uintptr not support: %v -> %v", from.Kind(), to.Kind()) - err = ErrCannotCopy.FormatWith(tool.Valfmt(&from), tool.Typfmtv(&from), tool.Valfmt(&to), tool.Typfmtv(&to)) + err = ErrCannotCopy.FormatWith(ref.Valfmt(&from), ref.Typfmtv(&from), ref.Valfmt(&to), ref.Typfmtv(&to)) } return } func copyUnsafePointer(c *cpController, params *Params, from, to reflect.Value) (err error) { - tgt := tool.Rindirect(to) + tgt := ref.Rindirect(to) if tgt.CanSet() { tgt.Set(from) } else { dbglog.Log(" copy unsafe pointer not support: %v -> %v", from.Kind(), to.Kind()) - err = ErrCannotCopy.FormatWith(tool.Valfmt(&from), tool.Typfmtv(&from), tool.Valfmt(&to), tool.Typfmtv(&to)) + err = ErrCannotCopy.FormatWith(ref.Valfmt(&from), ref.Typfmtv(&from), ref.Valfmt(&to), ref.Typfmtv(&to)) } return } @@ -1508,7 +1509,7 @@ func copyUnsafePointer(c *cpController, params *Params, from, to reflect.Value) // copyFunc never used. // Deprecated always. func copyFunc(c *cpController, params *Params, from, to reflect.Value) (err error) { //nolint:unused,deadcode //reserved - tgt := tool.Rindirect(to) + tgt := ref.Rindirect(to) if tgt.CanSet() { tgt.Set(from) return @@ -1528,14 +1529,14 @@ func copyFunc(c *cpController, params *Params, from, to reflect.Value) (err erro } dbglog.Log(" function pointer copied: %v (%v) -> %v", from.Kind(), from.Interface(), to.Kind()) } else { - err = ErrCannotCopy.FormatWith(tool.Valfmt(&from), tool.Typfmtv(&from), tool.Valfmt(&to), tool.Typfmtv(&to)) + err = ErrCannotCopy.FormatWith(ref.Valfmt(&from), ref.Typfmtv(&from), ref.Valfmt(&to), ref.Typfmtv(&to)) } return } func copyChan(c *cpController, params *Params, from, to reflect.Value) (err error) { - tgt := tool.Rindirect(to) + tgt := ref.Rindirect(to) if tgt.CanSet() { dbglog.Log(" copy chan: %v (%v) -> %v (%v)", from.Kind(), from.Type(), tgt.Kind(), tgt.Type()) tgt.Set(from) @@ -1562,8 +1563,8 @@ func copyDefaultHandler(c *cpController, params *Params, from, to reflect.Value) } } - fromind, toind := tool.Rdecodesimple(from), tool.Rdecodesimple(to) - dbglog.Log(" copyDefaultHandler: %v -> %v | %v", tool.Typfmtv(&fromind), tool.Typfmtv(&toind), tool.Typfmtv(&to)) + fromind, toind := ref.Rdecodesimple(from), ref.Rdecodesimple(to) + dbglog.Log(" copyDefaultHandler: %v -> %v | %v", ref.Typfmtv(&fromind), ref.Typfmtv(&toind), ref.Typfmtv(&to)) // //////////////// source is primitive types but target isn't its var processed bool @@ -1600,12 +1601,12 @@ func copyDefaultHandler(c *cpController, params *Params, from, to reflect.Value) //nolint:lll //keep it func tryCopyPrimitiveToPrimitive(params *Params, from, fromind, to, toind reflect.Value, sourceType, targetType, toIndType reflect.Type) (stop bool, err error) { stop = true - if tool.CanConvert(&fromind, toIndType) { + if ref.CanConvert(&fromind, toIndType) { var val = fromind.Convert(toIndType) err = setTargetValue1(params, to, toind, val) return } - if tool.CanConvert(&from, to.Type()) && to.CanSet() { + if ref.CanConvert(&from, to.Type()) && to.CanSet() { var val = from.Convert(to.Type()) err = setTargetValue1(params, to, toind, val) return @@ -1616,7 +1617,7 @@ func tryCopyPrimitiveToPrimitive(params *Params, from, fromind, to, toind reflec } else if to.CanSet() { to.Set(fromind) } else { - err = ErrCannotSet.FormatWith(fromind, tool.Typfmtv(&fromind), toind, tool.Typfmtv(&toind)) + err = ErrCannotSet.FormatWith(fromind, ref.Typfmtv(&fromind), toind, ref.Typfmtv(&toind)) } return } @@ -1628,7 +1629,7 @@ func tryCopyPrimitiveToPrimitive(params *Params, from, fromind, to, toind reflec func copyPrimitiveToComposite(c *cpController, params *Params, from, to reflect.Value, desiredType reflect.Type) (processed bool, err error) { switch tk := desiredType.Kind(); tk { //nolint:exhaustive //no need case reflect.Slice: - dbglog.Log(" copyPrimitiveToComposite: %v -> %v | %v", tool.Typfmtv(&from), tool.Typfmt(desiredType), tool.Typfmtv(&to)) + dbglog.Log(" copyPrimitiveToComposite: %v -> %v | %v", ref.Typfmtv(&from), ref.Typfmt(desiredType), ref.Typfmtv(&to)) eltyp := desiredType.Elem() elnew := reflect.New(eltyp) @@ -1637,11 +1638,11 @@ func copyPrimitiveToComposite(c *cpController, params *Params, from, to reflect. } elnewelem := elnew.Elem() - dbglog.Log(" source converted: %v (%v)", tool.Valfmt(&elnewelem), tool.Typfmtv(&elnewelem)) + dbglog.Log(" source converted: %v (%v)", ref.Valfmt(&elnewelem), ref.Typfmtv(&elnewelem)) slice := reflect.MakeSlice(reflect.SliceOf(eltyp), 1, 1) slice.Index(0).Set(elnewelem) - dbglog.Log(" source converted: %v (%v)", tool.Valfmt(&slice), tool.Typfmtv(&slice)) + dbglog.Log(" source converted: %v (%v)", ref.Valfmt(&slice), ref.Typfmtv(&slice)) err = copySlice(c, params, slice, to) processed = true @@ -1653,7 +1654,7 @@ func copyPrimitiveToComposite(c *cpController, params *Params, from, to reflect. // not support case reflect.Func: - tgt := tool.Rdecodesimple(to) + tgt := ref.Rdecodesimple(to) processed, err = true, copyToFuncImpl(c, from, tgt, tgt.Type()) } @@ -1671,8 +1672,8 @@ func setTargetValue1(params *Params, to, toind, newval reflect.Value) (err error } if err == nil { err = ErrUnknownState.WithTaggedData(errors.TaggedData{ // record the sites - "source": tool.Valfmt(&toind), - "target": tool.Valfmt(&newval), + "source": ref.Valfmt(&toind), + "target": ref.Valfmt(&newval), }) } return @@ -1685,7 +1686,7 @@ func setTargetValue2(params *Params, to, newval reflect.Value) (err error) { } // else do nothing return } - + // const unexportedR = true // if unexportedR { // if copyUnexportedFields, isExported := params.dstFieldIsExportedR(); !isExported { @@ -1699,7 +1700,7 @@ func setTargetValue2(params *Params, to, newval reflect.Value) (err error) { // if params != nil && params.dstDecoded != nil { // k = params.dstDecoded.Kind() // } - // + // // if k == reflect.Struct && params.accessor != nil && !tool.IsExported(params.accessor.StructField()) { // if params.controller.copyUnexportedFields { // cl.SetUnexportedField(to, newval) @@ -1717,8 +1718,8 @@ func setTargetValue2(params *Params, to, newval reflect.Value) (err error) { } err = ErrUnknownState.WithTaggedData(errors.TaggedData{ // record the sites - "source": tool.Valfmt(&to), - "target": tool.Valfmt(&newval), + "source": ref.Valfmt(&to), + "target": ref.Valfmt(&newval), }) return } diff --git a/ftor_test.go b/ftor_test.go index 84b0d82..434532a 100644 --- a/ftor_test.go +++ b/ftor_test.go @@ -4,7 +4,7 @@ import ( "strconv" "github.com/hedzr/evendeep/flags/cms" - "github.com/hedzr/evendeep/internal/tool" + "github.com/hedzr/evendeep/ref" "github.com/hedzr/evendeep/typ" "reflect" @@ -84,7 +84,7 @@ func TestCopySlice_differModes(t *testing.T) { var src = reflect.ValueOf(&so) var tgt = reflect.ValueOf(&to) - err = copySlice(c, params, tool.Rdecodesimple(src), tool.Rdecodesimple(tgt)) + err = copySlice(c, params, ref.Rdecodesimple(src), ref.Rdecodesimple(tgt)) if err != nil { t.Errorf("bad: %v", err) } else { @@ -94,7 +94,7 @@ func TestCopySlice_differModes(t *testing.T) { to = []int{1} tgt = reflect.ValueOf(&to) - err = copySlice(c, params, tool.Rdecodesimple(src), tool.Rdecodesimple(tgt)) + err = copySlice(c, params, ref.Rdecodesimple(src), ref.Rdecodesimple(tgt)) if err != nil { t.Errorf("bad: %v", err) } else { @@ -104,7 +104,7 @@ func TestCopySlice_differModes(t *testing.T) { to = []int{1} tgt = reflect.ValueOf(&to) - err = copySlice(c, newParams(withFlags(cms.SliceCopyAppend), withOwnersSimple(c, nil)), tool.Rdecodesimple(src), tool.Rdecodesimple(tgt)) + err = copySlice(c, newParams(withFlags(cms.SliceCopyAppend), withOwnersSimple(c, nil)), ref.Rdecodesimple(src), ref.Rdecodesimple(tgt)) if err != nil { t.Errorf("bad: %v", err) } else { @@ -114,7 +114,7 @@ func TestCopySlice_differModes(t *testing.T) { to = []int{} tgt = reflect.ValueOf(&to) - err = copySlice(c, newParams(withFlags(cms.SliceCopyAppend), withOwnersSimple(c, nil)), tool.Rdecodesimple(src), tool.Rdecodesimple(tgt)) + err = copySlice(c, newParams(withFlags(cms.SliceCopyAppend), withOwnersSimple(c, nil)), ref.Rdecodesimple(src), ref.Rdecodesimple(tgt)) if err != nil { t.Errorf("bad: %v", err) } else { @@ -124,7 +124,7 @@ func TestCopySlice_differModes(t *testing.T) { to = []int{2, 9, 1} tgt = reflect.ValueOf(&to) - err = copySlice(c, newParams(withFlags(cms.SliceCopyAppend), withOwnersSimple(c, nil)), tool.Rdecodesimple(src), tool.Rdecodesimple(tgt)) + err = copySlice(c, newParams(withFlags(cms.SliceCopyAppend), withOwnersSimple(c, nil)), ref.Rdecodesimple(src), ref.Rdecodesimple(tgt)) if err != nil { t.Errorf("bad: %v", err) } else { @@ -136,7 +136,7 @@ func TestCopySlice_differModes(t *testing.T) { src = reflect.ValueOf(&so) to = []int{2, 9, 1} tgt = reflect.ValueOf(&to) - err = copySlice(c, newParams(withFlags(cms.SliceMerge), withOwnersSimple(c, nil)), tool.Rdecodesimple(src), tool.Rdecodesimple(tgt)) + err = copySlice(c, newParams(withFlags(cms.SliceMerge), withOwnersSimple(c, nil)), ref.Rdecodesimple(src), ref.Rdecodesimple(tgt)) if err != nil { t.Errorf("bad: %v", err) } else { @@ -146,7 +146,7 @@ func TestCopySlice_differModes(t *testing.T) { to = []int{3, 77, 2, 15} tgt = reflect.ValueOf(&to) - err = copySlice(c, newParams(withFlags(cms.SliceMerge), withOwnersSimple(c, nil)), tool.Rdecodesimple(src), tool.Rdecodesimple(tgt)) + err = copySlice(c, newParams(withFlags(cms.SliceMerge), withOwnersSimple(c, nil)), ref.Rdecodesimple(src), ref.Rdecodesimple(tgt)) if err != nil { t.Errorf("bad: %v", err) } else { @@ -169,7 +169,7 @@ func TestCopySlice_mergeMode(t *testing.T) { var src = reflect.ValueOf(&so) var tgt = reflect.ValueOf(&to) - err = copySlice(c, params, tool.Rdecodesimple(src), tool.Rdecodesimple(tgt)) + err = copySlice(c, params, ref.Rdecodesimple(src), ref.Rdecodesimple(tgt)) if err != nil { t.Errorf("bad: %v", err) } else { @@ -179,7 +179,7 @@ func TestCopySlice_mergeMode(t *testing.T) { to = []int{2, 77} tgt = reflect.ValueOf(&to) - err = copySlice(c, params, tool.Rdecodesimple(src), tool.Rdecodesimple(tgt)) + err = copySlice(c, params, ref.Rdecodesimple(src), ref.Rdecodesimple(tgt)) if err != nil { t.Errorf("bad: %v", err) } else { @@ -246,7 +246,7 @@ func TestPointerOfPre(t *testing.T) { ptr1 := av.Pointer() t.Logf("a.pointer = %v", strconv.FormatUint(uint64(ptr1), 16)) np := reflect.New(av.Type()) - t.Logf("np = %v, typ = %v", tool.Valfmt(&np), tool.Typfmtv(&np)) + t.Logf("np = %v, typ = %v", ref.Valfmt(&np), ref.Typfmtv(&np)) typ := av.Type() // type of *A val := reflect.New(typ) diff --git a/params.go b/params.go index 7d0c810..858dcf4 100644 --- a/params.go +++ b/params.go @@ -1,16 +1,15 @@ package evendeep import ( - "github.com/hedzr/log" + "reflect" + "unsafe" "github.com/hedzr/evendeep/dbglog" "github.com/hedzr/evendeep/flags" "github.com/hedzr/evendeep/flags/cms" "github.com/hedzr/evendeep/internal/cl" - "github.com/hedzr/evendeep/internal/tool" - - "reflect" - "unsafe" + "github.com/hedzr/evendeep/ref" + logz "github.com/hedzr/logg/slog" ) // Params is params package. @@ -92,7 +91,7 @@ func withOwners(c *cpController, ownerParams *Params, ownerSource, ownerTarget, var st, tt reflect.Type if p.srcDecoded == nil && p.srcOwner != nil { - d, _ := tool.Rdecode(*p.srcOwner) + d, _ := ref.Rdecode(*p.srcOwner) p.srcDecoded = &d if p.srcOwner.IsValid() { p.srcType = p.srcOwner.Type() @@ -105,13 +104,13 @@ func withOwners(c *cpController, ownerParams *Params, ownerSource, ownerTarget, p.dstType = p.dstOwner.Type() } else if p.srcOwner != nil { st = p.srcOwner.Type() - st = tool.RindirectType(st) + st = ref.RindirectType(st) p.parseSourceStruct(ownerParams, st) p.dstType = st } if p.dstDecoded == nil && p.dstOwner != nil { - d, _ := tool.Rdecode(*p.dstOwner) + d, _ := ref.Rdecode(*p.dstOwner) p.dstDecoded = &d } @@ -120,7 +119,7 @@ func withOwners(c *cpController, ownerParams *Params, ownerSource, ownerTarget, p.parseTargetStruct(ownerParams, tt) } else if p.dstOwner != nil { tt = p.dstOwner.Type() - tt = tool.RindirectType(tt) + tt = ref.RindirectType(tt) p.parseTargetStruct(ownerParams, tt) } @@ -214,7 +213,7 @@ func (params *Params) dstFieldIsExportedR() (copyUnexportedFields, isExported bo return false, true // non-struct-field target, treat it as exported } - isExported, copyUnexportedFields = tool.IsExported(params.accessor.StructField()), params.controller.copyUnexportedFields + isExported, copyUnexportedFields = ref.IsExported(params.accessor.StructField()), params.controller.copyUnexportedFields if isExported && params.owner != nil { copyUnexportedFields, isExported = params.owner.dstFieldIsExportedR() } @@ -231,9 +230,9 @@ func (params *Params) processUnexportedField(target, newval reflect.Value) (proc } if fld := params.accessor.StructField(); fld != nil { // in a struct - if !tool.IsExported(fld) { + if !ref.IsExported(fld) { dbglog.Log(" unexported field %q (typ: %v): old(%v) -> new(%v)", - fld.Name, tool.Typfmt(fld.Type), tool.Valfmt(&target), tool.Valfmt(&newval)) + fld.Name, ref.Typfmt(fld.Type), ref.Valfmt(&target), ref.Valfmt(&newval)) cl.SetUnexportedField(target, newval) processed = true } @@ -307,10 +306,10 @@ func (params *Params) addChildParams(ppChild *Params) { params.children = make(map[string]*Params) } if _, ok := ppChild.children[fieldName]; ok { - log.Panicf("field %q exists, cannot iterate another field on the same name", fieldName) + logz.Panic("field exists, cannot iterate another field on the same name", "field", fieldName) } // if ppChild == nil { - // log.Panicf("setting nil Params for field %q, r u kidding me?", fieldName) + // logz.Panic("setting nil Params for field, r u kidding me?", "field", fieldName) // } params.children[fieldName] = ppChild diff --git a/structiterator.go b/structiterator.go index b3783e2..0a8738c 100644 --- a/structiterator.go +++ b/structiterator.go @@ -5,13 +5,12 @@ import ( "strings" "sync" - "github.com/hedzr/log" - "github.com/hedzr/evendeep/dbglog" "github.com/hedzr/evendeep/flags/cms" "github.com/hedzr/evendeep/internal" "github.com/hedzr/evendeep/internal/cl" - "github.com/hedzr/evendeep/internal/tool" + "github.com/hedzr/evendeep/ref" + logz "github.com/hedzr/logg/slog" ) // @@ -69,7 +68,7 @@ func (table *fieldsTableT) isReservedPackage(field *reflect.StructField, typ ref func (table *fieldsTableT) getAllFields(structValue reflect.Value, autoexpandstruct bool) fieldsTableT { table.autoExpandStruct = autoexpandstruct - structValue, _ = tool.Rdecode(structValue) + structValue, _ = ref.Rdecode(structValue) if structValue.Kind() != reflect.Struct { return *table } @@ -108,7 +107,7 @@ func (table *fieldsTableT) safeGetStructFieldValueInd(structValue *reflect.Value //nolint:lll //keep it func (table *fieldsTableT) getFields(structValue *reflect.Value, structType reflect.Type, fieldName string, fi int) (ret tableRecordsT) { - st := tool.Rdecodetypesimple(structType) + st := ref.Rdecodetypesimple(structType) if st.Kind() != reflect.Struct { return } @@ -119,7 +118,7 @@ func (table *fieldsTableT) getFields(structValue *reflect.Value, structType refl sf := structType.Field(i) sftyp := sf.Type - sftypind := tool.RindirectType(sftyp) + sftypind := ref.RindirectType(sftyp) svind := table.safeGetStructFieldValueInd(structValue, i) sftypindKind := sftypind.Kind() isStruct := sftypindKind == reflect.Struct @@ -131,7 +130,7 @@ func (table *fieldsTableT) getFields(structValue *reflect.Value, structType refl if internal.VerboseStructIterating { // only printed on `-tags="structiterating,verbose" dbglog.Log(" field %d: %v (%v) (%v) || %v", i, sf.Name, - tool.Typfmt(sftyp), tool.Typfmt(sftypind), tr.FieldValue()) + ref.Typfmt(sftyp), ref.Typfmt(sftypind), tr.FieldValue()) } if !tr.ShouldIgnore() { @@ -148,7 +147,7 @@ func (table *fieldsTableT) getFields(structValue *reflect.Value, structType refl } } else if internal.VerboseStructIterating { dbglog.Log(" field %d: %v (%v) (%v) || %v", i, sf.Name, - tool.Typfmt(sftyp), tool.Typfmt(sftypind), tool.Valfmtptr(tr.FieldValue())) + ref.Typfmt(sftyp), ref.Typfmt(sftypind), ref.Valfmtptr(tr.FieldValue())) } ret = append(ret, tr) @@ -161,7 +160,7 @@ func (table *fieldsTableT) tableRec(svind *reflect.Value, sf *reflect.StructFiel tr = new(tableRecT) tr.structField = sf - if tool.IsExported(sf) { + if ref.IsExported(sf) { tr.structFieldValue = svind } else if svind.CanAddr() { val := cl.GetUnexportedField(*svind) @@ -364,11 +363,11 @@ func (s *fieldAccessorT) Set(v reflect.Value) { // dbglog.Log(" target struct type: %v", tool.Typfmt(s.structType)) dbglog.Log(" setting struct.%q", s.structType.Field(s.index).Name) // if !tool.IsZero(*s.structValue) { - sv := tool.Rindirect(*s.structValue) + sv := ref.Rindirect(*s.structValue) fv := sv.Field(s.index) - dbglog.Log(" set %v (%v) -> struct.%q", tool.Valfmt(&v), tool.Typfmtv(&v), s.structType.Field(s.index).Name) - if v.IsValid() && !tool.IsZero(v) { - dbglog.Log(" set to v : %v", tool.Valfmt(&v)) + dbglog.Log(" set %v (%v) -> struct.%q", ref.Valfmt(&v), ref.Typfmtv(&v), s.structType.Field(s.index).Name) + if v.IsValid() && !ref.IsZero(v) { + dbglog.Log(" set to v : %v", ref.Valfmt(&v)) fv.Set(v) } else { dbglog.Log(" setToZero") @@ -379,10 +378,10 @@ func (s *fieldAccessorT) Set(v reflect.Value) { // } } else if s.structType.Kind() == reflect.Map { key := s.mapkey() - dbglog.Log(" set %v (%v) -> map[%v]", tool.Valfmt(&v), tool.Typfmtv(&v), tool.Valfmt(&key)) + dbglog.Log(" set %v (%v) -> map[%v]", ref.Valfmt(&v), ref.Typfmtv(&v), ref.Valfmt(&key)) s.structValue.SetMapIndex(key, v) } else { - dbglog.Wrn(` setting struct field value, but the container has type: %v`, tool.Typfmt(s.structType)) + dbglog.Wrn(` setting struct field value, but the container has type: %v`, ref.Typfmt(s.structType)) } } func (s *fieldAccessorT) SourceField() *tableRecT { return s.sourceTableRec } @@ -422,7 +421,7 @@ func (s *fieldAccessorT) FieldValue() *reflect.Value { if s.isStruct { if s.ValueValid() { - vind := tool.Rindirect(*s.structValue) + vind := ref.Rindirect(*s.structValue) if vind.IsValid() && s.index < vind.NumField() { r := vind.Field(s.index) return &r @@ -506,23 +505,23 @@ func (s *fieldAccessorT) ensurePtrField() (newed bool) { if s.isStruct && s.index < s.structType.NumField() { if s.structValue != nil { sf := s.structType.Field(s.index) - vind := tool.Rindirect(*s.structValue) + vind := ref.Rindirect(*s.structValue) // if tool.IsZero(vind) { // fv := vind.Field(s.index) // dbglog.Wrn(`zero value struct cannot .Field(): typ = %v, vind = %v | fv: %v`, tool.Typfmtv(&vind), tool.Valfmt(&vind), tool.Valfmt(&fv)) // return // } if vind.Kind() != reflect.Struct { - dbglog.Wrn(`vind isn't struct, cannot .Field(): typ = %v, vind = %v`, tool.Typfmtv(&vind), tool.Valfmt(&vind)) + dbglog.Wrn(`vind isn't struct, cannot .Field(): typ = %v, vind = %v`, ref.Typfmtv(&vind), ref.Valfmt(&vind)) return } fv := vind.Field(s.index) switch kind := sf.Type.Kind(); kind { //nolint:exhaustive //no need case reflect.Ptr: - if tool.IsNil(fv) { + if ref.IsNil(fv) { dbglog.Log(" autoNew") - if settable := fv.CanSet(); settable || !tool.IsExported(&sf) { // unexported field, try new it + if settable := fv.CanSet(); settable || !ref.IsExported(&sf) { // unexported field, try new it typ := sf.Type.Elem() nv := reflect.New(typ) if settable { @@ -532,7 +531,7 @@ func (s *fieldAccessorT) ensurePtrField() (newed bool) { } newed = true } else { - log.Warnf(" gave up since fv.CanSet is false. fv.typ: %v", tool.Typfmtv(&fv)) + logz.Warn(" gave up since fv.CanSet is false.", "fv.typ", ref.Typfmtv(&fv)) } } default: @@ -563,7 +562,7 @@ func (s *fieldAccessorT) mapkey() reflect.Value { // if err := fsc.CopyTo(nil, namev, kp.Elem()); err == nil { // key = kp.Elem() // } - log.Panicf(`unexpected type of key '%v': %v`, name, kk) + logz.Panic(`unexpected type of key`, "key", name, "kind", kk) } return key } @@ -585,7 +584,7 @@ func (s *structIteratorT) iipop() { } func (s *structIteratorT) iitop() *fieldAccessorT { if len(s.stack) == 0 { - log.Panicf(`unexpected iitop() on an empty stack`) + logz.Panic(`unexpected iitop() on an empty stack`) // return nil } return s.stack[len(s.stack)-1] @@ -610,13 +609,13 @@ func (s *structIteratorT) iitop() *fieldAccessorT { // // parent struct of the current field) // sf2 := reprev(position - 1) // if sf2 != nil { -// //log.Printf("prev.index = %v, prev.sv.valid = %v, sf = %v", prev.index, prev.ValueValid(), sf2) +// //logz.Printf("prev.index = %v, prev.sv.valid = %v, sf = %v", prev.index, prev.ValueValid(), sf2) // st = rdecodetypesimple(sf2.Type) -// //log.Printf("sf2.Type/st = %v", st) +// //logz.Printf("sf2.Type/st = %v", st) // if prev.index < st.NumField() { // fld := st.Field(prev.index) // sf = &fld -// //log.Printf("typ: %v, name: %v | %v", typfmt(sf.Type), sf.Name, sf) +// //logz.Printf("typ: %v, name: %v | %v", typfmt(sf.Type), sf.Name, sf) // } // } // } else { @@ -668,7 +667,7 @@ func (s *structIteratorT) MethodCallByName(name string) (mtd reflect.Method, v * if len(retv) > 0 { if len(retv) > 1 { errv := retv[len(retv)-1] - if tool.IsNil(errv) && tool.Iserrortype(mtd.Type.Out(len(retv)-1)) { + if ref.IsNil(errv) && ref.Iserrortype(mtd.Type.Out(len(retv)-1)) { v = &retv[0] } } else { @@ -729,8 +728,8 @@ func (s *structIteratorT) Next(params *Params, byName bool) (acc accessor, ok bo dbglog.Log(" | Next %d | src field: %v (%v) -> %v (%v) | autoexpd: (%v, %v)", s.srcIndex, accessorTmp.sourceTableRec.FieldName(), - tool.Typfmt(accessorTmp.srcStructField.Type), - accessorTmp.StructFieldName(), tool.Typfmt(accessorTmp.Type()), + ref.Typfmt(accessorTmp.srcStructField.Type), + accessorTmp.StructFieldName(), ref.Typfmt(accessorTmp.Type()), s.srcFields.autoExpandStruct, s.autoExpandStruct, ) s.dstIndex++ @@ -746,7 +745,7 @@ func (s *structIteratorT) Next(params *Params, byName bool) (acc accessor, ok bo if ok { dbglog.Log(" | Next %d | -> %v (%v)", s.dstIndex, - accessorTmp.StructFieldName(), tool.Typfmt(accessorTmp.Type())) + accessorTmp.StructFieldName(), ref.Typfmt(accessorTmp.Type())) s.dstIndex++ } } @@ -797,7 +796,7 @@ func (s *structIteratorT) doNextFieldByName(sourceTableRec *tableRecT, srcStruct dbglog.Log(" looking for field %q (src field: %q)", dstFieldName, srcStructField.Name) var tsf reflect.StructField - ts := tool.Rindirect(s.dstStruct) + ts := ref.Rindirect(s.dstStruct) tsf, ok = ts.Type().FieldByName(dstFieldName) if ok { dbglog.Log(" tsf: %v", tsf) @@ -814,7 +813,7 @@ func (s *structIteratorT) doNextFieldByName(sourceTableRec *tableRecT, srcStruct fieldTags: parseFieldTags(srcStructField.Tag, ""), } } else { - log.Warnf(" [WARN] dstFieldName %q NOT FOUND, it'll be ignored", dstFieldName) + logz.Warn(" [WARN] dstFieldName NOT FOUND, it'll be ignored", "dstFieldName", dstFieldName) s.dstIndex = -1 acc = &fieldAccessorT{ structValue: &ts, @@ -838,7 +837,7 @@ func (s *structIteratorT) doNext(srcFieldIsFuncAndTargetShouldNotExpand bool) (a var inretry bool if s.iiempty() { - vind := tool.Rindirect(s.dstStruct) + vind := ref.Rindirect(s.dstStruct) tind := vind.Type() lastone = s.iipush(&vind, tind, 0) } else { @@ -858,9 +857,9 @@ retryExpand: if field != nil { //nolint:nestif //keep it // tind := field.Type // rindirectType(field.Type) if s.autoExpandStruct { - tind := tool.RindirectType(field.Type) + tind := ref.RindirectType(field.Type) k1 := tind.Kind() - dbglog.Log(" typ: %v, name: %v | %v", tool.Typfmt(tind), field.Name, field) + dbglog.Log(" typ: %v, name: %v | %v", ref.Typfmt(tind), field.Name, field) if s.autoNew { var did = lastone.ensurePtrField() if did { @@ -872,7 +871,7 @@ retryExpand: !s.typShouldBeIgnored(tind) { fvp := lastone.FieldValue() lastone = s.iipush(fvp, tind, 0) - dbglog.Log(" -- (retry) -> filed is struct, typ: %v", tool.Typfmt(tind)) + dbglog.Log(" -- (retry) -> filed is struct, typ: %v", ref.Typfmt(tind)) inretry = true goto retryExpand } @@ -890,7 +889,7 @@ retryExpand: s.iipop() lastone = s.iitop() } else { - log.Warnf("cannot fetching field, empty struct ? ") + logz.Warn("cannot fetching field, empty struct ? ") } } @@ -935,7 +934,7 @@ func (s *structIteratorT) getTargetFieldNameBySourceField(knownSrcField *reflect ctx := &NameConverterContext{Params: nil} dstFieldName, ok = flagsInTag.CalcTargetName(knownSrcField.Name, ctx) if !ok { - if tr := s.dstStruct.FieldByName(knownSrcField.Name); !tool.IsNil(tr) { + if tr := s.dstStruct.FieldByName(knownSrcField.Name); !ref.IsNil(tr) { dstFieldName = knownSrcField.Name dbglog.Log(" dstName: %v, ok: %v [pre 2, fld: %v, tag: %v]", dstFieldName, ok, knownSrcField.Name, knownSrcField.Tag) } diff --git a/structiterator_test.go b/structiterator_test.go index 2592ee5..1dbb6a3 100644 --- a/structiterator_test.go +++ b/structiterator_test.go @@ -8,13 +8,13 @@ import ( "time" "unsafe" - "github.com/hedzr/evendeep/diff" - "github.com/hedzr/evendeep/internal/cl" - "github.com/hedzr/evendeep/typ" - "github.com/hedzr/evendeep/dbglog" + "github.com/hedzr/evendeep/diff" "github.com/hedzr/evendeep/flags/cms" + "github.com/hedzr/evendeep/internal/cl" "github.com/hedzr/evendeep/internal/tool" + "github.com/hedzr/evendeep/ref" + "github.com/hedzr/evendeep/typ" ) func TestFieldsTableT_getFields_special(t *testing.T) { @@ -62,10 +62,10 @@ func TestSetToZero(t *testing.T) { run := func(v reflect.Value) { // v := reflect.ValueOf(c) - vind := tool.Rdecodesimple(v) + vind := ref.Rdecodesimple(v) vf := vind.Field(0) // vf = vf.Elem() - t.Logf("src: %v", tool.Valfmt(&vf)) + t.Logf("src: %v", ref.Valfmt(&vf)) setToZero(&vf) } @@ -234,10 +234,10 @@ func TestSetToZero(t *testing.T) { {fn, Func(nil)}, } { v := reflect.ValueOf(case_) - vind := tool.Rdecodesimple(v) + vind := ref.Rdecodesimple(v) vf := vind.Field(0) // vf = vf.Elem() - t.Logf("%d. src: %+v", i, tool.Valfmt(&vf)) + t.Logf("%d. src: %+v", i, ref.Valfmt(&vf)) setToZero(&vf) if why, equal := diff.New(case_.Src, case_.Zero, diff.WithTreatEmptyStructPtrAsNilPtr(true)); !equal { @@ -265,7 +265,7 @@ func TestFieldAccessorT_mapkey_special(t *testing.T) { const byName = false x2 := x2data() v1 := reflect.ValueOf(&x2) - t1, _ := tool.Rdecode(v1) + t1, _ := ref.Rdecode(v1) it := newStructIterator(t1) t.Logf("%v", it) } @@ -274,7 +274,7 @@ func TestFieldAccessorT_IsAnyFlagsOK(t *testing.T) { const byName = false x2 := x2data() v1 := reflect.ValueOf(&x2) - t1, _ := tool.Rdecode(v1) + t1, _ := ref.Rdecode(v1) it := newStructIterator(t1) loopIt(t, it, byName, nil) } @@ -301,7 +301,7 @@ func TestFieldAccessorT_forMap(t *testing.T) { {"x"}: true, //nolint:gofmt } v1 := reflect.ValueOf(&x2) - t1, _ := tool.Rdecode(v1) + t1, _ := ref.Rdecode(v1) it := newStructIterator(t1) loopIt(t, it, byName, nil) } @@ -309,7 +309,7 @@ func TestFieldAccessorT_forMap(t *testing.T) { func TestFieldAccessorT_Operations(t *testing.T) { x1 := x1data() v1 := reflect.ValueOf(&x1) - t1, _ := tool.Rdecode(v1) + t1, _ := ref.Rdecode(v1) // x2 := new(X1) // t2 := rdecodesimple(reflect.ValueOf(&x2)) @@ -347,10 +347,10 @@ func TestFieldAccessorT_Operations(t *testing.T) { func TestStructIteratorT_Next_X1(t *testing.T) { x1 := x1data() v1 := reflect.ValueOf(&x1) - t1, _ := tool.Rdecode(v1) + t1, _ := ref.Rdecode(v1) x2 := new(X1) - t2 := tool.Rdecodesimple(reflect.ValueOf(&x2)) + t2 := ref.Rdecodesimple(reflect.ValueOf(&x2)) const byName = false @@ -375,7 +375,7 @@ func TestStructIteratorT_Next_X1(t *testing.T) { t.Logf("%d. field info missed", i) continue } - t.Logf("%d. %s (%v) -> %s (%v) | %v", i, strings.Join(tool.ReverseStringSlice(sourcefield.names), "."), tool.Valfmt(srcval), accessor.StructFieldName(), tool.Valfmt(dstval), tool.Typfmt(accessor.StructField().Type)) + t.Logf("%d. %s (%v) -> %s (%v) | %v", i, strings.Join(tool.ReverseStringSlice(sourcefield.names), "."), ref.Valfmt(srcval), accessor.StructFieldName(), ref.Valfmt(dstval), ref.Typfmt(accessor.StructField().Type)) // ec.Attach(invokeStructFieldTransformer(c, params, srcval, dstval, padding)) } }) @@ -398,7 +398,7 @@ func TestStructIteratorT_Next_X1(t *testing.T) { t.Logf("%d. field info missed", i) continue } - t.Logf("%d. %s (%v) -> %s (%v) | %v", i, strings.Join(tool.ReverseStringSlice(sourcefield.names), "."), tool.Valfmt(srcval), accessor.StructFieldName(), tool.Valfmt(dstval), tool.Typfmt(accessor.StructField().Type)) + t.Logf("%d. %s (%v) -> %s (%v) | %v", i, strings.Join(tool.ReverseStringSlice(sourcefield.names), "."), ref.Valfmt(srcval), accessor.StructFieldName(), ref.Valfmt(dstval), ref.Typfmt(accessor.StructField().Type)) // ec.Attach(invokeStructFieldTransformer(c, params, srcval, dstval, padding)) } }) @@ -448,14 +448,14 @@ func loopIt(t *testing.T, it structIterable, byName bool, checkName func(accesso } var val reflect.Value - if accessor.IsStruct() && !tool.IsExported(field) { + if accessor.IsStruct() && !ref.IsExported(field) { val = *accessor.FieldValue() val = cl.GetUnexportedField(val) // cl.SetUnexportedField(target, newval) } else { val = *accessor.FieldValue() } - t.Logf("%d. %q (%v) | %v", i, name, tool.Typfmt(*fieldType), tool.Valfmt(&val)) + t.Logf("%d. %q (%v) | %v", i, name, ref.Typfmt(*fieldType), ref.Valfmt(&val)) } } @@ -491,15 +491,15 @@ func testGetAllFieldsX1(t *testing.T) { x1 := x1data() v1 := reflect.ValueOf(&x1) - t1, _ := tool.Rdecode(v1) + t1, _ := ref.Rdecode(v1) var sourcefields fieldsTableT sourcefields = sourcefields.getAllFields(t1, false) for i, amount := 0, len(sourcefields.tableRecordsT); i < amount; i++ { sourcefield := sourcefields.tableRecordsT[i] srcval := sourcefield.FieldValue() - srctypstr := tool.Typfmtv(srcval) - dbglog.Log("%d. %s (%v) %v -> %s (%v)", i, strings.Join(tool.ReverseStringSlice(sourcefield.names), "."), tool.Valfmt(srcval), srctypstr, "", "") + srctypstr := ref.Typfmtv(srcval) + dbglog.Log("%d. %s (%v) %v -> %s (%v)", i, strings.Join(tool.ReverseStringSlice(sourcefield.names), "."), ref.Valfmt(srcval), srctypstr, "", "") } } @@ -507,7 +507,7 @@ func testStructIteratorNextT1(t *testing.T) { x1 := x1data() v1 := reflect.ValueOf(&x1) - t1, _ := tool.Rdecode(v1) + t1, _ := ref.Rdecode(v1) const byName = false @@ -522,7 +522,7 @@ func testStructIteratorNextT1(t *testing.T) { t.Logf("%d. field info missed", i) continue } - dbglog.Log("%d. %q (%v) %v %q", i, field.Name, tool.Typfmt(field.Type), field.Index, field.PkgPath) + dbglog.Log("%d. %q (%v) %v %q", i, field.Name, ref.Typfmt(field.Type), field.Index, field.PkgPath) } } @@ -553,7 +553,7 @@ func testStructIteratorNextEmployee2(t *testing.T) { defer func() { t.Log(sb.String()) }() v1 := reflect.ValueOf(&src) - t1, _ := tool.Rdecode(v1) + t1, _ := ref.Rdecode(v1) it := newStructIterator(t1) const byName = false for i := 0; ; i++ { @@ -566,8 +566,8 @@ func testStructIteratorNextEmployee2(t *testing.T) { t.Logf("%d. field info missed", i) continue } - t.Logf("%d. %q (%v) %v %q", i, field.Name, tool.Typfmt(field.Type), field.Index, field.PkgPath) - sb.WriteString(fmt.Sprintf("%d. %q (%v) %v %q\n", i, field.Name, tool.Typfmt(field.Type), field.Index, field.PkgPath)) + t.Logf("%d. %q (%v) %v %q", i, field.Name, ref.Typfmt(field.Type), field.Index, field.PkgPath) + sb.WriteString(fmt.Sprintf("%d. %q (%v) %v %q\n", i, field.Name, ref.Typfmt(field.Type), field.Index, field.PkgPath)) } if sb.String() != `0. "Base" (evendeep.Base (struct)) [0] "" @@ -605,7 +605,7 @@ func testStructIteratorNextEmployee2Exp(t *testing.T) { defer func() { t.Log(sb.String()) }() v1 := reflect.ValueOf(&src) - t1, _ := tool.Rdecode(v1) + t1, _ := ref.Rdecode(v1) it := newStructIterator(t1, withStructPtrAutoExpand(true)) const byName = false for i := 0; ; i++ { @@ -618,8 +618,8 @@ func testStructIteratorNextEmployee2Exp(t *testing.T) { t.Logf("%d. field info missed", i) continue } - t.Logf("%d. %q (%v) %v %q", i, field.Name, tool.Typfmt(field.Type), field.Index, field.PkgPath) - sb.WriteString(fmt.Sprintf("%d. %q (%v) %v %q\n", i, field.Name, tool.Typfmt(field.Type), field.Index, field.PkgPath)) + t.Logf("%d. %q (%v) %v %q", i, field.Name, ref.Typfmt(field.Type), field.Index, field.PkgPath) + sb.WriteString(fmt.Sprintf("%d. %q (%v) %v %q\n", i, field.Name, ref.Typfmt(field.Type), field.Index, field.PkgPath)) } if sb.String() != `0. "Name" (string (string)) [0] "" @@ -666,7 +666,7 @@ func testStructIteratorNextUser(t *testing.T) { }() v1 := reflect.ValueOf(&tgt) - t1, _ := tool.Rdecode(v1) + t1, _ := ref.Rdecode(v1) it := newStructIterator(t1) const byName = false for i := 0; ; i++ { @@ -675,7 +675,7 @@ func testStructIteratorNextUser(t *testing.T) { break } field := accessor.StructField() - _, _ = fmt.Fprintf(&sb, "%d. %q (%v) | %v(%v) | fld: %+v\n", i, field.Name, tool.Typfmt(field.Type), tool.Typfmt(accessor.Type()), field.Index, field) + _, _ = fmt.Fprintf(&sb, "%d. %q (%v) | %v(%v) | fld: %+v\n", i, field.Name, ref.Typfmt(field.Type), ref.Typfmt(accessor.Type()), field.Index, field) } } @@ -700,7 +700,7 @@ func testStructIteratorNextUserNew(t *testing.T) { } { sb.WriteString("\n") v1 := reflect.ValueOf(&tgt) // nolint:gosec // G601: Implicit memory aliasing in for loop - t1, _ := tool.Rdecode(v1) + t1, _ := ref.Rdecode(v1) it := newStructIterator(t1, withStructPtrAutoExpand(true), withStructFieldPtrAutoNew(true)) for i := 0; ; i++ { accessor, ok := it.Next(nil, false) @@ -708,7 +708,7 @@ func testStructIteratorNextUserNew(t *testing.T) { break } field := accessor.StructField() - _, _ = fmt.Fprintf(&sb, "%d. %q (%v) | %v(%v) | fld: %+v\n", i, field.Name, tool.Typfmt(field.Type), tool.Typfmt(accessor.Type()), field.Index, field) + _, _ = fmt.Fprintf(&sb, "%d. %q (%v) | %v(%v) | fld: %+v\n", i, field.Name, ref.Typfmt(field.Type), ref.Typfmt(accessor.Type()), field.Index, field) } } @@ -734,7 +734,7 @@ func testStructIteratorNextUserZero(t *testing.T) { } { sb.WriteString("\n\n\n") v1 := reflect.ValueOf(&tgt) // nolint:gosec // G601: Implicit memory aliasing in for loop - t1, _ := tool.Rdecode(v1) + t1, _ := ref.Rdecode(v1) it := newStructIterator(t1) for i := 0; ; i++ { accessor, ok := it.Next(nil, byName) @@ -742,7 +742,7 @@ func testStructIteratorNextUserZero(t *testing.T) { break } field := accessor.StructField() - _, _ = fmt.Fprintf(&sb, "%d. %q (%v) | %v(%v) | fld: %+v\n", i, field.Name, tool.Typfmt(field.Type), tool.Typfmt(accessor.Type()), field.Index, field) + _, _ = fmt.Fprintf(&sb, "%d. %q (%v) | %v(%v) | fld: %+v\n", i, field.Name, ref.Typfmt(field.Type), ref.Typfmt(accessor.Type()), field.Index, field) } } @@ -782,7 +782,7 @@ func testStructIteratorNextUserMore(t *testing.T) { } { sb.WriteString("\n\n\n") v1 := reflect.ValueOf(&tgt) // nolint:gosec // G601: Implicit memory aliasing in for loop - t1, _ := tool.Rdecode(v1) + t1, _ := ref.Rdecode(v1) it := newStructIterator(t1) for i := 0; ; i++ { accessor, ok := it.Next(nil, byName) @@ -790,7 +790,7 @@ func testStructIteratorNextUserMore(t *testing.T) { break } field := accessor.StructField() - _, _ = fmt.Fprintf(&sb, "%d. %q (%v) | %v(%v) | fld: %+v\n", i, field.Name, tool.Typfmt(field.Type), tool.Typfmt(accessor.Type()), field.Index, field) + _, _ = fmt.Fprintf(&sb, "%d. %q (%v) | %v(%v) | fld: %+v\n", i, field.Name, ref.Typfmt(field.Type), ref.Typfmt(accessor.Type()), field.Index, field) } } @@ -808,7 +808,7 @@ func teststructiteratorNextA4New(t *testing.T) { const byName = false a4 := new(A4) v1 := reflect.ValueOf(&a4) - t1, _ := tool.Rdecode(v1) + t1, _ := ref.Rdecode(v1) it := newStructIterator(t1, withStructPtrAutoExpand(true), withStructFieldPtrAutoNew(true)) for i := 0; ; i++ { accessor, ok := it.Next(nil, byName) @@ -816,7 +816,7 @@ func teststructiteratorNextA4New(t *testing.T) { break } field := accessor.StructField() - _, _ = fmt.Fprintf(&sb, "%d. %q (%v) | %v %v\n", i, field.Name, tool.Typfmt(field.Type), tool.Typfmt(accessor.Type()), field.Index) + _, _ = fmt.Fprintf(&sb, "%d. %q (%v) | %v %v\n", i, field.Name, ref.Typfmt(field.Type), ref.Typfmt(accessor.Type()), field.Index) } t.Logf(sb.String()) @@ -867,7 +867,7 @@ func teststructiteratorNextA4Zero(t *testing.T) { const byName = false a4 := new(A4) v1 := reflect.ValueOf(&a4) - t1, _ := tool.Rdecode(v1) + t1, _ := ref.Rdecode(v1) it := newStructIterator(t1, withStructPtrAutoExpand(true)) for i := 0; ; i++ { accessor, ok := it.Next(nil, byName) @@ -875,7 +875,7 @@ func teststructiteratorNextA4Zero(t *testing.T) { break } field := accessor.StructField() - _, _ = fmt.Fprintf(&sb, "%d. %q (%v) | %v %v\n", i, field.Name, tool.Typfmt(field.Type), tool.Typfmt(accessor.Type()), field.Index) + _, _ = fmt.Fprintf(&sb, "%d. %q (%v) | %v %v\n", i, field.Name, ref.Typfmt(field.Type), ref.Typfmt(accessor.Type()), field.Index) } t.Logf(sb.String()) @@ -925,7 +925,7 @@ func teststructiteratorNextA4(t *testing.T) { const byName = false a4 := prepareDataA4() v1 := reflect.ValueOf(&a4) - t1, _ := tool.Rdecode(v1) + t1, _ := ref.Rdecode(v1) it := newStructIterator(t1, withStructPtrAutoExpand(true)) for i := 0; ; i++ { accessor, ok := it.Next(nil, byName) @@ -933,7 +933,7 @@ func teststructiteratorNextA4(t *testing.T) { break } field := accessor.StructField() - _, _ = fmt.Fprintf(&sb, "%d. %q (%v) | %v %v\n", i, field.Name, tool.Typfmt(field.Type), tool.Typfmt(accessor.Type()), field.Index) + _, _ = fmt.Fprintf(&sb, "%d. %q (%v) | %v %v\n", i, field.Name, ref.Typfmt(field.Type), ref.Typfmt(accessor.Type()), field.Index) } t.Logf(sb.String()) @@ -989,7 +989,7 @@ func TestFieldsTable_getallfields(t *testing.T) { func testFieldsTableGetFieldsDeeply(t *testing.T) { x2 := new(X1) - t2 := tool.Rdecodesimple(reflect.ValueOf(&x2)) + t2 := ref.Rdecodesimple(reflect.ValueOf(&x2)) var sourcefields fieldsTableT sourcefields.getAllFields(t2, true) @@ -1000,7 +1000,7 @@ func testFieldsTableGetFieldsDeeply(t *testing.T) { for i, f := range sourcefields.tableRecordsT { _, _ = fmt.Fprintf(&sb, "%v. %v, %v | %v, %q, %q\n", i, f.FieldName(), f.indexes, - tool.Typfmt(f.structField.Type), f.structField.Tag, f.structField.PkgPath, + ref.Typfmt(f.structField.Type), f.structField.Tag, f.structField.PkgPath, ) } @@ -1019,7 +1019,7 @@ func testFieldsTableGetAllFields(t *testing.T) { for i, f := range sourcefields.tableRecordsT { _, _ = fmt.Fprintf(&sb, "%v. %v, %v | %v, %q, %q\n", i, f.FieldName(), f.indexes, - tool.Typfmt(f.structField.Type), f.structField.Tag, f.structField.PkgPath, + ref.Typfmt(f.structField.Type), f.structField.Tag, f.structField.PkgPath, ) } @@ -1106,7 +1106,7 @@ func testFieldsTableGetAllFieldsEmployee2(t *testing.T) { for i, f := range sourcefields.tableRecordsT { _, _ = fmt.Fprintf(&sb1, "%v. %v, %v | %v, %q, %q\n", i, f.FieldName(), f.indexes, - tool.Typfmt(f.structField.Type), f.structField.Tag, f.structField.PkgPath, + ref.Typfmt(f.structField.Type), f.structField.Tag, f.structField.PkgPath, ) } @@ -1165,7 +1165,7 @@ func testFieldsTableGetAllFieldsEmployee22(t *testing.T) { for i, f := range sourcefields.tableRecordsT { _, _ = fmt.Fprintf(&sb, "%v. %v, %v | %v, %q, %q\n", i, f.FieldName(), f.indexes, - tool.Typfmt(f.structField.Type), f.structField.Tag, f.structField.PkgPath, + ref.Typfmt(f.structField.Type), f.structField.Tag, f.structField.PkgPath, ) } @@ -1229,7 +1229,7 @@ func testFieldsTableGetAllFieldsUser(t *testing.T) { for i, f := range sourcefields.tableRecordsT { _, _ = fmt.Fprintf(&sb, "%v. %v, %v | %v, %q, %q\n", i, f.FieldName(), f.indexes, - tool.Typfmt(f.structField.Type), f.structField.Tag, f.structField.PkgPath, + ref.Typfmt(f.structField.Type), f.structField.Tag, f.structField.PkgPath, ) } diff --git a/tag_test.go b/tag_test.go index aca39bf..9f45694 100644 --- a/tag_test.go +++ b/tag_test.go @@ -3,7 +3,7 @@ package evendeep import ( "github.com/hedzr/evendeep/flags" "github.com/hedzr/evendeep/flags/cms" - "github.com/hedzr/evendeep/internal/tool" + "github.com/hedzr/evendeep/ref" "reflect" "testing" @@ -49,7 +49,7 @@ func subtestParse(t *testing.T) { // c := newCopier() v := reflect.ValueOf(&a) - v = tool.Rindirect(v) + v = ref.Rindirect(v) for i := 0; i < v.NumField(); i++ { fld := v.Type().Field(i) @@ -71,7 +71,7 @@ func subtestFlagTests(t *testing.T) { } var a AFS1 v := reflect.ValueOf(&a) - v = tool.Rindirect(v) + v = ref.Rindirect(v) sf, _ := v.Type().FieldByName("wouldbe") sf0, _ := v.Type().FieldByName("flags") sf1, _ := v.Type().FieldByName("converter") @@ -85,13 +85,13 @@ func subtestFlagTests(t *testing.T) { z.isFlagExists(cms.SliceCopy) v = reflect.ValueOf(&z) - tool.Rwant(v, reflect.Struct) + ref.Rwant(v, reflect.Struct) ve := v.Elem() - t.Logf("z: %v, nil: %v", tool.Valfmt(&ve), tool.Valfmt(nil)) + t.Logf("z: %v, nil: %v", ref.Valfmt(&ve), ref.Valfmt(nil)) var nilArray = [1]*int{(*int)(nil)} v = reflect.ValueOf(nilArray) - t.Logf("nilArray: %v, nil: %v", tool.Valfmt(&v), tool.Valfmt(nil)) + t.Logf("nilArray: %v, nil: %v", ref.Valfmt(&v), ref.Valfmt(nil)) v = reflect.ValueOf(&fieldTags{ flags: nil, @@ -100,7 +100,7 @@ func subtestFlagTests(t *testing.T) { nameConverter: nil, nameConvertRule: "", }) - tool.Rwant(v, reflect.Struct) + ref.Rwant(v, reflect.Struct) var ss1 = []int{8, 9} var ss2 = []int64{} @@ -109,11 +109,11 @@ func subtestFlagTests(t *testing.T) { var vv1 = reflect.ValueOf(ss1) var tt3 = reflect.TypeOf(ss3) var tp4 = reflect.TypeOf(&ss4) - t.Logf("ss1.type: %v", tool.Typfmtv(&vv1)) - t.Log(tool.CanConvertHelper(reflect.ValueOf(&ss1), reflect.TypeOf(&ss2))) - t.Log(tool.CanConvertHelper(vv1, reflect.TypeOf(ss2))) - t.Log(tool.CanConvertHelper(vv1, tt3)) - t.Log(tool.CanConvertHelper(vv1, tp4)) + t.Logf("ss1.type: %v", ref.Typfmtv(&vv1)) + t.Log(ref.CanConvertHelper(reflect.ValueOf(&ss1), reflect.TypeOf(&ss2))) + t.Log(ref.CanConvertHelper(vv1, reflect.TypeOf(ss2))) + t.Log(ref.CanConvertHelper(vv1, tt3)) + t.Log(ref.CanConvertHelper(vv1, tp4)) } func TestFieldTags_CalcTargetName(t *testing.T) { diff --git a/withopts.go b/withopts.go index 576521b..3f504fd 100644 --- a/withopts.go +++ b/withopts.go @@ -3,8 +3,6 @@ package evendeep import ( "encoding/json" - "github.com/hedzr/log/dir" - "github.com/hedzr/evendeep/flags" "github.com/hedzr/evendeep/flags/cms" ) @@ -363,7 +361,58 @@ func WithIgnoreNamesReset() Opt { // isWildMatch provides a filename wildcard matching algorithm // by dir.IsWildMatch. func isWildMatch(s, pattern string) bool { - return dir.IsWildMatch(s, pattern) + runeInputArray := []rune(s) + runePatternArray := []rune(pattern) + if len(runeInputArray) > 0 && len(runePatternArray) > 0 { + if runePatternArray[len(runePatternArray)-1] != '*' && runePatternArray[len(runePatternArray)-1] != '?' && runeInputArray[len(runeInputArray)-1] != runePatternArray[len(runePatternArray)-1] { + return false + } + } + return isMatchUtil([]rune(s), []rune(pattern), 0, 0, len([]rune(s)), len([]rune(pattern))) +} + +func isMatchUtil(input, pattern []rune, inputIndex, patternIndex int, inputLength, patternLength int) bool { + + if inputIndex == inputLength && patternIndex == patternLength { + return true + } else if patternIndex == patternLength { + return false + } else if inputIndex == inputLength { + if pattern[patternIndex] == '*' && restPatternStar(pattern, patternIndex+1, patternLength) { + return true + } else { + return false + } + } + + if pattern[patternIndex] == '*' { + return isMatchUtil(input, pattern, inputIndex, patternIndex+1, inputLength, patternLength) || + isMatchUtil(input, pattern, inputIndex+1, patternIndex, inputLength, patternLength) + } + + if pattern[patternIndex] == '?' { + return isMatchUtil(input, pattern, inputIndex+1, patternIndex+1, inputLength, patternLength) + } + + if inputIndex < inputLength { + if input[inputIndex] == pattern[patternIndex] { + return isMatchUtil(input, pattern, inputIndex+1, patternIndex+1, inputLength, patternLength) + } else { + return false + } + } + + return false +} + +func restPatternStar(pattern []rune, patternIndex int, patternLength int) bool { + for patternIndex < patternLength { + if pattern[patternIndex] != '*' { + return false + } + patternIndex++ + } + return true } // WithStructTagName set the name which is used for retrieve the struct tag pieces.