chore: unified parse mixed string and array

This commit is contained in:
Skyxim 2023-03-12 12:08:16 +08:00
parent 17fea4b459
commit 4b1e00d3aa
3 changed files with 47 additions and 37 deletions

View File

@ -1,5 +1,11 @@
package utils package utils
import (
"errors"
"fmt"
"reflect"
)
func Filter[T comparable](tSlice []T, filter func(t T) bool) []T { func Filter[T comparable](tSlice []T, filter func(t T) bool) []T {
result := make([]T, 0) result := make([]T, 0)
for _, t := range tSlice { for _, t := range tSlice {
@ -9,3 +15,20 @@ func Filter[T comparable](tSlice []T, filter func(t T) bool) []T {
} }
return result return result
} }
func ToStringSlice(value any) ([]string, error) {
strArr := make([]string, 0)
switch reflect.TypeOf(value).Kind() {
case reflect.Slice, reflect.Array:
origin := reflect.ValueOf(value)
for i := 0; i < origin.Len(); i++ {
item := fmt.Sprintf("%v", origin.Index(i))
strArr = append(strArr, item)
}
case reflect.String:
strArr = append(strArr, fmt.Sprintf("%v", value))
default:
return nil, errors.New("value format error, must be string or array")
}
return strArr, nil
}

View File

@ -2,11 +2,11 @@ package resolver
import ( import (
"errors" "errors"
"fmt"
"math/rand" "math/rand"
"net/netip" "net/netip"
"reflect"
"strings" "strings"
"github.com/Dreamacro/clash/common/utils"
) )
type HostValue struct { type HostValue struct {
@ -19,27 +19,27 @@ func NewHostValue(value any) (HostValue, error) {
isDomain := true isDomain := true
ips := make([]netip.Addr, 0) ips := make([]netip.Addr, 0)
domain := "" domain := ""
switch reflect.TypeOf(value).Kind() { if valueArr, err := utils.ToStringSlice(value); err != nil {
case reflect.Slice, reflect.Array: return HostValue{}, err
isDomain = false } else {
origin := reflect.ValueOf(value) if len(valueArr) > 1 {
for i := 0; i < origin.Len(); i++ { isDomain=false
if ip, err := netip.ParseAddr(fmt.Sprintf("%v", origin.Index(i))); err == nil { for _, str := range valueArr {
if ip, err := netip.ParseAddr(str); err == nil {
ips = append(ips, ip)
} else {
return HostValue{}, err
}
}
} else if len(valueArr) == 1 {
host := valueArr[0]
if ip, err := netip.ParseAddr(host); err == nil {
ips = append(ips, ip) ips = append(ips, ip)
isDomain = false
} else { } else {
return HostValue{}, err domain = host
} }
} }
case reflect.String:
host := fmt.Sprintf("%v", value)
if ip, err := netip.ParseAddr(host); err == nil {
ips = append(ips, ip)
isDomain = false
} else {
domain = host
}
default:
return HostValue{}, errors.New("value format error, must be string or array")
} }
if isDomain { if isDomain {
return NewHostValueByDomain(domain) return NewHostValueByDomain(domain)

View File

@ -9,7 +9,6 @@ import (
"net/netip" "net/netip"
"net/url" "net/url"
"os" "os"
"reflect"
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
@ -852,7 +851,7 @@ func parseHosts(cfg *RawConfig) (*trie.DomainTrie[resolver.HostValue], error) {
} }
} }
} }
anyValue=ips anyValue = ips
} }
} }
value, err := resolver.NewHostValue(anyValue) value, err := resolver.NewHostValue(anyValue)
@ -988,24 +987,12 @@ func parseNameServerPolicy(nsPolicy map[string]any, preferH3 bool) (map[string][
policy := map[string][]dns.NameServer{} policy := map[string][]dns.NameServer{}
for domain, server := range nsPolicy { for domain, server := range nsPolicy {
var (
nameservers []dns.NameServer
err error
)
switch reflect.TypeOf(server).Kind() { servers, err := utils.ToStringSlice(server)
case reflect.Slice, reflect.Array: if err != nil {
origin := reflect.ValueOf(server) return nil, err
servers := make([]string, 0)
for i := 0; i < origin.Len(); i++ {
servers = append(servers, fmt.Sprintf("%v", origin.Index(i)))
}
nameservers, err = parseNameServer(servers, preferH3)
case reflect.String:
nameservers, err = parseNameServer([]string{fmt.Sprintf("%v", server)}, preferH3)
default:
return nil, errors.New("server format error, must be string or array")
} }
nameservers, err := parseNameServer(servers, preferH3)
if err != nil { if err != nil {
return nil, err return nil, err
} }