Something went wrong. Try again.
sloproxy
Something went wrong. Try again.
1.8 kB · 81 lines
Go
at main
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182package config
import ( "reflect"
"gopkg.in/yaml.v3")
var yamlNodeType = reflect.TypeOf(yaml.Node{})
// CloneForRuntime returns an independent in-memory snapshot of the full config.func (cfg *Config) CloneForRuntime() *Config { if cfg == nil { return nil } cloned := cloneRuntimeValue(reflect.ValueOf(cfg)) return cloned.Interface().(*Config)}
func cloneRuntimeValue(v reflect.Value) reflect.Value { if !v.IsValid() { return v }
if v.Type() == yamlNodeType { node := v.Interface().(yaml.Node) return reflect.ValueOf(*deepCopyNode(&node)) }
switch v.Kind() { case reflect.Pointer: if v.IsNil() { return reflect.Zero(v.Type()) } out := reflect.New(v.Type().Elem()) out.Elem().Set(cloneRuntimeValue(v.Elem())) return out case reflect.Interface: if v.IsNil() { return reflect.Zero(v.Type()) } return cloneRuntimeValue(v.Elem()) case reflect.Struct: out := reflect.New(v.Type()).Elem() for i := 0; i < v.NumField(); i++ { dst := out.Field(i) if !dst.CanSet() { return v } dst.Set(cloneRuntimeValue(v.Field(i))) } return out case reflect.Slice: if v.IsNil() { return reflect.Zero(v.Type()) } out := reflect.MakeSlice(v.Type(), v.Len(), v.Len()) for i := 0; i < v.Len(); i++ { out.Index(i).Set(cloneRuntimeValue(v.Index(i))) } return out case reflect.Array: out := reflect.New(v.Type()).Elem() for i := 0; i < v.Len(); i++ { out.Index(i).Set(cloneRuntimeValue(v.Index(i))) } return out case reflect.Map: if v.IsNil() { return reflect.Zero(v.Type()) } out := reflect.MakeMapWithSize(v.Type(), v.Len()) iter := v.MapRange() for iter.Next() { out.SetMapIndex(cloneRuntimeValue(iter.Key()), cloneRuntimeValue(iter.Value())) } return out default: return v }}