mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-06-23 00:35:09 +08:00
82 lines
1.7 KiB
Go
82 lines
1.7 KiB
Go
package 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
|
|
}
|
|
}
|