gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/config/handler.go (about)

     1  package config
     2  
     3  import (
     4  	"encoding"
     5  	"encoding/json"
     6  	"gitee.com/sy_183/go-common/assert"
     7  	"gitee.com/sy_183/go-common/errors"
     8  	"gitee.com/sy_183/go-common/strings/unsafe"
     9  	"gopkg.in/yaml.v3"
    10  	"reflect"
    11  	"strconv"
    12  	"time"
    13  )
    14  
    15  type handler interface {
    16  	canHandle(c any) bool
    17  	handle(c any) (nc any, modified bool, err error)
    18  	handleAfterChildren(c any) (nc any, modified bool, err error)
    19  }
    20  
    21  type PreModifyConfig interface {
    22  	PreModify() (nc any, modified bool)
    23  }
    24  
    25  type PreHandlerConfig interface {
    26  	PreHandle()
    27  }
    28  
    29  type PreModifyAfterChildrenConfig interface {
    30  	PreModifyAfterChildren() (nc any, modified bool)
    31  }
    32  
    33  type PreHandleAfterChildrenConfig interface {
    34  	PreHandleAfterChildren()
    35  }
    36  
    37  type PostModifyConfig interface {
    38  	PostModify() (nc any, modified bool, err error)
    39  }
    40  
    41  type PostHandlerConfig interface {
    42  	PostHandle() error
    43  }
    44  
    45  type PostModifyAfterChildrenConfig interface {
    46  	PostModifyAfterChildren() (nc any, modified bool, err error)
    47  }
    48  
    49  type PostHandleAfterChildrenConfig interface {
    50  	PostHandleAfterChildren() error
    51  }
    52  
    53  type preHandler struct{}
    54  
    55  func (preHandler) canHandle(c any) bool {
    56  	if _, ok := c.(PreModifyConfig); ok {
    57  		return true
    58  	}
    59  	if _, ok := c.(PreHandlerConfig); ok {
    60  		return true
    61  	}
    62  	return false
    63  }
    64  
    65  func (p preHandler) handle(c any) (nc any, modified bool, err error) {
    66  	nc = c
    67  	if pmc, ok := nc.(PreModifyConfig); ok {
    68  		if nc, modified = pmc.PreModify(); !modified {
    69  			nc = c
    70  		}
    71  	}
    72  	if phc, ok := nc.(PreHandlerConfig); ok {
    73  		phc.PreHandle()
    74  	}
    75  	return
    76  }
    77  
    78  func (p preHandler) handleAfterChildren(c any) (nc any, modified bool, err error) {
    79  	nc = c
    80  	if pmc, ok := nc.(PreModifyAfterChildrenConfig); ok {
    81  		if nc, modified = pmc.PreModifyAfterChildren(); !modified {
    82  			nc = c
    83  		}
    84  	}
    85  	if phc, ok := nc.(PreHandleAfterChildrenConfig); ok {
    86  		phc.PreHandleAfterChildren()
    87  	}
    88  	return
    89  }
    90  
    91  type postHandler struct{}
    92  
    93  func (postHandler) canHandle(c any) bool {
    94  	if _, ok := c.(PostModifyConfig); ok {
    95  		return true
    96  	}
    97  	if _, ok := c.(PostHandlerConfig); ok {
    98  		return true
    99  	}
   100  	return false
   101  }
   102  
   103  func (postHandler) handle(c any) (nc any, modified bool, err error) {
   104  	nc = c
   105  	if pmc, ok := nc.(PostModifyConfig); ok {
   106  		if nc, modified, err = pmc.PostModify(); err != nil {
   107  			return
   108  		} else if !modified {
   109  			nc = c
   110  		} else {
   111  			ct := reflect.TypeOf(c)
   112  			nct := reflect.TypeOf(nc)
   113  			if ct.Kind() == reflect.Ptr && ct.Elem() == nct {
   114  				nec := reflect.New(nct)
   115  				nec.Elem().Set(reflect.ValueOf(nc))
   116  				nc = nec.Interface()
   117  			}
   118  		}
   119  	}
   120  	if phc, ok := nc.(PostHandlerConfig); ok {
   121  		err = phc.PostHandle()
   122  	}
   123  	return
   124  }
   125  
   126  func (postHandler) handleAfterChildren(c any) (nc any, modified bool, err error) {
   127  	nc = c
   128  	if pmc, ok := nc.(PostModifyAfterChildrenConfig); ok {
   129  		if nc, modified, err = pmc.PostModifyAfterChildren(); err != nil {
   130  			return
   131  		} else if !modified {
   132  			nc = c
   133  		} else {
   134  			ct := reflect.TypeOf(c)
   135  			nct := reflect.TypeOf(nc)
   136  			if ct.Kind() == reflect.Ptr && ct.Elem() == nct {
   137  				ncp := reflect.New(nct)
   138  				ncp.Elem().Set(reflect.ValueOf(nc))
   139  				nc = ncp.Interface()
   140  			}
   141  		}
   142  	}
   143  
   144  	if phc, ok := nc.(PostHandleAfterChildrenConfig); ok {
   145  		err = phc.PostHandleAfterChildren()
   146  	}
   147  	return
   148  }
   149  
   150  func handleDefault(v reflect.Value, zerop, timeLayerp, def *string, cs map[any]struct{}) error {
   151  	vt := v.Type()
   152  	if def != nil {
   153  		var vp, nv reflect.Value
   154  		if vt.Kind() != reflect.Ptr {
   155  			if v.CanAddr() {
   156  				vp = v.Addr()
   157  			} else {
   158  				vp = reflect.New(vt)
   159  				nv = vp.Elem()
   160  				nv.Set(v)
   161  			}
   162  		} else if v.IsNil() {
   163  			if v.CanSet() {
   164  				nv = reflect.New(vt.Elem())
   165  				vp = nv
   166  			}
   167  		} else {
   168  			vp = v
   169  		}
   170  		if vp != (reflect.Value{}) {
   171  			if vp.CanInterface() {
   172  				vpi := vp.Interface()
   173  				if tp, is := vpi.(*time.Time); is {
   174  					t, err := time.Parse(*timeLayerp, *def)
   175  					if err != nil {
   176  						return err
   177  					}
   178  					*tp = t
   179  					return nil
   180  				}
   181  				if m, is := vpi.(encoding.TextUnmarshaler); is {
   182  					if err := m.UnmarshalText(unsafe.Bytes(*def)); err != nil {
   183  						return err
   184  					}
   185  					if nv != (reflect.Value{}) {
   186  						v.Set(nv)
   187  					}
   188  					return nil
   189  				}
   190  			}
   191  		}
   192  	}
   193  	switch vt.Kind() {
   194  	case reflect.String:
   195  		if v.CanSet() && def != nil {
   196  			if v.IsZero() {
   197  				v.SetString(*def)
   198  			}
   199  		}
   200  	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
   201  		if v.CanSet() && def != nil {
   202  			if vt == reflect.TypeOf(time.Duration(0)) {
   203  				du, err := time.ParseDuration(*def)
   204  				if err != nil {
   205  					return err
   206  				}
   207  				if v.IsZero() {
   208  					v.SetInt(int64(du))
   209  				}
   210  			} else {
   211  				parsed, err := strconv.ParseInt(*def, 0, int(vt.Size())*8)
   212  				if err != nil {
   213  					return err
   214  				}
   215  				if v.IsZero() {
   216  					v.SetInt(parsed)
   217  				}
   218  			}
   219  		}
   220  	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
   221  		if v.CanSet() && def != nil {
   222  			parsed, err := strconv.ParseUint(*def, 0, int(vt.Size())*8)
   223  			if err != nil {
   224  				return err
   225  			}
   226  			if v.IsZero() {
   227  				v.SetUint(parsed)
   228  			}
   229  		}
   230  	case reflect.Float32, reflect.Float64:
   231  		if v.CanSet() && def != nil {
   232  			parsed, err := strconv.ParseFloat(*def, int(vt.Size())*8)
   233  			if err != nil {
   234  				return err
   235  			}
   236  			if v.IsZero() {
   237  				v.SetFloat(parsed)
   238  			}
   239  		}
   240  	case reflect.Complex64, reflect.Complex128:
   241  		if v.CanSet() && def != nil {
   242  			parsed, err := strconv.ParseComplex(*def, int(vt.Size())*8)
   243  			if err != nil {
   244  				return err
   245  			}
   246  			if v.IsZero() {
   247  				v.SetComplex(parsed)
   248  			}
   249  		}
   250  	case reflect.Bool:
   251  		if v.CanSet() && def != nil {
   252  			var zero bool
   253  			parsed, err := strconv.ParseBool(*def)
   254  			if err != nil {
   255  				return err
   256  			}
   257  			if v.Bool() == zero {
   258  				v.SetBool(parsed)
   259  			}
   260  		}
   261  	case reflect.Array, reflect.Struct:
   262  		if def != nil && v.IsZero() {
   263  			if vt == reflect.TypeOf(time.Time{}) {
   264  				if v.CanSet() {
   265  					parsed, err := time.Parse(time.RFC3339Nano, *def)
   266  					if err != nil {
   267  						return err
   268  					}
   269  					v.Set(reflect.ValueOf(parsed))
   270  				}
   271  			} else if *def != "" {
   272  				// noCopy flag represents the pointer using the current array or struct
   273  				var noCopy bool
   274  				var pv reflect.Value
   275  				var pvi any
   276  				if v.CanAddr() {
   277  					// pointer using the current array or struct
   278  					pv = v.Addr()
   279  					noCopy = true
   280  					if pv.CanInterface() {
   281  						pvi = pv.Interface()
   282  					}
   283  				} else if v.CanSet() {
   284  					// new array pointer
   285  					pv = reflect.New(vt)
   286  					pvi = pv.Interface()
   287  				}
   288  				if pvi != nil {
   289  					// parse array use yaml or json
   290  					err := yaml.Unmarshal(unsafe.Bytes(*def), pvi)
   291  					if err != nil {
   292  						err2 := json.Unmarshal(unsafe.Bytes(*def), pvi)
   293  						if err2 != nil {
   294  							return errors.Append(err, err2)
   295  						}
   296  					}
   297  					if !noCopy {
   298  						// use the pointer of the current array, and do not
   299  						// need to set
   300  						v.Set(pv.Elem())
   301  					}
   302  				}
   303  			}
   304  		}
   305  		switch vt.Kind() {
   306  		case reflect.Array:
   307  			// handle array element
   308  			l := v.Len()
   309  			for i := 0; i < l; i++ {
   310  				if err := handleDefault(v.Index(i), nil, nil, nil, cs); err != nil {
   311  					return err
   312  				}
   313  			}
   314  		case reflect.Struct:
   315  			nf := v.NumField()
   316  			for i := 0; i < nf; i++ {
   317  				fv := v.Field(i)
   318  				if !vt.Field(i).IsExported() {
   319  					continue
   320  				}
   321  				tag := vt.Field(i).Tag
   322  				if fdef, has := tag.Lookup("default"); has {
   323  					var fzerop *string
   324  					if fzero, has := tag.Lookup("zero"); has {
   325  						fzerop = &fzero
   326  					}
   327  					var ftimeLayerp *string
   328  					if ftimeLayer, has := tag.Lookup("timeLayer"); has {
   329  						ftimeLayerp = &ftimeLayer
   330  					}
   331  					if err := handleDefault(fv, fzerop, ftimeLayerp, &fdef, cs); err != nil {
   332  						return err
   333  					}
   334  				} else if err := handleDefault(fv, nil, nil, nil, cs); err != nil {
   335  					return err
   336  				}
   337  			}
   338  		}
   339  	case reflect.Slice, reflect.Map:
   340  		kind := vt.Kind()
   341  		if def != nil && v.CanSet() {
   342  			if *def != "" && v.Len() == 0 {
   343  				var pv reflect.Value
   344  				var pvi any
   345  				if v.CanAddr() {
   346  					if pv = v.Addr(); pv.CanInterface() {
   347  						// use current pointer of slice or map
   348  						if !v.IsNil() {
   349  							// map or slice is nil, make it first
   350  							switch kind {
   351  							case reflect.Slice:
   352  								v.Set(reflect.MakeSlice(vt, 0, 0))
   353  							case reflect.Map:
   354  								v.Set(reflect.MakeMap(vt))
   355  							}
   356  						}
   357  						pvi = pv.Interface()
   358  					}
   359  				}
   360  				if pvi == nil {
   361  					// new pointer of slice or map
   362  					pv = reflect.New(vt)
   363  					switch kind {
   364  					case reflect.Slice:
   365  						pv.Elem().Set(reflect.MakeSlice(vt, 0, 0))
   366  					case reflect.Map:
   367  						pv.Elem().Set(reflect.MakeMap(vt))
   368  					}
   369  					pvi = pv.Interface()
   370  				}
   371  				// parse slice or map use yaml or json
   372  				err := yaml.Unmarshal(unsafe.Bytes(*def), pvi)
   373  				if err != nil {
   374  					err2 := json.Unmarshal(unsafe.Bytes(*def), pvi)
   375  					if err2 != nil {
   376  						return errors.Append(err, err2)
   377  					}
   378  				}
   379  				v.Set(pv.Elem())
   380  			}
   381  		}
   382  		switch kind {
   383  		case reflect.Slice:
   384  			// handle slice element
   385  			l := v.Len()
   386  			for i := 0; i < l; i++ {
   387  				if err := handleDefault(v.Index(i), nil, nil, nil, cs); err != nil {
   388  					return err
   389  				}
   390  			}
   391  		case reflect.Map:
   392  			// handle map value
   393  			for iter := v.MapRange(); iter.Next(); {
   394  				if err := handleDefault(iter.Value(), nil, nil, nil, cs); err != nil {
   395  					return err
   396  				}
   397  			}
   398  		}
   399  	case reflect.Ptr:
   400  		if def != nil && v.CanSet() {
   401  			nv := reflect.New(vt.Elem())
   402  			if err := handleDefault(nv.Elem(), zerop, timeLayerp, def, cs); err != nil {
   403  				return err
   404  			}
   405  			if v.CanInterface() {
   406  				// update recursive call set
   407  				if !v.IsNil() {
   408  					delete(cs, v.Interface())
   409  				}
   410  				v.Set(nv)
   411  				cs[v.Interface()] = struct{}{}
   412  			}
   413  		} else if v.IsNil() {
   414  			return nil
   415  		} else {
   416  			if v.CanInterface() {
   417  				// check and update recursive call set
   418  				if _, repeat := cs[v.Interface()]; repeat {
   419  					return nil
   420  				}
   421  				cs[v.Interface()] = struct{}{}
   422  			}
   423  			if err := handleDefault(v.Elem(), zerop, timeLayerp, def, cs); err != nil {
   424  				return err
   425  			}
   426  		}
   427  	}
   428  	return nil
   429  }
   430  
   431  func HandleDefault(c any) error {
   432  	return handleDefault(reflect.ValueOf(c), nil, nil, nil, make(map[interface{}]struct{}))
   433  }
   434  
   435  func doHandlerPtr(pi any, pv reflect.Value, setFn func(v reflect.Value), handleFn func(c any) (nc any, modified bool, err error), cs map[any]struct{}) (err error, repeat bool) {
   436  	pvt := pv.Type()
   437  	nc, mod, err := handleFn(pi)
   438  	if err != nil {
   439  		return err, false
   440  	}
   441  	if mod {
   442  		nct := reflect.TypeOf(nc)
   443  		ncv := reflect.ValueOf(nc)
   444  		if nct == pvt && ncv != pv {
   445  			if pv.CanSet() {
   446  				pv.Set(ncv)
   447  			} else if setFn != nil {
   448  				setFn(ncv)
   449  			}
   450  			delete(cs, pi)
   451  			if _, repeat := cs[nc]; repeat {
   452  				return nil, true
   453  			}
   454  			cs[nc] = struct{}{}
   455  		} else if nct == pvt.Elem() {
   456  			if ve := pv.Elem(); ve.CanSet() {
   457  				ve.Set(ncv)
   458  			}
   459  		}
   460  	}
   461  	return nil, false
   462  }
   463  
   464  func doHandle(v, pv reflect.Value, copied bool, setFn func(v reflect.Value), handleFn func(c any) (nc any, modified bool, err error)) error {
   465  	if pv.CanInterface() {
   466  		nc, mod, err := handleFn(pv.Interface())
   467  		if err != nil {
   468  			return err
   469  		}
   470  		if mod {
   471  			nct := reflect.TypeOf(nc)
   472  			ncv := reflect.ValueOf(nc)
   473  			if v.CanSet() {
   474  				if nct == v.Type() {
   475  					v.Set(ncv)
   476  				} else if nct == pv.Type() && (copied || ncv != pv) {
   477  					v.Set(ncv.Elem())
   478  				}
   479  			} else if setFn != nil {
   480  				if nct == v.Type() {
   481  					setFn(ncv)
   482  				} else if nct == pv.Type() && (copied || ncv != pv) {
   483  					setFn(ncv.Elem())
   484  				}
   485  			}
   486  		}
   487  	}
   488  	return nil
   489  }
   490  
   491  func handleChildren(v reflect.Value, handler handler, cs map[any]struct{}) error {
   492  	vt := v.Type()
   493  	switch v.Kind() {
   494  	case reflect.Slice, reflect.Array:
   495  		ll := v.Len()
   496  		for i := 0; i < ll; i++ {
   497  			if err := handle(v.Index(i), nil, handler, cs); err != nil {
   498  				return err
   499  			}
   500  		}
   501  	case reflect.Map:
   502  		for iter := v.MapRange(); iter.Next(); {
   503  			if err := handle(iter.Value(), func(mv reflect.Value) {
   504  				v.SetMapIndex(iter.Key(), mv)
   505  			}, handler, cs); err != nil {
   506  				return err
   507  			}
   508  		}
   509  	case reflect.Struct:
   510  		nf := v.NumField()
   511  		for i := 0; i < nf; i++ {
   512  			fv := v.Field(i)
   513  			if !vt.Field(i).IsExported() {
   514  				continue
   515  			}
   516  			if err := handle(fv, nil, handler, cs); err != nil {
   517  				return err
   518  			}
   519  		}
   520  	case reflect.Ptr:
   521  		if err := handle(v, nil, handler, cs); err != nil {
   522  			return err
   523  		}
   524  	}
   525  	return nil
   526  }
   527  
   528  func handle(v reflect.Value, setFn func(v reflect.Value), handler handler, cs map[any]struct{}) error {
   529  	vt := v.Type()
   530  	if v.Kind() == reflect.Ptr {
   531  		if v.IsNil() {
   532  			return nil
   533  		}
   534  		if v.CanInterface() {
   535  			c := v.Interface()
   536  			if _, repeat := cs[c]; repeat {
   537  				return nil
   538  			}
   539  			cs[c] = struct{}{}
   540  			if err, repeat := doHandlerPtr(c, v, setFn, handler.handle, cs); err != nil {
   541  				return err
   542  			} else if repeat {
   543  				return nil
   544  			}
   545  		}
   546  		if err := handleChildren(v.Elem(), handler, cs); err != nil {
   547  			return err
   548  		}
   549  		if v.CanInterface() {
   550  			c := v.Interface()
   551  			if err, repeat := doHandlerPtr(c, v, setFn, handler.handleAfterChildren, cs); err != nil {
   552  				return err
   553  			} else if repeat {
   554  				return nil
   555  			}
   556  		}
   557  	} else if handler.canHandle(reflect.NewAt(vt, nil).Interface()) {
   558  		var pv reflect.Value
   559  		var copied bool
   560  		if v.CanAddr() {
   561  			pv = v.Addr()
   562  		} else {
   563  			pv = reflect.New(vt)
   564  			pv.Elem().Set(v)
   565  			copied = true
   566  		}
   567  		if pv.CanInterface() {
   568  			if err := doHandle(v, pv, copied, setFn, handler.handle); err != nil {
   569  				return err
   570  			}
   571  		}
   572  		if err := handleChildren(v, handler, cs); err != nil {
   573  			return err
   574  		}
   575  		if pv.CanInterface() {
   576  			if err := doHandle(v, pv, copied, setFn, handler.handleAfterChildren); err != nil {
   577  				return err
   578  			}
   579  		}
   580  	} else if err := handleChildren(v, handler, cs); err != nil {
   581  		return err
   582  	}
   583  
   584  	return nil
   585  }
   586  
   587  func PreHandle(c any) error {
   588  	return handle(reflect.ValueOf(c), nil, preHandler{}, make(map[interface{}]struct{}))
   589  }
   590  
   591  func PostHandle(c any) error {
   592  	return handle(reflect.ValueOf(c), nil, postHandler{}, make(map[interface{}]struct{}))
   593  }
   594  
   595  //func handle3(handler handler, c any, cs map[any]struct{}) (nc any, modified bool, err error) {
   596  //	var mod bool
   597  //	nc = c
   598  //	// ct: config type
   599  //	ct := reflect.TypeOf(c)
   600  //	// cv: config value
   601  //	cv := reflect.ValueOf(nc)
   602  //	v := cv
   603  //
   604  //	switch ct.Kind() {
   605  //	case reflect.Ptr:
   606  //		if cv.IsNil() {
   607  //			return c, false, nil
   608  //		}
   609  //		v = v.Elem()
   610  //		if _, repeat := cs[nc]; repeat {
   611  //			return
   612  //		}
   613  //	}
   614  //
   615  //	old := nc
   616  //	if nc, mod, err = handler.handle(nc); err != nil {
   617  //		return
   618  //	}
   619  //	modified = modified || mod
   620  //
   621  //	if ct.Kind() == reflect.Ptr && mod {
   622  //		// handler modify config
   623  //		delete(cs, old)
   624  //		cs[nc] = struct{}{}
   625  //	}
   626  //
   627  //	switch v.Kind() {
   628  //	case reflect.Struct:
   629  //		nf := v.NumField()
   630  //		// walk fields and handle filed
   631  //		for i := 0; i < nf; i++ {
   632  //			fv := v.Field(i)
   633  //			if fv.Kind() == reflect.Ptr {
   634  //				if fv.CanInterface() {
   635  //					fi := fv.Interface()
   636  //					if nfi, mod, err := handle3(handler, fi, cs); err != nil {
   637  //						return nc, modified, err
   638  //					} else if mod {
   639  //						fv.Set(reflect.ValueOf(nfi))
   640  //					}
   641  //				}
   642  //				continue
   643  //			}
   644  //			// field not pointer and field has address
   645  //			if fv.CanAddr() {
   646  //				// field has address
   647  //				// fpv: field pointer value
   648  //				fpv := fv.Addr()
   649  //				if fpv.CanInterface() {
   650  //					// fpi: field pointer interface
   651  //					fpi := fpv.Interface()
   652  //					// nfpi: new field pointer interface
   653  //					if nfpi, mod, err := handle3(handler, fpi, cs); err != nil {
   654  //						return nc, modified, err
   655  //					} else if mod {
   656  //						fpv.Set(reflect.ValueOf(nfpi))
   657  //					}
   658  //				}
   659  //				continue
   660  //			}
   661  //			// field not have address
   662  //			if fv.CanInterface() {
   663  //				fpv := reflect.New(fv.Type())
   664  //				fpv.Elem().Set(fv)
   665  //				if fpv.CanInterface() {
   666  //					// mpi: map pointer interface
   667  //					fpi := fpv.Interface()
   668  //					// npmi: new map pointer interface
   669  //					if nfpi, mod, err := handle3(handler, fpi, cs); err != nil {
   670  //						return nc, modified, err
   671  //					} else if mod {
   672  //						fpv = reflect.ValueOf(nfpi)
   673  //					}
   674  //					fv.Set(fpv.Elem())
   675  //				}
   676  //			}
   677  //		}
   678  //
   679  //	case reflect.Map:
   680  //		for iter := v.MapRange(); iter.Next(); {
   681  //			// mv: map value
   682  //			mv := iter.Value()
   683  //			if mv.Kind() == reflect.Ptr {
   684  //				if mv.CanInterface() {
   685  //					// mvi: map value interface
   686  //					mvi := mv.Interface()
   687  //					// nmvi: new map value interface
   688  //					// mod: map value modified
   689  //					if nmvi, mod, err := handle3(handler, mvi, cs); err != nil {
   690  //						return nc, modified, err
   691  //					} else if mod {
   692  //						v.SetMapIndex(iter.Key(), reflect.ValueOf(nmvi))
   693  //					}
   694  //				}
   695  //				continue
   696  //			}
   697  //			if mv.CanAddr() {
   698  //				// mpv: map pointer value
   699  //				mpv := mv.Addr()
   700  //				if mpv.CanInterface() {
   701  //					// mpi: map pointer interface
   702  //					mpi := mpv.Interface()
   703  //					// npmi: new map pointer interface
   704  //					if nmpi, mod, err := handle3(handler, mpi, cs); err != nil {
   705  //						return nc, modified, err
   706  //					} else if mod {
   707  //						mpv.Set(reflect.ValueOf(nmpi))
   708  //					}
   709  //				}
   710  //				continue
   711  //			}
   712  //			if mv.CanInterface() {
   713  //				// mvi: map value interface
   714  //				mpv := reflect.New(mv.Type())
   715  //				mpv.Elem().Set(mv)
   716  //				if mpv.CanInterface() {
   717  //					// mpi: map pointer interface
   718  //					mpi := mpv.Interface()
   719  //					// npmi: new map pointer interface
   720  //					if nmpi, mod, err := handle3(handler, mpi, cs); err != nil {
   721  //						return nc, modified, err
   722  //					} else if mod {
   723  //						mpv = reflect.ValueOf(nmpi)
   724  //					}
   725  //					v.SetMapIndex(iter.Key(), mpv.Elem())
   726  //				}
   727  //			}
   728  //		}
   729  //
   730  //	case reflect.Slice, reflect.Array:
   731  //		ll := v.Len()
   732  //		for i := 0; i < ll; i++ {
   733  //			lv := v.Index(i)
   734  //			if lv.Kind() == reflect.Ptr {
   735  //				if lv.CanInterface() {
   736  //					// lvi: list value interface
   737  //					lvi := lv.Interface()
   738  //					// nlvi: new list value interface
   739  //					// mod: list value modified
   740  //					if nlvi, mod, err := handle3(handler, lvi, cs); err != nil {
   741  //						return nc, modified, err
   742  //					} else if mod {
   743  //						lv.Set(reflect.ValueOf(nlvi))
   744  //					}
   745  //				}
   746  //				continue
   747  //			}
   748  //			if lv.CanAddr() {
   749  //				// lpv: list pointer value
   750  //				lpv := lv.Addr()
   751  //				if lpv.CanInterface() {
   752  //					// lpi: list pointer interface
   753  //					lpi := lpv.Interface()
   754  //					// nlmi: new list pointer interface
   755  //					if nlpi, mod, err := handle3(handler, lpi, cs); err != nil {
   756  //						return nc, modified, err
   757  //					} else if mod {
   758  //						lpv.Set(reflect.ValueOf(nlpi))
   759  //					}
   760  //				}
   761  //				continue
   762  //			}
   763  //			if lv.CanInterface() {
   764  //				lpv := reflect.New(lv.Type())
   765  //				lpv.Elem().Set(lv)
   766  //				if lpv.CanInterface() {
   767  //					// mpi: map pointer interface
   768  //					lpi := lpv.Interface()
   769  //					// npmi: new map pointer interface
   770  //					if nlpi, mod, err := handle3(handler, lpi, cs); err != nil {
   771  //						return nc, modified, err
   772  //					} else if mod {
   773  //						lpv = reflect.ValueOf(nlpi)
   774  //					}
   775  //					lv.Set(lpv.Elem())
   776  //				}
   777  //			}
   778  //		}
   779  //	}
   780  //
   781  //	old = nc
   782  //	if nc, mod, err = handler.handleAfterChildren(nc); err != nil {
   783  //		return
   784  //	}
   785  //	modified = modified || mod
   786  //
   787  //	if ct.Kind() == reflect.Ptr && mod {
   788  //		// handler modify config
   789  //		delete(cs, old)
   790  //		cs[nc] = struct{}{}
   791  //	}
   792  //
   793  //	return
   794  //}
   795  
   796  func Handle(c any) error {
   797  	if err := HandleDefault(c); err != nil {
   798  		return err
   799  	}
   800  	if err := PreHandle(c); err != nil {
   801  		return err
   802  	}
   803  	if err := PostHandle(c); err != nil {
   804  		return err
   805  	}
   806  	return nil
   807  }
   808  
   809  func HandleWith[C any](c C) (C, error) {
   810  	if err := Handle(c); err != nil {
   811  		return c, err
   812  	}
   813  	return c, nil
   814  }
   815  
   816  func MustHandleWith[C any](c C) C {
   817  	return assert.Must(HandleWith(c))
   818  }