github.com/hedzr/evendeep@v0.4.8/cvts.go (about)

     1  package evendeep
     2  
     3  import (
     4  	"bytes"
     5  	"encoding"
     6  	"encoding/json"
     7  	"fmt"
     8  	"math"
     9  	"reflect"
    10  	"strconv"
    11  	"strings"
    12  	"time"
    13  
    14  	"github.com/hedzr/log"
    15  
    16  	"github.com/hedzr/evendeep/dbglog"
    17  	"github.com/hedzr/evendeep/flags"
    18  	"github.com/hedzr/evendeep/flags/cms"
    19  	"github.com/hedzr/evendeep/internal/syscalls"
    20  	"github.com/hedzr/evendeep/internal/tool"
    21  	"github.com/hedzr/evendeep/typ"
    22  
    23  	"gopkg.in/hedzr/errors.v3"
    24  )
    25  
    26  const timeConstString = "time"
    27  
    28  // RegisterDefaultConverters registers the ValueConverter list into
    29  // default converters registry.
    30  //
    31  // It takes effects on DefaultCopyController, MakeClone, DeepCopy,
    32  // and New, ....
    33  func RegisterDefaultConverters(ss ...ValueConverter) {
    34  	defValueConverters = append(defValueConverters, ss...)
    35  	initGlobalOperators()
    36  }
    37  
    38  // RegisterDefaultCopiers registers the ValueCopier list into
    39  // default copiers registry.
    40  //
    41  // It takes effects on DefaultCopyController, MakeClone, DeepCopy,
    42  // and New, ....
    43  func RegisterDefaultCopiers(ss ...ValueCopier) {
    44  	defValueCopiers = append(defValueCopiers, ss...)
    45  	initGlobalOperators()
    46  }
    47  
    48  func initConverters() {
    49  	dbglog.Log("initializing default converters and copiers ...")
    50  	defValueConverters = ValueConverters{ // Transform()
    51  		&fromStringConverter{}, // the final choice here
    52  		&toStringConverter{},
    53  
    54  		// &toFuncConverter{},
    55  		&fromFuncConverter{},
    56  
    57  		&toDurationConverter{},
    58  		&fromDurationConverter{},
    59  		&toTimeConverter{},
    60  		&fromTimeConverter{},
    61  
    62  		&fromBytesBufferConverter{},
    63  		&fromSyncPkgConverter{},
    64  		&fromMapConverter{},
    65  	}
    66  	defValueCopiers = ValueCopiers{ // CopyTo()
    67  		&fromStringConverter{}, // the final choice here
    68  		&toStringConverter{},
    69  
    70  		&toFuncConverter{},
    71  		&fromFuncConverter{},
    72  
    73  		&toDurationConverter{},
    74  		&fromDurationConverter{},
    75  		&toTimeConverter{},
    76  		&fromTimeConverter{},
    77  
    78  		&fromBytesBufferConverter{},
    79  		&fromSyncPkgConverter{},
    80  		&fromMapConverter{},
    81  	}
    82  
    83  	lenValueConverters = len(defValueConverters)
    84  	lenValueCopiers = len(defValueCopiers)
    85  }
    86  
    87  var defValueConverters ValueConverters      //nolint:gochecknoglobals //i know that
    88  var defValueCopiers ValueCopiers            //nolint:gochecknoglobals //i know that
    89  var lenValueConverters, lenValueCopiers int //nolint:gochecknoglobals //i know that
    90  
    91  func defaultValueConverters() ValueConverters { return defValueConverters }
    92  func defaultValueCopiers() ValueCopiers       { return defValueCopiers }
    93  
    94  // ValueConverter for internal used.
    95  type ValueConverter interface {
    96  	Transform(ctx *ValueConverterContext, source reflect.Value, targetType reflect.Type) (target reflect.Value, err error)
    97  	Match(params *Params, source, target reflect.Type) (ctx *ValueConverterContext, yes bool)
    98  }
    99  
   100  // ValueCopier  for internal used.
   101  type ValueCopier interface {
   102  	CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error)
   103  	Match(params *Params, source, target reflect.Type) (ctx *ValueConverterContext, yes bool)
   104  }
   105  
   106  // NameConverter for internal used.
   107  type NameConverter interface {
   108  	ToGoName(ctx *NameConverterContext, fieldName string) (goName string)
   109  	ToFieldName(ctx *NameConverterContext, goName string) (fieldName string)
   110  }
   111  
   112  // ValueConverters for internal used.
   113  type ValueConverters []ValueConverter
   114  
   115  // ValueCopiers for internal used.
   116  type ValueCopiers []ValueCopier
   117  
   118  // NameConverters for internal used.
   119  type NameConverters []NameConverter
   120  
   121  // NameConverterContext for internal used.
   122  type NameConverterContext struct {
   123  	*Params
   124  }
   125  
   126  // ValueConverterContext for internal used.
   127  type ValueConverterContext struct {
   128  	*Params
   129  }
   130  
   131  //
   132  
   133  //nolint:lll //no why
   134  func (valueConverters ValueConverters) findConverters(params *Params, from, to reflect.Type, userDefinedOnly bool) (converter ValueConverter, ctx *ValueConverterContext) {
   135  	var yes bool
   136  	var min int
   137  	if userDefinedOnly {
   138  		min = lenValueConverters
   139  	}
   140  	for i := len(valueConverters) - 1; i >= min; i-- {
   141  		// FILO: the last added converter has the first priority
   142  		cvt := valueConverters[i]
   143  		if cvt != nil {
   144  			if ctx, yes = cvt.Match(params, from, to); yes {
   145  				converter = cvt
   146  				break
   147  			}
   148  		}
   149  	}
   150  	return
   151  }
   152  
   153  //nolint:lll //no why
   154  func (valueCopiers ValueCopiers) findCopiers(params *Params, from, to reflect.Type, userDefinedOnly bool) (copier ValueCopier, ctx *ValueConverterContext) {
   155  	var yes bool
   156  	var min int
   157  	if userDefinedOnly {
   158  		min = lenValueCopiers
   159  	}
   160  	for i := len(valueCopiers) - 1; i >= min; i-- {
   161  		// FILO: the last added converter has the first priority
   162  		cpr := valueCopiers[i]
   163  		if cpr != nil {
   164  			if ctx, yes = cpr.Match(params, from, to); yes {
   165  				copier = cpr
   166  				break
   167  			}
   168  		}
   169  	}
   170  	return
   171  }
   172  
   173  //
   174  
   175  // IsCopyFunctionResultToTarget does SAFELY test if copyFunctionResultToTarget is true or not.
   176  func (ctx *ValueConverterContext) IsCopyFunctionResultToTarget() bool {
   177  	if ctx == nil || ctx.Params == nil || ctx.controller == nil {
   178  		return false
   179  	}
   180  	return ctx.controller.copyFunctionResultToTarget
   181  }
   182  
   183  // IsPassSourceToTargetFunction does SAFELY test if passSourceAsFunctionInArgs is true or not.
   184  func (ctx *ValueConverterContext) IsPassSourceToTargetFunction() bool {
   185  	if ctx == nil || ctx.Params == nil || ctx.controller == nil {
   186  		return false
   187  	}
   188  	return ctx.controller.passSourceAsFunctionInArgs
   189  }
   190  
   191  // Preprocess find out a converter to transform source to target.
   192  // If no comfortable converter found, the return processed is false.
   193  //
   194  //nolint:lll //no why
   195  func (ctx *ValueConverterContext) Preprocess(source reflect.Value, targetType reflect.Type, cvtOuter ValueConverter) (processed bool, target reflect.Value, err error) {
   196  	if ctx != nil && ctx.Params != nil && ctx.Params.controller != nil {
   197  		sourceType := source.Type()
   198  		if cvt, ctxCvt := ctx.controller.valueConverters.findConverters(ctx.Params, sourceType, targetType, false); cvt != nil && cvt != cvtOuter {
   199  			target, err = cvt.Transform(ctxCvt, source, targetType)
   200  			processed = true
   201  			return
   202  		}
   203  	}
   204  	return
   205  }
   206  
   207  //nolint:unused //future
   208  func (ctx *ValueConverterContext) isStruct() bool {
   209  	if ctx == nil {
   210  		return false
   211  	}
   212  	return ctx.Params.isStruct()
   213  }
   214  
   215  //nolint:unused //future
   216  func (ctx *ValueConverterContext) isFlagExists(ftf cms.CopyMergeStrategy) (ret bool) {
   217  	if ctx == nil {
   218  		return
   219  	}
   220  	return ctx.Params.isFlagExists(ftf)
   221  }
   222  
   223  // isGroupedFlagOK tests if the given flag is exists or valid.
   224  //
   225  // Different with isGroupedFlagOKDeeply is, isGroupedFlagOK will return
   226  // false simply while Params.fieldTags is empty or unset.
   227  //
   228  // When Params.fieldTags is valid, the actual testing will be forwarded
   229  // to Params.fieldTags.flags.isGroupedFlagOK().
   230  func (ctx *ValueConverterContext) isGroupedFlagOK(ftf ...cms.CopyMergeStrategy) (ret bool) { //nolint:unused //future
   231  	if ctx == nil {
   232  		return flags.New().IsGroupedFlagOK(ftf...)
   233  	}
   234  	return ctx.Params.isGroupedFlagOK(ftf...)
   235  }
   236  
   237  // isGroupedFlagOKDeeply tests if the given flag is exists or valid.
   238  //
   239  // Different with isGroupedFlagOK is, isGroupedFlagOKDeeply will check
   240  // whether the given flag is a leader (i.e. default choice) in a group
   241  // or not, even if Params.fieldTags is empty or unset.
   242  //
   243  // When Params.fieldTags is valid, the actual testing will be forwarded
   244  // to Params.fieldTags.flags.isGroupedFlagOK().
   245  func (ctx *ValueConverterContext) isGroupedFlagOKDeeply(ftf ...cms.CopyMergeStrategy) (ret bool) {
   246  	if ctx == nil {
   247  		return flags.New().IsGroupedFlagOK(ftf...)
   248  	}
   249  	return ctx.Params.isGroupedFlagOKDeeply(ftf...)
   250  }
   251  
   252  //nolint:unused //future
   253  func (ctx *ValueConverterContext) isAnyFlagsOK(ftf ...cms.CopyMergeStrategy) (ret bool) {
   254  	if ctx == nil {
   255  		return flags.New().IsAnyFlagsOK(ftf...)
   256  	}
   257  	return ctx.Params.isAnyFlagsOK(ftf...)
   258  }
   259  
   260  //nolint:unused //future
   261  func (ctx *ValueConverterContext) isAllFlagsOK(ftf ...cms.CopyMergeStrategy) (ret bool) {
   262  	if ctx == nil {
   263  		return flags.New().IsAllFlagsOK(ftf...)
   264  	}
   265  	return ctx.Params.isAllFlagsOK(ftf...)
   266  }
   267  
   268  //
   269  
   270  //
   271  
   272  //
   273  
   274  type cvtbase struct{}
   275  
   276  func (c *cvtbase) safeType(tgt, tgtptr reflect.Value) reflect.Type {
   277  	if tgt.IsValid() {
   278  		return tgt.Type()
   279  	}
   280  	if tgtptr.IsValid() {
   281  		if tgtptr.Kind() == reflect.Interface {
   282  			return tgtptr.Type()
   283  		}
   284  		return tgtptr.Type().Elem()
   285  	}
   286  	log.Panicf("niltyp !! CANNOT fetch type: tgt = %v, tgtptr = %v", tool.Typfmtv(&tgt), tool.Typfmtv(&tgtptr))
   287  	return tool.Niltyp
   288  }
   289  
   290  // processUnexportedField try to set newval into target if it's an unexported field.
   291  func (c *cvtbase) processUnexportedField(ctx *ValueConverterContext, target, newval reflect.Value) (processed bool) {
   292  	if ctx == nil || ctx.Params == nil {
   293  		return
   294  	}
   295  	processed = ctx.Params.processUnexportedField(target, newval)
   296  	return
   297  }
   298  
   299  //nolint:lll //no why
   300  func (c *cvtbase) checkSource(ctx *ValueConverterContext, source reflect.Value, targetType reflect.Type) (target reflect.Value, processed bool) {
   301  	if ctx == nil {
   302  		return
   303  	}
   304  
   305  	if processed = ctx.isGroupedFlagOKDeeply(cms.Ignore); processed {
   306  		return
   307  	}
   308  	if processed = tool.IsNil(source) && ctx.isGroupedFlagOKDeeply(cms.OmitIfNil, cms.OmitIfEmpty); processed {
   309  		target = reflect.Zero(targetType)
   310  		return
   311  	}
   312  	if processed = tool.IsZero(source) && ctx.isGroupedFlagOKDeeply(cms.OmitIfZero, cms.OmitIfEmpty); processed {
   313  		target = reflect.Zero(targetType)
   314  	}
   315  	return
   316  }
   317  
   318  //nolint:lll //no why
   319  func (c *cvtbase) checkTarget(ctx *ValueConverterContext, target reflect.Value, targetType reflect.Type) (processed bool) {
   320  	if processed = !target.IsValid(); processed {
   321  		return
   322  	}
   323  	if processed = tool.IsNil(target) && ctx.isGroupedFlagOKDeeply(cms.OmitIfTargetNil); processed {
   324  		return
   325  	}
   326  	processed = tool.IsZero(target) && ctx.isGroupedFlagOKDeeply(cms.OmitIfTargetZero)
   327  	return
   328  }
   329  
   330  //
   331  
   332  type toConverterBase struct{ cvtbase }
   333  
   334  func (c *toConverterBase) fallback(target reflect.Value) (err error) {
   335  	tgtType := reflect.TypeOf((*time.Duration)(nil)).Elem()
   336  	tool.Rindirect(target).Set(reflect.Zero(tgtType))
   337  	return
   338  }
   339  
   340  //
   341  
   342  type fromConverterBase struct{ cvtbase }
   343  
   344  func (c *fromConverterBase) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) {
   345  	panic("not impl")
   346  }
   347  
   348  func (c *fromConverterBase) Transform(ctx *ValueConverterContext,
   349  	source reflect.Value, targetType reflect.Type) (target reflect.Value, err error) {
   350  	panic("not impl")
   351  }
   352  
   353  func (c *fromConverterBase) Match(params *Params, source, target reflect.Type) (ctx *ValueConverterContext, yes bool) {
   354  	panic("not impl")
   355  }
   356  
   357  //nolint:unused,lll //future
   358  func (c *fromConverterBase) preprocess(ctx *ValueConverterContext, source reflect.Value, targetType reflect.Type) (processed bool, target reflect.Value, err error) {
   359  	if !(ctx != nil && ctx.Params != nil && ctx.Params.controller != nil) {
   360  		return
   361  	}
   362  
   363  	sourceType := source.Type()
   364  	if cvt, ctxCvt := ctx.controller.valueConverters.findConverters(ctx.Params, sourceType, targetType, false); cvt != nil {
   365  		if cvt == c {
   366  			return
   367  		}
   368  		if cc, ok := cvt.(*fromConverterBase); ok && cc == c {
   369  			return
   370  		}
   371  
   372  		target, err = cvt.Transform(ctxCvt, source, targetType)
   373  		processed = true
   374  		return
   375  	}
   376  	return
   377  }
   378  
   379  func (c *fromConverterBase) postCopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) {
   380  	// if source.IsValid() {
   381  	//	if canConvert(&source, target.Type()) {
   382  	//		nv := source.Convert(target.Type())
   383  	//		target.Set(nv)
   384  	//		return
   385  	//		//} else {
   386  	//		//	nv := fmt.Sprintf("%v", source.Interface())
   387  	//		//	target.Set(reflect.ValueOf(nv))
   388  	//	}
   389  	// }
   390  	//
   391  	// target = reflect.Zero(target.Type())
   392  	// return
   393  	var nv reflect.Value
   394  	nv, err = c.convertToOrZeroTarget(ctx, source, target.Type())
   395  	if err == nil {
   396  		if target.CanSet() {
   397  			dbglog.Log("    postCopyTo: set nv(%v) into target (%v)", tool.Valfmt(&nv), tool.Valfmt(&target))
   398  			target.Set(nv)
   399  		} else {
   400  			err = ErrCannotSet.FormatWith(tool.Valfmt(&target), tool.Typfmtv(&target), tool.Valfmt(&nv), tool.Typfmtv(&nv))
   401  		}
   402  	}
   403  	return
   404  }
   405  
   406  func (c *fromConverterBase) convertToOrZeroTarget(ctx *ValueConverterContext,
   407  	source reflect.Value, targetType reflect.Type) (target reflect.Value, err error) {
   408  	if tool.CanConvert(&source, targetType) {
   409  		nv := source.Convert(targetType)
   410  		target = nv
   411  	} else if ctx.isGroupedFlagOKDeeply(cms.ClearIfInvalid) {
   412  		target = reflect.Zero(targetType)
   413  	}
   414  	return
   415  }
   416  
   417  //
   418  
   419  //
   420  
   421  //
   422  
   423  type toStringConverter struct{ toConverterBase }
   424  
   425  func (c *toStringConverter) postCopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) {
   426  	if source.IsValid() {
   427  		if tool.CanConvert(&source, target.Type()) {
   428  			nv := source.Convert(target.Type())
   429  			if c.processUnexportedField(ctx, target, nv) {
   430  				return
   431  			}
   432  			target.Set(nv)
   433  			return
   434  		}
   435  
   436  		newVal := fmt.Sprintf("%v", source.Interface())
   437  		nv := reflect.ValueOf(newVal)
   438  		if c.processUnexportedField(ctx, target, nv) {
   439  			return
   440  		}
   441  		target.Set(nv)
   442  		return
   443  	}
   444  
   445  	// target = reflect.Zero(target.Type())
   446  	return //nolint:nakedret //i do
   447  }
   448  
   449  func (c *toStringConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) {
   450  	tgt, tgtptr := tool.Rdecode(target)
   451  	tgtType := c.safeType(tgt, tgtptr) // because tgt might be invalid, so we fetch tgt type via its pointer
   452  	dbglog.Log("     target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v",
   453  		tool.Typfmtv(&target), tool.Typfmt(target.Type()), tool.Typfmtv(&tgtptr),
   454  		tool.Typfmtv(&tgt), tool.Typfmt(tgtType))
   455  
   456  	if processed := c.checkTarget(ctx, tgt, tgtType); processed {
   457  		return
   458  	}
   459  
   460  	if ret, e := c.Transform(ctx, source, tgtType); e == nil {
   461  		if c.processUnexportedField(ctx, target, ret) {
   462  			return
   463  		}
   464  		dbglog.Log("     set: %v (%v) <- %v", tool.Valfmt(&target), tool.Typfmtv(&target), tool.Valfmt(&ret))
   465  		tgtptr.Set(ret)
   466  	} else {
   467  		err = c.postCopyTo(ctx, source, target)
   468  	}
   469  	return
   470  }
   471  
   472  // Transform will transform source type (bool, int, ...) to target string.
   473  func (c *toStringConverter) Transform(ctx *ValueConverterContext, source reflect.Value,
   474  	targetType reflect.Type) (target reflect.Value, err error) {
   475  	if source.IsValid() {
   476  		// var processed bool
   477  		// if processed, target, err = ctx.Preprocess(source, targetType, c); processed {
   478  		//	return
   479  		// }
   480  
   481  		var processed bool
   482  		if target, processed = c.checkSource(ctx, source, targetType); processed {
   483  			return
   484  		}
   485  
   486  		var str string
   487  		if str, processed, err = tryMarshalling(source); processed {
   488  			if err == nil {
   489  				target = reflect.ValueOf(str)
   490  			}
   491  			return
   492  		}
   493  
   494  		target, err = rToString(source, targetType)
   495  		return
   496  	}
   497  
   498  	if ctx == nil || ctx.isGroupedFlagOKDeeply(cms.ClearIfInvalid) {
   499  		target = reflect.Zero(reflect.TypeOf((*string)(nil)).Elem())
   500  	}
   501  	return
   502  }
   503  
   504  func (c *toStringConverter) Match(params *Params, source, target reflect.Type) (ctx *ValueConverterContext, yes bool) {
   505  	if yes = target.Kind() == reflect.String; yes {
   506  		ctx = &ValueConverterContext{params}
   507  	}
   508  	return
   509  }
   510  
   511  //
   512  
   513  var marshallableTypes = map[string]reflect.Type{ //nolint:gochecknoglobals //no
   514  	// "MarshalBinary": reflect.TypeOf((*encoding.BinaryMarshaler)(nil)).Elem(),
   515  	"MarshalText": reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem(),
   516  	"MarshalJSON": reflect.TypeOf((*json.Marshaler)(nil)).Elem(),
   517  }
   518  
   519  var textMarshaller = TextMarshaller(func(v interface{}) ([]byte, error) { //nolint:gochecknoglobals //no
   520  	return json.MarshalIndent(v, "", "  ")
   521  })
   522  
   523  func canMarshalling(source reflect.Value) (mtd reflect.Value, yes bool) {
   524  	st := source.Type()
   525  	for fnn, t := range marshallableTypes {
   526  		if st.Implements(t) {
   527  			yes, mtd = true, source.MethodByName(fnn)
   528  			break
   529  		}
   530  	}
   531  	return
   532  }
   533  
   534  // FallbackToBuiltinStringMarshalling exposes the builtin string
   535  // marshalling mechanism for your customized ValueConverter or
   536  // ValueCopier.
   537  func FallbackToBuiltinStringMarshalling(source reflect.Value) (str string, err error) {
   538  	return doMarshalling(source)
   539  }
   540  
   541  func doMarshalling(source reflect.Value) (str string, err error) {
   542  	var data []byte
   543  	if mtd, yes := canMarshalling(source); yes {
   544  		ret := mtd.Call(nil)
   545  		if err, yes = (ret[1].Interface()).(error); err == nil && yes {
   546  			data = ret[0].Interface().([]byte) //nolint:errcheck //no need
   547  		}
   548  	} else {
   549  		data, err = textMarshaller(source.Interface())
   550  	}
   551  	if err == nil {
   552  		str = string(data)
   553  	}
   554  	return
   555  }
   556  
   557  func tryMarshalling(source reflect.Value) (str string, processed bool, err error) {
   558  	var data []byte
   559  	var mtd reflect.Value
   560  	if mtd, processed = canMarshalling(source); processed {
   561  		ret := mtd.Call(nil)
   562  		if err, _ = (ret[1].Interface()).(error); err == nil {
   563  			data = ret[0].Interface().([]byte) //nolint:errcheck //no need
   564  		}
   565  	}
   566  	if err == nil {
   567  		str = string(data)
   568  	}
   569  	return
   570  }
   571  
   572  //
   573  
   574  type fromStringConverter struct{ fromConverterBase }
   575  
   576  func (c *fromStringConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) {
   577  	tgt, tgtptr := tool.Rdecode(target)
   578  	tgttyp := c.safeType(tgt, tgtptr) // because tgt might be invalid, so we fetch tgt type via its pointer
   579  	dbglog.Log("  target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v",
   580  		tool.Typfmtv(&target), tool.Typfmt(target.Type()), tool.Typfmtv(&tgtptr),
   581  		tool.Typfmtv(&tgt), tool.Typfmt(tgttyp))
   582  
   583  	if processed := c.checkTarget(ctx, tgt, tgttyp); processed {
   584  		// target.Set(ret)
   585  		return
   586  	}
   587  
   588  	var ret reflect.Value
   589  	var e error
   590  	if ret, e = c.Transform(ctx, source, tgttyp); e == nil {
   591  		if tgtptr.Kind() == reflect.Interface { //nolint:gocritic // no need to switch to 'switch' clause
   592  			tgtptr.Set(ret)
   593  		} else if tgtptr.Kind() == reflect.Ptr {
   594  			tgtptr.Elem().Set(ret)
   595  		} else if tgt.CanSet() {
   596  			tgt.Set(ret)
   597  		} else {
   598  			err = ErrCannotSet.FormatWith(tool.Valfmt(&tgt), tool.Typfmtv(&tgt), tool.Valfmt(&ret), tool.Typfmtv(&ret))
   599  		}
   600  		dbglog.Log("  tgt / ret transformed: %v / %v", tool.Valfmt(&tgt), tool.Valfmt(&ret))
   601  		return
   602  	}
   603  
   604  	if !errors.IsAnyOf(e, strconv.ErrSyntax, strconv.ErrRange) {
   605  		dbglog.Log("  Transform() failed: %v", e)
   606  		dbglog.Log("  try running postCopyTo()")
   607  		err = c.postCopyTo(ctx, source, target)
   608  	}
   609  	return
   610  }
   611  
   612  // Transform will transform source string to target type (bool, int, ...)
   613  func (c *fromStringConverter) Transform(ctx *ValueConverterContext, source reflect.Value, targetType reflect.Type) (target reflect.Value, err error) {
   614  	if !source.IsValid() {
   615  		target, err = c.convertToOrZeroTarget(ctx, source, targetType)
   616  		return
   617  	}
   618  
   619  	// var processed bool
   620  	// if processed, target, err = c.preprocess(ctx, source, targetType); processed {
   621  	//	return
   622  	// }
   623  
   624  	var processed bool
   625  	if target, processed = c.checkSource(ctx, source, targetType); processed {
   626  		return
   627  	}
   628  
   629  	switch k := targetType.Kind(); k { //nolint:exhaustive //no need
   630  	case reflect.Bool:
   631  		target = rToBool(source)
   632  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   633  		target, err = rToInteger(source, targetType)
   634  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   635  		target, err = rToUInteger(source, targetType)
   636  
   637  	case reflect.Uintptr:
   638  		target = rToUIntegerHex(source, targetType)
   639  	// case reflect.UnsafePointer:
   640  	//	// target = rToUIntegerHex(source, targetType)
   641  	//	err = errors.InvalidArgument
   642  	// case reflect.Ptr:
   643  	//	//target = rToUIntegerHex(source, targetType)
   644  	//	err = errors.InvalidArgument
   645  
   646  	case reflect.Float32, reflect.Float64:
   647  		target, err = rToFloat(source, targetType)
   648  	case reflect.Complex64, reflect.Complex128:
   649  		target, err = rToComplex(source, targetType)
   650  
   651  	case reflect.String:
   652  		target = source
   653  
   654  	// reflect.Array
   655  	// reflect.Chan
   656  	// reflect.Func
   657  	// reflect.Interface
   658  	// reflect.Map
   659  	// reflect.Slice
   660  	// reflect.Struct
   661  
   662  	default:
   663  		target, err = c.convertToOrZeroTarget(ctx, source, targetType)
   664  	}
   665  	return
   666  }
   667  
   668  //nolint:lll //keep it
   669  func (c *fromStringConverter) Match(params *Params, source, target reflect.Type) (ctx *ValueConverterContext, yes bool) {
   670  	if yes = source.Kind() == reflect.String; yes {
   671  		ctx = &ValueConverterContext{params}
   672  	}
   673  	return
   674  }
   675  
   676  //
   677  
   678  //
   679  
   680  //
   681  
   682  // fromMapConverter transforms a map to other types (esp string, slice, struct).
   683  type fromMapConverter struct{ fromConverterBase }
   684  
   685  func (c *fromMapConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) {
   686  	tgt, tgtptr := tool.Rdecode(target)
   687  	tgttyp := c.safeType(tgt, tgtptr) // because tgt might be invalid, so we fetch tgt type via its pointer
   688  	dbglog.Log("  target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v",
   689  		tool.Typfmtv(&target), tool.Typfmt(target.Type()), tool.Typfmtv(&tgtptr),
   690  		tool.Typfmtv(&tgt), tool.Typfmt(tgttyp))
   691  
   692  	if processed := c.checkTarget(ctx, tgt, tgttyp); processed {
   693  		// target.Set(ret)
   694  		return
   695  	}
   696  
   697  	if ctx.controller.targetSetter != nil {
   698  		if tgttyp.Kind() == reflect.Struct {
   699  			// DON'T get into c.Transform(), because Transform will modify
   700  			// a temporary new instance and return it to caller, and
   701  			// the new instance will be set to 'target'.
   702  			// When target setter is valid, we assume the setter will
   703  			// modify the real target directly rather than on a temporary
   704  			// object.
   705  			err = c.toStructDirectly(ctx, source, target, tgttyp)
   706  			return
   707  		}
   708  	}
   709  
   710  	if ret, e := c.Transform(ctx, source, tgttyp); e == nil { //nolint:nestif //keep it
   711  		if k := tgtptr.Kind(); k == reflect.Interface { //nolint:gocritic // no need to switch to 'switch' clause
   712  			tgtptr.Set(ret)
   713  		} else if k == reflect.Ptr {
   714  			tgtptr.Elem().Set(ret)
   715  			// } else if tool.IsZero(tgt) {
   716  		} else if tgt.CanSet() {
   717  			tgt.Set(ret)
   718  		} else {
   719  			err = ErrCannotSet.FormatWith(tool.Valfmt(&tgt), tool.Typfmtv(&tgt), tool.Valfmt(&ret), tool.Typfmtv(&ret))
   720  		}
   721  		dbglog.Log("  tgt: %v (ret = %v)", tool.Valfmt(&tgt), tool.Valfmt(&ret))
   722  	} else if !errors.Is(e, strconv.ErrSyntax) && !errors.Is(e, strconv.ErrRange) {
   723  		dbglog.Log("  Transform() failed: %v", e)
   724  		dbglog.Log("  try running postCopyTo()")
   725  		err = c.postCopyTo(ctx, source, target)
   726  	}
   727  	return
   728  }
   729  
   730  // Transform will transform source string to target type (bool, int, ...)
   731  //
   732  //nolint:lll //keep it
   733  func (c *fromMapConverter) Transform(ctx *ValueConverterContext, source reflect.Value, targetType reflect.Type) (target reflect.Value, err error) {
   734  	if source.IsValid() {
   735  		var processed bool
   736  		if target, processed = c.checkSource(ctx, source, targetType); processed {
   737  			return
   738  		}
   739  
   740  		switch k := targetType.Kind(); k { //nolint:exhaustive //no need
   741  		case reflect.String:
   742  			var str string
   743  			if str, err = doMarshalling(source); err == nil {
   744  				target = reflect.ValueOf(str)
   745  			}
   746  
   747  		case reflect.Struct:
   748  			target, err = c.toStruct(ctx, source, targetType)
   749  
   750  		// case reflect.Slice:
   751  		// case reflect.Array:
   752  
   753  		default:
   754  			target, err = c.convertToOrZeroTarget(ctx, source, targetType)
   755  		}
   756  	} else {
   757  		target, err = c.convertToOrZeroTarget(ctx, source, targetType)
   758  	}
   759  	return
   760  }
   761  
   762  //nolint:lll,gocognit //keep it
   763  func (c *fromMapConverter) toStructDirectly(ctx *ValueConverterContext, source, target reflect.Value, targetType reflect.Type) (err error) {
   764  	cc := ctx.controller
   765  
   766  	preSetter := func(value reflect.Value, names ...string) (processed bool, err error) {
   767  		if cc.targetSetter != nil {
   768  			if err = cc.targetSetter(&value, names...); err == nil {
   769  				processed = true
   770  			} else {
   771  				if err != ErrShouldFallback { //nolint:errorlint //want it exactly
   772  					return // has error
   773  				}
   774  				err, processed = nil, false
   775  			}
   776  		}
   777  		return
   778  	}
   779  
   780  	var ec = errors.New("map -> struct errors")
   781  	defer ec.Defer(&err)
   782  
   783  	keys := source.MapKeys()
   784  	for _, key := range keys {
   785  		src := source.MapIndex(key)
   786  		st := src.Kind()
   787  		if st == reflect.Interface {
   788  			src = src.Elem()
   789  		}
   790  
   791  		// convert map key to string type
   792  		key, err = rToString(key, tool.StringType)
   793  		if err != nil {
   794  			continue // ignore non-string key
   795  		}
   796  		ks := key.String()
   797  		dbglog.Log("  key %q, src: %v (%v)", ks, tool.Valfmt(&src), tool.Typfmtv(&src))
   798  
   799  		if cc.targetSetter != nil {
   800  			newtyp := src.Type()
   801  			val := reflect.New(newtyp).Elem()
   802  			err = ctx.controller.copyTo(ctx.Params, src, val)
   803  			dbglog.Log("  nv.%q: %v (%v) ", ks, tool.Valfmt(&val), tool.Typfmtv(&val))
   804  			var processed bool
   805  			if processed, err = preSetter(val, ks); err != nil || processed {
   806  				ec.Attach(err)
   807  				continue
   808  			}
   809  		}
   810  	}
   811  	return
   812  }
   813  
   814  //nolint:lll,gocognit //keep it
   815  func (c *fromMapConverter) toStruct(ctx *ValueConverterContext, source reflect.Value, targetType reflect.Type) (target reflect.Value, err error) {
   816  	cc := ctx.controller
   817  
   818  	preSetter := func(value reflect.Value, names ...string) (processed bool, err error) {
   819  		if cc.targetSetter != nil {
   820  			if err = cc.targetSetter(&value, names...); err == nil {
   821  				processed = true
   822  			} else {
   823  				if err != ErrShouldFallback { //nolint:errorlint //want it exactly
   824  					return // has error
   825  				}
   826  				err, processed = nil, false
   827  			}
   828  		}
   829  		return
   830  	}
   831  
   832  	var ec = errors.New("map -> struct errors")
   833  	defer ec.Defer(&err)
   834  
   835  	target = reflect.New(targetType).Elem()
   836  	keys := source.MapKeys()
   837  	for _, key := range keys {
   838  		src := source.MapIndex(key)
   839  		st := src.Kind()
   840  		if st == reflect.Interface {
   841  			src = src.Elem()
   842  		}
   843  
   844  		// convert map key to string type
   845  		key, err = rToString(key, tool.StringType)
   846  		if err != nil {
   847  			continue // ignore non-string key
   848  		}
   849  		ks := key.String()
   850  		dbglog.Log("  key %q, src: %v (%v)", ks, tool.Valfmt(&src), tool.Typfmtv(&src))
   851  
   852  		if cc.targetSetter != nil {
   853  			newtyp := src.Type()
   854  			val := reflect.New(newtyp).Elem()
   855  			err = ctx.controller.copyTo(ctx.Params, src, val)
   856  			dbglog.Log("  nv.%q: %v (%v) ", ks, tool.Valfmt(&val), tool.Typfmtv(&val))
   857  			var processed bool
   858  			if processed, err = preSetter(val, ks); err != nil || processed {
   859  				ec.Attach(err)
   860  				continue
   861  			}
   862  		}
   863  
   864  		// use the key.(string) as the target struct field name
   865  		tsf, ok := targetType.FieldByName(ks)
   866  		if !ok {
   867  			continue
   868  		}
   869  
   870  		fld := target.FieldByName(ks)
   871  		// dbglog.Log("  fld %q: ", ks)
   872  		tsft := tsf.Type
   873  		tsfk := tsft.Kind()
   874  		if tsfk == reflect.Interface {
   875  			// tsft = tsft.Elem()
   876  			fld = fld.Elem()
   877  		} else if tsfk == reflect.Ptr {
   878  			dbglog.Log("  fld.%q: %v (%v)", ks, tool.Valfmt(&fld), tool.Typfmtv(&fld))
   879  			if fld.IsNil() {
   880  				n := reflect.New(fld.Type().Elem())
   881  				target.FieldByName(ks).Set(n)
   882  				fld = target.FieldByName(ks)
   883  			}
   884  			// tsft = tsft.Elem()
   885  			fld = fld.Elem()
   886  			dbglog.Log("  fld.%q: %v (%v)", ks, tool.Valfmt(&fld), tool.Typfmtv(&fld))
   887  		}
   888  
   889  		err = ctx.controller.copyTo(ctx.Params, src, fld)
   890  		dbglog.Log("  nv.%q: %v (%v) ", ks, tool.Valfmt(&fld), tool.Typfmtv(&fld))
   891  		ec.Attach(err)
   892  
   893  		// var nv reflect.Value
   894  		// nv, err = c.fromConverterBase.convertToOrZeroTarget(ctx, src, tsft)
   895  		// dbglog.Log("  nv.%q: %v (%v) ", ks, valfmt(&nv), typfmtv(&nv))
   896  		// if err == nil {
   897  		//	if fld.CanSet() {
   898  		//		if tsfk == reflect.Ptr {
   899  		//			n := reflect.New(fld.Type().Elem())
   900  		//			n.Elem().Set(nv)
   901  		//			nv = n
   902  		//		}
   903  		//		fld.Set(nv)
   904  		//	} else {
   905  		//		err = ErrCannotSet.FormatWith(valfmt(&fld), typfmtv(&fld), valfmt(&nv), typfmtv(&nv))
   906  		//	}
   907  		// }
   908  	}
   909  	dbglog.Log("  target: %v (%v) ", tool.Valfmt(&target), tool.Typfmtv(&target))
   910  	return
   911  }
   912  
   913  func (c *fromMapConverter) Match(params *Params, source, target reflect.Type) (ctx *ValueConverterContext, yes bool) {
   914  	if yes = source.Kind() == reflect.Map && target.Kind() != reflect.Map; yes {
   915  		ctx = &ValueConverterContext{params}
   916  	}
   917  	return
   918  }
   919  
   920  //
   921  
   922  //
   923  
   924  //
   925  
   926  // fromSyncPkgConverter provides default actions for all entities
   927  // in sync package, such as sync.Pool, sync.RWMutex, and so on.
   928  //
   929  // By default, these entities should NOT be copied from one to another
   930  // one. So our default actions are empty.
   931  type fromSyncPkgConverter struct{ fromConverterBase }
   932  
   933  //nolint:lll //keep it
   934  func (c *fromSyncPkgConverter) Match(params *Params, source, target reflect.Type) (ctx *ValueConverterContext, yes bool) {
   935  	// st.PkgPath() . st.Name()
   936  	if yes = source.Kind() == reflect.Struct && strings.HasPrefix(source.String(), "sync."); yes {
   937  		ctx = &ValueConverterContext{params}
   938  		dbglog.Log("    src: %v, tgt: %v | Matched", source, target)
   939  	} else {
   940  		// dbglog.Log("    src: %v, tgt: %v", source, target)
   941  	}
   942  	return
   943  }
   944  func (c *fromSyncPkgConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) {
   945  	return
   946  }
   947  
   948  func (c *fromSyncPkgConverter) Transform(ctx *ValueConverterContext, source reflect.Value, targetType reflect.Type) (target reflect.Value, err error) {
   949  	return
   950  }
   951  
   952  //
   953  
   954  type fromBytesBufferConverter struct{ fromConverterBase }
   955  
   956  func (c *fromBytesBufferConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) {
   957  	tgt, tgtptr := tool.Rdecode(target)
   958  	tgtType := c.safeType(tgt, tgtptr) // because tgt might be invalid, so we fetch tgt type via its pointer
   959  	// tgtType := target.Type()
   960  	dbglog.Log(" target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v",
   961  		tool.Typfmtv(&target), tool.Typfmt(target.Type()),
   962  		tool.Typfmtv(&tgtptr), tool.Typfmtv(&tgt), tool.Typfmt(tgtType))
   963  
   964  	if processed := c.checkTarget(ctx, tgt, tgtType); processed {
   965  		// target.Set(ret)
   966  		return
   967  	}
   968  
   969  	from := source.Interface().(bytes.Buffer) //nolint:errcheck //no need
   970  	tv := tgtptr.Interface()
   971  	switch to := tv.(type) {
   972  	case bytes.Buffer:
   973  		to.Reset()
   974  		to.Write(from.Bytes())
   975  		// dbglog.Log("     to: %v", to.String())
   976  	case *bytes.Buffer:
   977  		to.Reset()
   978  		to.Write(from.Bytes())
   979  		// dbglog.Log("    *to: %v", to.String())
   980  	case *[]byte:
   981  		tgtptr.Elem().Set(reflect.ValueOf(from.Bytes()))
   982  	case []byte:
   983  		tgtptr.Elem().Set(reflect.ValueOf(from.Bytes()))
   984  	}
   985  	return
   986  }
   987  
   988  //nolint:lll //keep it
   989  func (c *fromBytesBufferConverter) Transform(ctx *ValueConverterContext, source reflect.Value, targetType reflect.Type) (target reflect.Value, err error) {
   990  	var processed bool
   991  	if target, processed = c.checkSource(ctx, source, targetType); processed {
   992  		return
   993  	}
   994  
   995  	// TO/DO implement me
   996  	// panic("implement me")
   997  	from := source.Interface().(bytes.Buffer) //nolint:errcheck //no need
   998  	var to bytes.Buffer
   999  	_, err = to.Write(from.Bytes())
  1000  	target = reflect.ValueOf(to)
  1001  	return
  1002  }
  1003  
  1004  //nolint:lll //keep it
  1005  func (c *fromBytesBufferConverter) Match(params *Params, source, target reflect.Type) (ctx *ValueConverterContext, yes bool) {
  1006  	// st.PkgPath() . st.Name()
  1007  	if yes = source.Kind() == reflect.Struct && source.String() == "bytes.Buffer"; yes {
  1008  		ctx = &ValueConverterContext{params}
  1009  		dbglog.Log("    src: %v, tgt: %v | Matched", source, target)
  1010  	} else {
  1011  		// dbglog.Log("    src: %v, tgt: %v", source, target)
  1012  	}
  1013  	return
  1014  }
  1015  
  1016  //
  1017  
  1018  //
  1019  
  1020  //
  1021  
  1022  type fromTimeConverter struct{ fromConverterBase }
  1023  
  1024  func (c *fromTimeConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) {
  1025  	tgt, tgtptr := tool.Rdecode(target)
  1026  	tgtType := c.safeType(tgt, tgtptr) // because tgt might be invalid, so we fetch tgt type via its pointer
  1027  	dbglog.Log("  target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v",
  1028  		tool.Typfmtv(&target), tool.Typfmt(target.Type()), tool.Typfmtv(&tgtptr),
  1029  		tool.Typfmtv(&tgt), tool.Typfmt(tgtType))
  1030  
  1031  	if processed := c.checkTarget(ctx, tgt, tgtType); processed {
  1032  		// tgtptr.Set(ret)
  1033  		return
  1034  	}
  1035  
  1036  	var ret reflect.Value
  1037  	var e error
  1038  	if ret, e = c.Transform(ctx, source, tgtType); e == nil {
  1039  		if k := tgtptr.Kind(); k == reflect.Interface { //nolint:gocritic // no need to switch to 'switch' clause
  1040  			tgtptr.Set(ret)
  1041  		} else if k == reflect.Ptr {
  1042  			tgtptr.Elem().Set(ret)
  1043  		} else if tgt.CanSet() {
  1044  			tgt.Set(ret)
  1045  		} else {
  1046  			err = ErrCannotSet.FormatWith(tool.Valfmt(&tgt), tool.Typfmtv(&tgt), tool.Valfmt(&ret), tool.Typfmtv(&ret))
  1047  		}
  1048  		dbglog.Log("  tgt: %v (ret = %v)", tool.Valfmt(&tgt), tool.Valfmt(&ret))
  1049  		return
  1050  	}
  1051  
  1052  	dbglog.Log("  Transform() failed: %v", e)
  1053  	dbglog.Log("              trying to postCopyTo()")
  1054  	err = c.postCopyTo(ctx, source, target)
  1055  	return
  1056  }
  1057  
  1058  //nolint:lll //keep it
  1059  func (c *fromTimeConverter) Transform(ctx *ValueConverterContext, source reflect.Value, targetType reflect.Type) (target reflect.Value, err error) {
  1060  	if source.IsValid() {
  1061  		var processed bool
  1062  		if target, processed = c.checkSource(ctx, source, targetType); processed {
  1063  			return
  1064  		}
  1065  
  1066  		switch k := targetType.Kind(); k { //nolint:exhaustive //no need
  1067  		case reflect.Bool:
  1068  			b := tool.IsNil(source) || tool.IsZero(source)
  1069  			target = reflect.ValueOf(b)
  1070  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1071  			tm := source.Interface().(time.Time) //nolint:errcheck //no need
  1072  			t := reflect.ValueOf(tm.Unix())
  1073  			target, err = rToInteger(t, targetType)
  1074  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  1075  			tm := source.Interface().(time.Time) //nolint:errcheck //no need
  1076  			t := reflect.ValueOf(tm.Unix())
  1077  			target, err = rToUInteger(t, targetType)
  1078  
  1079  		case reflect.Float32, reflect.Float64:
  1080  			tm := source.Interface().(time.Time) //nolint:errcheck //no need
  1081  			f := float64(tm.UnixNano()) / 1e9    //nolint:gomnd //simple case
  1082  			t := reflect.ValueOf(f)
  1083  			target, err = rToFloat(t, targetType)
  1084  		case reflect.Complex64, reflect.Complex128:
  1085  			tm := source.Interface().(time.Time) //nolint:errcheck //no need
  1086  			f := float64(tm.UnixNano()) / 1e9    //nolint:gomnd //simple case
  1087  			t := reflect.ValueOf(f)
  1088  			target, err = rToComplex(t, targetType)
  1089  
  1090  		case reflect.String:
  1091  			tm := source.Interface().(time.Time) //nolint:errcheck //no need
  1092  			str := tm.Format(time.RFC3339)
  1093  			t := reflect.ValueOf(str)
  1094  			target, err = rToString(t, targetType)
  1095  
  1096  		default:
  1097  			target, err = c.convertToOrZeroTarget(ctx, source, targetType)
  1098  		}
  1099  	} else {
  1100  		target, err = c.convertToOrZeroTarget(ctx, source, targetType)
  1101  	}
  1102  	return
  1103  }
  1104  
  1105  func (c *fromTimeConverter) Match(params *Params, source, target reflect.Type) (ctx *ValueConverterContext, yes bool) {
  1106  	if sk := source.Kind(); sk == reflect.Struct {
  1107  		if yes = source.Name() == "Time" && source.PkgPath() == timeConstString; yes {
  1108  			ctx = &ValueConverterContext{params}
  1109  		}
  1110  	}
  1111  	return
  1112  }
  1113  
  1114  //
  1115  
  1116  //nolint:gochecknoglobals //i know that
  1117  var knownTimeLayouts = []string{
  1118  	"2006-01-02 15:04:05.000000000",
  1119  	"2006-01-02 15:04:05.000000",
  1120  	"2006-01-02 15:04:05.000",
  1121  	"2006-01-02 15:04:05",
  1122  	"2006-01-02 15:04",
  1123  	"2006-01-02",
  1124  
  1125  	"2006-01-02 15:04:05.999999999Z07:00",
  1126  	"2006-01-02 15:04:05.999999999",
  1127  	"2006-01-02 15:04:05Z07:00",
  1128  	"2006-01-02 15:04:05",
  1129  
  1130  	time.RFC3339,
  1131  
  1132  	time.ANSIC,
  1133  	time.UnixDate,
  1134  	time.RubyDate,
  1135  	time.RFC822,
  1136  	time.RFC822Z,
  1137  	time.RFC850,
  1138  	time.RFC1123,
  1139  	time.RFC1123Z,
  1140  	time.RFC3339Nano,
  1141  	time.Kitchen,
  1142  	time.Stamp,
  1143  	time.StampMilli,
  1144  	time.StampMicro,
  1145  	time.StampNano,
  1146  
  1147  	"01/02/2006 15:04:05.000000000",
  1148  	"01/02/2006 15:04:05.000000",
  1149  	"01/02/2006 15:04:05.000",
  1150  	"01/02/2006 15:04:05",
  1151  	"01/02/2006 15:04",
  1152  	"01/02/2006",
  1153  }
  1154  
  1155  type toTimeConverter struct{ toConverterBase }
  1156  
  1157  // func (c *toTimeConverter) fallback(target reflect.Value) (err error) {
  1158  //	var timeTimeTyp = reflect.TypeOf((*time.Time)(nil)).Elem()
  1159  //	rindirect(target).Set(reflect.Zero(timeTimeTyp))
  1160  //	return
  1161  // }
  1162  
  1163  func (c *toTimeConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) {
  1164  	// tgtType := target.Type()
  1165  	tgt, tgtptr := tool.Rdecode(target)
  1166  	tgtType := c.safeType(tgt, tgtptr) // because tgt might be invalid, so we fetch tgt type via its pointer
  1167  	dbglog.Log("  target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v",
  1168  		tool.Typfmtv(&target), tool.Typfmt(target.Type()), tool.Typfmtv(&tgtptr),
  1169  		tool.Typfmtv(&tgt), tool.Typfmt(tgtType))
  1170  
  1171  	if processed := c.checkTarget(ctx, tgt, tgtType); processed {
  1172  		// target.Set(ret)
  1173  		return
  1174  	}
  1175  
  1176  	if ret, e := c.Transform(ctx, source, tgtType); e == nil {
  1177  		target.Set(ret)
  1178  	} else if ctx.isGroupedFlagOKDeeply(cms.ClearIfInvalid) {
  1179  		err = c.fallback(target)
  1180  	}
  1181  	return
  1182  }
  1183  
  1184  func tryParseTime(s string) (tm time.Time) {
  1185  	var err error
  1186  	for _, layout := range knownTimeLayouts {
  1187  		tm, err = time.Parse(layout, s)
  1188  		if err == nil {
  1189  			return
  1190  		}
  1191  	}
  1192  	return
  1193  }
  1194  
  1195  //nolint:lll //keep it
  1196  func (c *toTimeConverter) Transform(ctx *ValueConverterContext, source reflect.Value, targetType reflect.Type) (target reflect.Value, err error) {
  1197  	if source.IsValid() { //nolint:gocritic // no need to switch to 'switch' clause
  1198  		var processed bool
  1199  		if target, processed = c.checkSource(ctx, source, targetType); processed {
  1200  			return
  1201  		}
  1202  
  1203  		switch k := source.Kind(); k { //nolint:exhaustive //no need
  1204  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1205  			tm := time.Unix(source.Int(), 0)
  1206  			target = reflect.ValueOf(tm)
  1207  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  1208  			tm := time.Unix(int64(source.Uint()), 0)
  1209  			target = reflect.ValueOf(tm)
  1210  
  1211  		case reflect.Float32, reflect.Float64:
  1212  			sec, dec := math.Modf(source.Float())
  1213  			tm := time.Unix(int64(sec), int64(dec*(1e9)))
  1214  			target = reflect.ValueOf(tm)
  1215  		case reflect.Complex64, reflect.Complex128:
  1216  			sec, dec := math.Modf(real(source.Complex()))
  1217  			tm := time.Unix(int64(sec), int64(dec*(1e9)))
  1218  			target = reflect.ValueOf(tm)
  1219  
  1220  		case reflect.String:
  1221  			tm := tryParseTime(source.String())
  1222  			target = reflect.ValueOf(tm)
  1223  
  1224  		default:
  1225  			err = ErrCannotConvertTo.FormatWith(source, tool.Typfmtv(&source), targetType, targetType.Kind())
  1226  		}
  1227  	} else if ctx.isGroupedFlagOKDeeply(cms.ClearIfInvalid) {
  1228  		target = reflect.Zero(targetType)
  1229  	} else {
  1230  		err = errors.New("source (%v) is invalid", tool.Valfmt(&source))
  1231  	}
  1232  	return
  1233  }
  1234  
  1235  func (c *toTimeConverter) Match(params *Params, source, target reflect.Type) (ctx *ValueConverterContext, yes bool) {
  1236  	if tk := target.Kind(); tk == reflect.Struct {
  1237  		if yes = target.Name() == "Time" && target.PkgPath() == timeConstString; yes {
  1238  			ctx = &ValueConverterContext{params}
  1239  		}
  1240  	}
  1241  	return
  1242  }
  1243  
  1244  //
  1245  
  1246  //
  1247  
  1248  //
  1249  
  1250  type fromDurationConverter struct{ fromConverterBase }
  1251  
  1252  func (c *fromDurationConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) {
  1253  	tgt, tgtptr := tool.Rdecode(target)
  1254  	tgttyp := c.safeType(tgt, tgtptr) // because tgt might be invalid, so we fetch tgt type via its pointer
  1255  	dbglog.Log("  target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v",
  1256  		tool.Typfmtv(&target), tool.Typfmt(target.Type()), tool.Typfmtv(&tgtptr),
  1257  		tool.Typfmtv(&tgt), tool.Typfmt(tgttyp))
  1258  
  1259  	var processed bool
  1260  	if target, processed = c.checkSource(ctx, source, tgttyp); processed {
  1261  		return
  1262  	}
  1263  
  1264  	var ret reflect.Value
  1265  	var e error
  1266  	if ret, e = c.Transform(ctx, source, tgttyp); e == nil {
  1267  		if tgtptr.Kind() == reflect.Interface { //nolint:gocritic // no need to switch to 'switch' clause
  1268  			tgtptr.Set(ret)
  1269  		} else if tgtptr.Kind() == reflect.Ptr {
  1270  			tgtptr.Elem().Set(ret)
  1271  		} else if tgt.CanSet() {
  1272  			tgt.Set(ret)
  1273  		} else {
  1274  			err = ErrCannotSet.FormatWith(tool.Valfmt(&tgt), tool.Typfmtv(&tgt), tool.Valfmt(&ret), tool.Typfmtv(&ret))
  1275  		}
  1276  		dbglog.Log("  tgt: %v (ret = %v)", tool.Valfmt(&tgt), tool.Valfmt(&ret))
  1277  		return
  1278  	}
  1279  
  1280  	dbglog.Log("  Transform() failed: %v", e)
  1281  	dbglog.Log("              trying to postCopyTo()")
  1282  	err = c.postCopyTo(ctx, source, target)
  1283  	return
  1284  }
  1285  
  1286  //nolint:lll //keep it
  1287  func (c *fromDurationConverter) Transform(ctx *ValueConverterContext, source reflect.Value, targetType reflect.Type) (target reflect.Value, err error) {
  1288  	if source.IsValid() {
  1289  		// var processed bool
  1290  		// if processed, target, err = c.preprocess(ctx, source, targetType); processed {
  1291  		//	return
  1292  		// }
  1293  
  1294  		var processed bool
  1295  		if target, processed = c.checkSource(ctx, source, targetType); processed {
  1296  			return
  1297  		}
  1298  
  1299  		switch k := targetType.Kind(); k { //nolint:exhaustive //no need
  1300  		case reflect.Bool:
  1301  			target = rToBool(source)
  1302  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1303  			target, err = rToInteger(source, targetType)
  1304  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  1305  			target, err = rToUInteger(source, targetType)
  1306  
  1307  		case reflect.Uintptr:
  1308  			target = rToUIntegerHex(source, targetType)
  1309  		// case reflect.UnsafePointer:
  1310  		//	// target = rToUIntegerHex(source, targetType)
  1311  		//	err = errors.InvalidArgument
  1312  		// case reflect.Ptr:
  1313  		//	//target = rToUIntegerHex(source, targetType)
  1314  		//	err = errors.InvalidArgument
  1315  
  1316  		case reflect.Float32, reflect.Float64:
  1317  			target, err = rToFloat(source, targetType)
  1318  		case reflect.Complex64, reflect.Complex128:
  1319  			target, err = rToComplex(source, targetType)
  1320  
  1321  		case reflect.String:
  1322  			target, err = rToString(source, targetType)
  1323  
  1324  		// reflect.Array
  1325  		// reflect.Chan
  1326  		// reflect.Func
  1327  		// reflect.Interface
  1328  		// reflect.Map
  1329  		// reflect.Slice
  1330  		// reflect.Struct
  1331  
  1332  		default:
  1333  			target, err = c.convertToOrZeroTarget(ctx, source, targetType)
  1334  		}
  1335  	} else {
  1336  		target, err = c.convertToOrZeroTarget(ctx, source, targetType)
  1337  	}
  1338  	return
  1339  }
  1340  
  1341  //nolint:lll //keep it
  1342  func (c *fromDurationConverter) Match(params *Params, source, target reflect.Type) (ctx *ValueConverterContext, yes bool) {
  1343  	if sk := source.Kind(); sk == reflect.Int64 {
  1344  		if yes = source.Name() == "Duration" && source.PkgPath() == timeConstString; yes {
  1345  			ctx = &ValueConverterContext{params}
  1346  		}
  1347  	}
  1348  	return
  1349  }
  1350  
  1351  //
  1352  
  1353  //
  1354  
  1355  //
  1356  
  1357  type toDurationConverter struct{ toConverterBase }
  1358  
  1359  func (c *toDurationConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) {
  1360  	// tgtType := target.Type()
  1361  	tgt, tgtptr := tool.Rdecode(target)
  1362  	tgtType := c.safeType(tgt, tgtptr) // because tgt might be invalid, so we fetch tgt type via its pointer
  1363  	dbglog.Log("  target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v",
  1364  		tool.Typfmtv(&target), tool.Typfmt(target.Type()), tool.Typfmtv(&tgtptr),
  1365  		tool.Typfmtv(&tgt), tool.Typfmt(tgtType))
  1366  
  1367  	if processed := c.checkTarget(ctx, tgt, tgtType); processed {
  1368  		// tgtptr.Set(ret)
  1369  		return
  1370  	}
  1371  
  1372  	if ret, e := c.Transform(ctx, source, tgtType); e == nil {
  1373  		target.Set(ret)
  1374  	} else if ctx.isGroupedFlagOKDeeply(cms.ClearIfInvalid) {
  1375  		err = c.fallback(target)
  1376  	}
  1377  	return
  1378  }
  1379  
  1380  //nolint:lll //keep it
  1381  func (c *toDurationConverter) Transform(ctx *ValueConverterContext, source reflect.Value, targetType reflect.Type) (target reflect.Value, err error) {
  1382  	if source.IsValid() { //nolint:nestif,gocritic // no need to switch to 'switch' clause
  1383  		var processed bool
  1384  		if target, processed = c.checkSource(ctx, source, targetType); processed {
  1385  			return
  1386  		}
  1387  
  1388  		switch k := source.Kind(); k { //nolint:exhaustive //no need
  1389  		case reflect.Bool:
  1390  			if source.Bool() {
  1391  				target = reflect.ValueOf(1 * time.Nanosecond)
  1392  			} else {
  1393  				target = reflect.ValueOf(0 * time.Second)
  1394  			}
  1395  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1396  			target = reflect.ValueOf(time.Duration(source.Int()))
  1397  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  1398  			target = reflect.ValueOf(time.Duration(int64(source.Uint())))
  1399  
  1400  		case reflect.Uintptr:
  1401  			target = reflect.ValueOf(time.Duration(int64(syscalls.UintptrToUint(source.Pointer()))))
  1402  		// case reflect.UnsafePointer:
  1403  		//	// target = rToUIntegerHex(source, targetType)
  1404  		//	err = errors.InvalidArgument
  1405  		// case reflect.Ptr:
  1406  		//	//target = rToUIntegerHex(source, targetType)
  1407  		//	err = errors.InvalidArgument
  1408  
  1409  		case reflect.Float32, reflect.Float64:
  1410  			target = reflect.ValueOf(time.Duration(int64(source.Float())))
  1411  		case reflect.Complex64, reflect.Complex128:
  1412  			target = reflect.ValueOf(time.Duration(int64(real(source.Complex()))))
  1413  
  1414  		case reflect.String:
  1415  			var dur time.Duration
  1416  			dur, err = time.ParseDuration(source.String())
  1417  			if err == nil {
  1418  				target = reflect.ValueOf(dur)
  1419  			}
  1420  
  1421  		// reflect.Array
  1422  		// reflect.Chan
  1423  		// reflect.Func
  1424  		// reflect.Interface
  1425  		// reflect.Map
  1426  		// reflect.Slice
  1427  		// reflect.Struct
  1428  
  1429  		default:
  1430  			err = ErrCannotConvertTo.FormatWith(source, tool.Typfmtv(&source), targetType, targetType.Kind())
  1431  		}
  1432  	} else if ctx.isGroupedFlagOKDeeply(cms.ClearIfInvalid) {
  1433  		target = reflect.Zero(targetType)
  1434  	} else {
  1435  		err = errors.New("source (%v) is invalid", tool.Valfmt(&source))
  1436  	}
  1437  	return
  1438  }
  1439  
  1440  //nolint:lll //keep it
  1441  func (c *toDurationConverter) Match(params *Params, source, target reflect.Type) (ctx *ValueConverterContext, yes bool) {
  1442  	if tk := target.Kind(); tk == reflect.Int64 {
  1443  		if yes = target.Name() == "Duration" && target.PkgPath() == timeConstString; yes {
  1444  			ctx = &ValueConverterContext{params}
  1445  		}
  1446  	}
  1447  	return
  1448  }
  1449  
  1450  //
  1451  
  1452  //
  1453  
  1454  type toFuncConverter struct{ fromConverterBase }
  1455  
  1456  func copyToFuncImpl(controller *cpController, source, target reflect.Value, targetType reflect.Type) (err error) {
  1457  	var presets []typ.Any
  1458  	if controller != nil {
  1459  		presets = controller.funcInputs
  1460  	}
  1461  	if targetType.NumIn() == len(presets)+1 {
  1462  		var args []reflect.Value
  1463  		for _, in := range presets {
  1464  			args = append(args, reflect.ValueOf(in))
  1465  		}
  1466  		args = append(args, source)
  1467  
  1468  		res := target.Call(args)
  1469  		if len(res) > 0 {
  1470  			last := res[len(res)-1]
  1471  			if tool.Iserrortype(targetType.Out(len(res)-1)) && !tool.IsNil(last) {
  1472  				err = last.Interface().(error) //nolint:errcheck //no need
  1473  			}
  1474  		}
  1475  	}
  1476  	return
  1477  }
  1478  
  1479  // processUnexportedField try to set newval into target if it's an unexported field.
  1480  //
  1481  //nolint:lll //keep it
  1482  func (c *toFuncConverter) processUnexportedField(ctx *ValueConverterContext, target, newval reflect.Value) (processed bool) {
  1483  	if ctx == nil || ctx.Params == nil {
  1484  		return
  1485  	}
  1486  	processed = ctx.Params.processUnexportedField(target, newval)
  1487  	return
  1488  }
  1489  
  1490  func (c *toFuncConverter) copyTo(ctx *ValueConverterContext, source, src, tgt, tsetter reflect.Value) (err error) {
  1491  	if ctx.isGroupedFlagOKDeeply(cms.Ignore) {
  1492  		return
  1493  	}
  1494  
  1495  	tgttyp := tgt.Type()
  1496  	dbglog.Log("  copyTo: src: %v, tgt: %v,", tool.Typfmtv(&src), tool.Typfmt(tgttyp))
  1497  
  1498  	if k := src.Kind(); k != reflect.Func && ctx.IsPassSourceToTargetFunction() {
  1499  		var controller *cpController
  1500  		if ctx.Params != nil && ctx.controller != nil {
  1501  			controller = ctx.controller
  1502  		}
  1503  		err = copyToFuncImpl(controller, source, tgt, tgttyp)
  1504  	} else if k == reflect.Func {
  1505  		if !c.processUnexportedField(ctx, tgt, src) {
  1506  			tsetter.Set(src)
  1507  		}
  1508  		dbglog.Log("    function pointer copied: %v (%v) -> %v", source.Kind(), source.Interface(), tgt.Kind())
  1509  	}
  1510  	return
  1511  }
  1512  
  1513  func (c *toFuncConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) {
  1514  	src := tool.Rdecodesimple(source)
  1515  	tgt, tgtptr := tool.Rdecode(target)
  1516  	tgtType := c.safeType(tgt, tgtptr) // because tgt might be invalid, so we fetch tgt type via its pointer
  1517  	// Log("  CopyTo: src: %v, tgt: %v,", typfmtv(&src), typfmt(tgtType))
  1518  	dbglog.Log("  target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v",
  1519  		tool.Typfmtv(&target), tool.Typfmt(target.Type()), tool.Typfmtv(&tgtptr),
  1520  		tool.Typfmtv(&tgt), tool.Typfmt(tgtType))
  1521  
  1522  	if processed := c.checkTarget(ctx, tgt, tgtType); processed {
  1523  		// tgtptr.Set(ret)
  1524  		return
  1525  	}
  1526  
  1527  	err = c.copyTo(ctx, source, src, tgt, tgtptr)
  1528  	return
  1529  }
  1530  
  1531  // func (c *toFuncConverter) Transform(ctx *ValueConverterContext, source reflect.Value,
  1532  //	 targetType reflect.Type) (target reflect.Value, err error) {
  1533  //
  1534  //	target = reflect.New(targetType).Elem()
  1535  //
  1536  //	src := rdecodesimple(source)
  1537  //	tgt, tgtptr := rdecode(target)
  1538  //
  1539  //	var processed bool
  1540  //	if target, processed = c.checkSource(ctx, source, targetType); processed {
  1541  //		return
  1542  //	}
  1543  //
  1544  //	err = c.copyTo(ctx, source, src, tgt, tgtptr)
  1545  //	return
  1546  // }
  1547  
  1548  func (c *toFuncConverter) Match(params *Params, source, target reflect.Type) (ctx *ValueConverterContext, yes bool) {
  1549  	if tk := target.Kind(); tk == reflect.Func {
  1550  		yes, ctx = true, &ValueConverterContext{params}
  1551  	}
  1552  	return
  1553  }
  1554  
  1555  //
  1556  
  1557  type fromFuncConverter struct{ fromConverterBase }
  1558  
  1559  func (c *fromFuncConverter) CopyTo(ctx *ValueConverterContext, source, target reflect.Value) (err error) {
  1560  	// tsetter might not be equal to tgt when:
  1561  	//    target represents -> (ptr - interface{} - bool)
  1562  	// such as:
  1563  	//    var a interface{} = true
  1564  	//    var target = reflect.ValueOf(&a)
  1565  	//    tgt, tsetter := rdecodesimple(target), rindirect(target)
  1566  	//    assertNotEqual(tgt, tsetter)
  1567  	//    // in this case, tsetter represents 'a' and tgt represents
  1568  	//    // 'decoded bool(a)'.
  1569  	//
  1570  	src := tool.Rdecodesimple(source)
  1571  	tgt, tgtptr := tool.Rdecode(target)
  1572  	tgtType := c.safeType(tgt, tgtptr)
  1573  	// dbglog.Log("  CopyTo: src: %v, tgt: %v, tsetter: %v", typfmtv(&src), typfmt(tgttyp), typfmtv(&tsetter))
  1574  	dbglog.Log("  target: %v (%v), tgtptr: %v, tgt: %v, tgttyp: %v",
  1575  		tool.Typfmtv(&target), tool.Typfmt(target.Type()), tool.Typfmtv(&tgtptr),
  1576  		tool.Typfmtv(&tgt), tool.Typfmt(tgtType))
  1577  
  1578  	if processed := c.checkTarget(ctx, tgt, tgtType); processed {
  1579  		// target.Set(ret)
  1580  		return
  1581  	}
  1582  
  1583  	if k := tgtType.Kind(); k != reflect.Func && ctx.IsCopyFunctionResultToTarget() {
  1584  		err = c.funcResultToTarget(ctx, src, target)
  1585  		return
  1586  	} else if k == reflect.Func {
  1587  		if !c.processUnexportedField(ctx, tgt, src) {
  1588  			tgtptr.Set(src)
  1589  		}
  1590  		dbglog.Log("    function pointer copied: %v (%v) -> %v", source.Kind(), source.Interface(), target.Kind())
  1591  	}
  1592  
  1593  	// if ret, e := c.Transform(ctx, src, tgttyp); e == nil {
  1594  	//	if !target.IsValid() || isZero(target) {
  1595  	//		return errors.New("cannot set to zero or invalid target")
  1596  	//	}
  1597  	//	if canConvert(&ret, tgttyp) {
  1598  	//		nv := ret.Convert(tgttyp)
  1599  	//		if c.processUnexportedField(ctx, tgt, nv) {
  1600  	//			return
  1601  	//		}
  1602  	//		tsetter.Set(nv)
  1603  	//	}
  1604  	// }
  1605  	return
  1606  }
  1607  
  1608  //nolint:lll,gocognit //keep it
  1609  func (c *fromFuncConverter) funcResultToTarget(ctx *ValueConverterContext, source, target reflect.Value) (err error) {
  1610  	sourceType := source.Type()
  1611  	var presetInArgsLen int
  1612  	var ok bool
  1613  	var controllerIsValid = ctx != nil && ctx.Params != nil && ctx.Params.controller != nil
  1614  	if controllerIsValid {
  1615  		presetInArgsLen = len(ctx.controller.funcInputs)
  1616  	}
  1617  	if sourceType.NumIn() == presetInArgsLen { //nolint:nestif //keep it
  1618  		numOutSrc := sourceType.NumOut()
  1619  		if numOutSrc > 0 {
  1620  			srcResults := source.Call([]reflect.Value{})
  1621  
  1622  			results := srcResults
  1623  			lastoutargtype := sourceType.Out(sourceType.NumOut() - 1)
  1624  			ok = tool.Iserrortype(lastoutargtype)
  1625  			if ok {
  1626  				v := results[len(results)-1].Interface()
  1627  				err, _ = v.(error)
  1628  				if err != nil {
  1629  					return
  1630  				}
  1631  				results = results[:len(results)-1]
  1632  			}
  1633  
  1634  			if len(results) > 0 {
  1635  				if controllerIsValid {
  1636  					// if tk := target.Kind(); tk == reflect.Ptr && isNil(target) {}
  1637  					err = ctx.controller.copyTo(ctx.Params, results[0], target)
  1638  					return
  1639  				}
  1640  
  1641  				// target, err = c.expandResults(ctx, sourceType, targetType, results)
  1642  				err = errors.New("expecting ctx.Params.controller is valid object ptr")
  1643  				return
  1644  			}
  1645  		}
  1646  	}
  1647  	//nolint:lll //keep it
  1648  	err = errors.New("unmatched number of function return and preset input args: function needs %v params but preset %v input args", sourceType.NumIn(), presetInArgsLen)
  1649  	return
  1650  }
  1651  
  1652  // // processUnexportedField try to set newval into target if it's an unexported field
  1653  // func (c *fromFuncConverter) processUnexportedField(ctx *ValueConverterContext, target,
  1654  //	newval reflect.Value) (processed bool) {
  1655  //	if ctx == nil || ctx.Params == nil {
  1656  //		return
  1657  //	}
  1658  //	processed = ctx.Params.processUnexportedField(target, newval)
  1659  //	return
  1660  // }
  1661  
  1662  //nolint:lll //keep it
  1663  func (c *fromFuncConverter) Transform(ctx *ValueConverterContext, source reflect.Value, targetType reflect.Type) (target reflect.Value, err error) {
  1664  	var processed bool
  1665  	if target, processed = c.checkSource(ctx, source, targetType); processed {
  1666  		return
  1667  	}
  1668  
  1669  	target = reflect.New(targetType).Elem()
  1670  	err = c.CopyTo(ctx, source, target)
  1671  
  1672  	// src, tgt, tgttyp := rdecodesimple(source), rdecodesimple(target), rdecodetypesimple(targetType)
  1673  	// Log("  Transform: src: %v, tgt: %v", typfmtv(&src), typfmt(tgttyp))
  1674  	// if k := tgttyp.Kind(); k != reflect.Func && ctx.IsCopyFunctionResultToTarget() {
  1675  	//	target, err = c.funcResultToField(ctx, src, tgttyp)
  1676  	//	return
  1677  	//
  1678  	// } else if k == reflect.Func {
  1679  	//
  1680  	//	if c.processUnexportedField(ctx, tgt, src) {
  1681  	//		ptr := source.Pointer()
  1682  	//		target.SetPointer(unsafe.Pointer(ptr))
  1683  	//	}
  1684  	//	Log("    function pointer copied: %v (%v) -> %v", source.Kind(), source.Interface(), target.Kind())
  1685  	// }
  1686  	return
  1687  }
  1688  
  1689  // func (c *fromFuncConverter) funcResultToField(ctx *ValueConverterContext, source reflect.Value,
  1690  // 	targetType reflect.Type) (target reflect.Value, err error) {
  1691  //	sourceType := source.Type()
  1692  //	var presetInArgsLen int
  1693  //	var ok bool
  1694  //	var controllerIsValid = ctx != nil && ctx.Params != nil && ctx.Params.controller != nil
  1695  //	if controllerIsValid {
  1696  //		presetInArgsLen = len(ctx.controller.funcInputs)
  1697  //	}
  1698  //	if sourceType.NumIn() == presetInArgsLen {
  1699  //		numOutSrc := sourceType.NumOut()
  1700  //		if numOutSrc > 0 {
  1701  //			srcResults := source.Call([]reflect.Value{})
  1702  //
  1703  //			results := srcResults
  1704  //			lastoutargtype := sourceType.Out(sourceType.NumOut() - 1)
  1705  //			ok = iserrortype(lastoutargtype)
  1706  //			if ok {
  1707  //				err, ok = results[len(results)-1].Interface().(error)
  1708  //				if err != nil {
  1709  //					return
  1710  //				}
  1711  //				results = results[:len(results)-1]
  1712  //			}
  1713  //
  1714  //			if len(results) > 0 {
  1715  //				// slice,map,struct
  1716  //				// scalar
  1717  //
  1718  //				target, err = c.expandResults(ctx, sourceType, targetType, results)
  1719  //			}
  1720  //		}
  1721  //	} else {
  1722  //		err = errors.New("unmatched number of function return and preset input args: function needs
  1723  // %v params but preset %v input args", sourceType.NumIn(), presetInArgsLen)
  1724  //	}
  1725  //	return
  1726  // }
  1727  //
  1728  // func (c *fromFuncConverter) expandResults(ctx *ValueConverterContext, sourceType, targetType
  1729  // reflect.Type, results []reflect.Value) (target reflect.Value, err error) {
  1730  //	//srclen := len(results)
  1731  //	switch kind := targetType.Kind(); kind {
  1732  //	case reflect.Bool:
  1733  //		target = rToBool(results[0])
  1734  //	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1735  //		target, err = rToInteger(results[0], targetType)
  1736  //	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1737  //		target, err = rToUInteger(results[0], targetType)
  1738  //	case reflect.Float32, reflect.Float64:
  1739  //		target, err = rToFloat(results[0], targetType)
  1740  //	case reflect.Complex64, reflect.Complex128:
  1741  //		target, err = rToComplex(results[0], targetType)
  1742  //	case reflect.String:
  1743  //		{
  1744  //			var processed bool
  1745  //			if processed, target, err = ctx.Preprocess(results[0], targetType, c); processed {
  1746  //				return
  1747  //			}
  1748  //		}
  1749  //		target, err = rToString(results[0], targetType)
  1750  //
  1751  //	case reflect.Array:
  1752  //		target, err = rToArray(ctx, results[0], targetType, -1)
  1753  //	case reflect.Slice:
  1754  //		target, err = rToSlice(ctx, results[0], targetType, -1)
  1755  //	case reflect.Map:
  1756  //		target, err = rToMap(ctx, results[0], sourceType, targetType)
  1757  //	case reflect.Struct:
  1758  //		target, err = rToStruct(ctx, results[0], sourceType, targetType)
  1759  //	case reflect.Func:
  1760  //		target, err = rToFunc(ctx, results[0], sourceType, targetType)
  1761  //
  1762  //	case reflect.Interface, reflect.Ptr, reflect.Chan:
  1763  //		if results[0].Type().ConvertibleTo(targetType) {
  1764  //			target = results[0].Convert(targetType)
  1765  //		} else {
  1766  //			err = errCannotConvertTo.FormatWith(typfmt(results[0].Type()), typfmt(targetType))
  1767  //		}
  1768  //
  1769  //	case reflect.UnsafePointer:
  1770  //		err = errCannotConvertTo.FormatWith(typfmt(results[0].Type()), typfmt(targetType))
  1771  //	}
  1772  //	return
  1773  // }
  1774  
  1775  func (c *fromFuncConverter) Match(params *Params, source, target reflect.Type) (ctx *ValueConverterContext, yes bool) {
  1776  	if sk := source.Kind(); sk == reflect.Func {
  1777  		yes, ctx = true, &ValueConverterContext{params}
  1778  	}
  1779  	return
  1780  }