chore: support KeyReplacer in Structure Decoder

This commit is contained in:
gVisor bot 2022-11-27 13:44:38 +08:00
parent 262797c5a4
commit 4171855c77
3 changed files with 27 additions and 8 deletions

View file

@ -99,7 +99,6 @@ type HysteriaOption struct {
Down string `proxy:"down"` Down string `proxy:"down"`
DownSpeed int `proxy:"down-speed,omitempty"` // compatible with Stash DownSpeed int `proxy:"down-speed,omitempty"` // compatible with Stash
Auth string `proxy:"auth,omitempty"` Auth string `proxy:"auth,omitempty"`
OldAuthString string `proxy:"auth_str,omitempty"`
AuthString string `proxy:"auth-str,omitempty"` AuthString string `proxy:"auth-str,omitempty"`
Obfs string `proxy:"obfs,omitempty"` Obfs string `proxy:"obfs,omitempty"`
SNI string `proxy:"sni,omitempty"` SNI string `proxy:"sni,omitempty"`

View file

@ -9,14 +9,10 @@ import (
C "github.com/Dreamacro/clash/constant" C "github.com/Dreamacro/clash/constant"
) )
func ParseProxy(mapping map[string]any) (C.Proxy, error) { var keyReplacer = strings.NewReplacer("_", "-")
newMapping := make(map[string]any)
for key := range mapping {
newMapping[strings.ReplaceAll(key, "_", "-")] = mapping[key]
}
mapping = newMapping
decoder := structure.NewDecoder(structure.Option{TagName: "proxy", WeaklyTypedInput: true}) func ParseProxy(mapping map[string]any) (C.Proxy, error) {
decoder := structure.NewDecoder(structure.Option{TagName: "proxy", WeaklyTypedInput: true, KeyReplacer: keyReplacer})
proxyType, existType := mapping["type"].(string) proxyType, existType := mapping["type"].(string)
if !existType { if !existType {
return nil, fmt.Errorf("missing type") return nil, fmt.Errorf("missing type")

View file

@ -13,6 +13,7 @@ import (
type Option struct { type Option struct {
TagName string TagName string
WeaklyTypedInput bool WeaklyTypedInput bool
KeyReplacer *strings.Replacer
} }
// Decoder is the core of structure // Decoder is the core of structure
@ -48,7 +49,24 @@ func (d *Decoder) Decode(src map[string]any, dst any) error {
key, omitKey, found := strings.Cut(tag, ",") key, omitKey, found := strings.Cut(tag, ",")
omitempty := found && omitKey == "omitempty" omitempty := found && omitKey == "omitempty"
if d.option.KeyReplacer != nil {
key = d.option.KeyReplacer.Replace(key)
}
value, ok := src[key] value, ok := src[key]
if !ok {
for _strKey := range src {
strKey := _strKey
if d.option.KeyReplacer != nil {
strKey = d.option.KeyReplacer.Replace(strKey)
}
if strings.EqualFold(key, strKey) {
value = src[_strKey]
ok = true
break
}
}
}
if !ok || value == nil { if !ok || value == nil {
if omitempty { if omitempty {
continue continue
@ -346,6 +364,9 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
tagValue = strings.SplitN(tagValue, ",", 2)[0] tagValue = strings.SplitN(tagValue, ",", 2)[0]
if tagValue != "" { if tagValue != "" {
fieldName = tagValue fieldName = tagValue
if d.option.KeyReplacer != nil {
fieldName = d.option.KeyReplacer.Replace(fieldName)
}
} }
rawMapKey := reflect.ValueOf(fieldName) rawMapKey := reflect.ValueOf(fieldName)
@ -359,6 +380,9 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
// Not a string key // Not a string key
continue continue
} }
if d.option.KeyReplacer != nil {
mK = d.option.KeyReplacer.Replace(mK)
}
if strings.EqualFold(mK, fieldName) { if strings.EqualFold(mK, fieldName) {
rawMapKey = dataValKey rawMapKey = dataValKey