add tests

This commit is contained in:
2025-06-12 19:33:14 +10:00
parent 69deed91df
commit c1012750ff
24 changed files with 1830 additions and 440 deletions

View File

@ -28,16 +28,12 @@ func (p *AnytlsParser) GetType() string {
func (p *AnytlsParser) Parse(proxy string) (P.Proxy, error) {
if !hasPrefix(proxy, p.GetPrefixes()) {
return P.Proxy{}, &ParseError{Type: ErrInvalidPrefix, Raw: proxy}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidPrefix, proxy)
}
link, err := url.Parse(proxy)
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "url parse error",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, err.Error())
}
username := link.User.Username()
@ -49,26 +45,15 @@ func (p *AnytlsParser) Parse(proxy string) (P.Proxy, error) {
query := link.Query()
server := link.Hostname()
if server == "" {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "missing server host",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, "missing server host")
}
portStr := link.Port()
if portStr == "" {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "missing server port",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, "missing server port")
}
port, err := ParsePort(portStr)
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidPort,
Raw: portStr,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidPort, err.Error())
}
insecure, sni := query.Get("insecure"), query.Get("sni")
insecureBool := insecure == "1"

View File

@ -6,9 +6,7 @@ import (
"strconv"
"strings"
"github.com/bestnite/sub2clash/logger"
P "github.com/bestnite/sub2clash/model/proxy"
"go.uber.org/zap"
)
func hasPrefix(proxy string, prefixes []string) bool {
@ -65,7 +63,7 @@ func DecodeBase64(s string) (string, error) {
return string(decodeStr), nil
}
func ParseProxies(proxies ...string) []P.Proxy {
func ParseProxies(proxies ...string) ([]P.Proxy, error) {
var result []P.Proxy
for _, proxy := range proxies {
if proxy != "" {
@ -73,15 +71,11 @@ func ParseProxies(proxies ...string) []P.Proxy {
var err error
proxyItem, err = ParseProxyWithRegistry(proxy)
if err == nil {
result = append(result, proxyItem)
} else {
logger.Logger.Debug(
"parse proxy failed", zap.String("proxy", proxy), zap.Error(err),
)
if err != nil {
return nil, err
}
result = append(result, proxyItem)
}
}
return result
return result, nil
}

View File

@ -1,11 +1,5 @@
package parser
type ParseError struct {
Type ParseErrorType
Message string
Raw string
}
type ParseErrorType string
const (
@ -16,9 +10,6 @@ const (
ErrInvalidBase64 ParseErrorType = "invalid base64"
)
func (e *ParseError) Error() string {
if e.Message != "" {
return string(e.Type) + ": " + e.Message + " \"" + e.Raw + "\""
}
return string(e.Type)
func (e ParseErrorType) Error() string {
return string(e)
}

View File

@ -29,42 +29,26 @@ func (p *HysteriaParser) GetType() string {
func (p *HysteriaParser) Parse(proxy string) (P.Proxy, error) {
if !hasPrefix(proxy, p.GetPrefixes()) {
return P.Proxy{}, &ParseError{Type: ErrInvalidPrefix, Raw: proxy}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidPrefix, proxy)
}
link, err := url.Parse(proxy)
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "url parse error",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, err.Error())
}
server := link.Hostname()
if server == "" {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "missing server host",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, "missing server host")
}
portStr := link.Port()
if portStr == "" {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "missing server port",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, "missing server port")
}
port, err := ParsePort(portStr)
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidPort,
Message: err.Error(),
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidPort, err.Error())
}
query := link.Query()

View File

@ -28,16 +28,12 @@ func (p *Hysteria2Parser) GetType() string {
func (p *Hysteria2Parser) Parse(proxy string) (P.Proxy, error) {
if !hasPrefix(proxy, p.GetPrefixes()) {
return P.Proxy{}, &ParseError{Type: ErrInvalidPrefix, Raw: proxy}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidPrefix, proxy)
}
link, err := url.Parse(proxy)
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "url parse error",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, err.Error())
}
username := link.User.Username()
@ -49,26 +45,15 @@ func (p *Hysteria2Parser) Parse(proxy string) (P.Proxy, error) {
query := link.Query()
server := link.Hostname()
if server == "" {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "missing server host",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, "missing server host")
}
portStr := link.Port()
if portStr == "" {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "missing server port",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, "missing server port")
}
port, err := ParsePort(portStr)
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidPort,
Raw: portStr,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidPort, err.Error())
}
obfs, obfsPassword, insecure, sni := query.Get("obfs"), query.Get("obfs-password"), query.Get("insecure"), query.Get("sni")
insecureBool := insecure == "1"

View File

@ -1,6 +1,7 @@
package parser
import (
"fmt"
"strings"
"sync"
@ -66,7 +67,7 @@ func GetAllPrefixes() []string {
func ParseProxyWithRegistry(proxy string) (P.Proxy, error) {
proxy = strings.TrimSpace(proxy)
if proxy == "" {
return P.Proxy{}, &ParseError{Type: ErrInvalidStruct, Raw: proxy, Message: "empty proxy string"}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, "empty proxy string")
}
for prefix, parser := range registry.parsers {
@ -75,5 +76,5 @@ func ParseProxyWithRegistry(proxy string) (P.Proxy, error) {
}
}
return P.Proxy{}, &ParseError{Type: ErrInvalidPrefix, Raw: proxy, Message: "unsupported protocol"}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidPrefix, "unsupported protocol")
}

View File

@ -32,7 +32,7 @@ func (p *ShadowsocksParser) GetType() string {
// Parse 解析Shadowsocks代理
func (p *ShadowsocksParser) Parse(proxy string) (P.Proxy, error) {
if !hasPrefix(proxy, p.GetPrefixes()) {
return P.Proxy{}, &ParseError{Type: ErrInvalidPrefix, Raw: proxy}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidPrefix, proxy)
}
if !strings.Contains(proxy, "@") {
@ -45,11 +45,7 @@ func (p *ShadowsocksParser) Parse(proxy string) (P.Proxy, error) {
}
d, err := DecodeBase64(s[0])
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "url parse error",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, err.Error())
}
if len(s) == 2 {
proxy = "ss://" + d + "#" + s[1]
@ -59,36 +55,21 @@ func (p *ShadowsocksParser) Parse(proxy string) (P.Proxy, error) {
}
link, err := url.Parse(proxy)
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "url parse error",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, err.Error())
}
server := link.Hostname()
if server == "" {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "missing server host",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, "missing server host")
}
portStr := link.Port()
if portStr == "" {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "missing server port",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, "missing server port")
}
port, err := ParsePort(portStr)
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, err.Error())
}
method := link.User.Username()
@ -109,11 +90,7 @@ func (p *ShadowsocksParser) Parse(proxy string) (P.Proxy, error) {
if password != "" && isLikelyBase64(password) {
password, err = DecodeBase64(password)
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "password decode error",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, err.Error())
}
}

View File

@ -1,6 +1,7 @@
package parser
import (
"fmt"
"net/url"
"strconv"
"strings"
@ -28,7 +29,7 @@ func (p *ShadowsocksRParser) GetType() string {
func (p *ShadowsocksRParser) Parse(proxy string) (P.Proxy, error) {
if !hasPrefix(proxy, p.GetPrefixes()) {
return P.Proxy{}, &ParseError{Type: ErrInvalidPrefix, Raw: proxy}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidPrefix, proxy)
}
for _, prefix := range p.GetPrefixes() {
@ -40,32 +41,27 @@ func (p *ShadowsocksRParser) Parse(proxy string) (P.Proxy, error) {
proxy, err := DecodeBase64(proxy)
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidBase64,
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidBase64, err.Error())
}
serverInfoAndParams := strings.SplitN(proxy, "/?", 2)
parts := strings.Split(serverInfoAndParams[0], ":")
if len(serverInfoAndParams) != 2 {
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, proxy)
}
parts := SplitNRight(serverInfoAndParams[0], ":", 6)
if len(parts) < 6 {
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, proxy)
}
server := parts[0]
protocol := parts[2]
method := parts[3]
obfs := parts[4]
password, err := DecodeBase64(parts[5])
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Raw: proxy,
Message: err.Error(),
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, err.Error())
}
port, err := ParsePort(parts[1])
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidPort,
Message: err.Error(),
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidPort, err.Error())
}
var obfsParam string
@ -74,11 +70,7 @@ func (p *ShadowsocksRParser) Parse(proxy string) (P.Proxy, error) {
if len(serverInfoAndParams) == 2 {
params, err := url.ParseQuery(serverInfoAndParams[1])
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrCannotParseParams,
Raw: proxy,
Message: err.Error(),
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrCannotParseParams, err.Error())
}
if params.Get("obfsparam") != "" {
obfsParam, err = DecodeBase64(params.Get("obfsparam"))
@ -92,11 +84,7 @@ func (p *ShadowsocksRParser) Parse(proxy string) (P.Proxy, error) {
remarks = server + ":" + strconv.Itoa(port)
}
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Raw: proxy,
Message: err.Error(),
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, err.Error())
}
}
@ -121,3 +109,26 @@ func (p *ShadowsocksRParser) Parse(proxy string) (P.Proxy, error) {
func init() {
RegisterParser(&ShadowsocksRParser{})
}
func SplitNRight(s, sep string, n int) []string {
if n <= 0 {
return nil
}
if n == 1 {
return []string{s}
}
parts := strings.Split(s, sep)
if len(parts) <= n {
return parts
}
result := make([]string, n)
for i, j := len(parts)-1, 0; i >= 0; i, j = i-1, j+1 {
if j < n-1 {
result[n-j-1] = parts[len(parts)-j-1]
} else {
result[0] = strings.Join(parts[:i+1], sep)
break
}
}
return result
}

View File

@ -27,39 +27,24 @@ func (p *SocksParser) GetType() string {
func (p *SocksParser) Parse(proxy string) (P.Proxy, error) {
if !hasPrefix(proxy, p.GetPrefixes()) {
return P.Proxy{}, &ParseError{Type: ErrInvalidPrefix, Raw: proxy}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidPrefix, proxy)
}
link, err := url.Parse(proxy)
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "url parse error",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, err.Error())
}
server := link.Hostname()
if server == "" {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "missing server host",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, "missing server host")
}
portStr := link.Port()
if portStr == "" {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "missing server port",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, "missing server port")
}
port, err := ParsePort(portStr)
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidPort,
Raw: portStr,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidPort, err.Error())
}
remarks := link.Fragment
@ -86,6 +71,8 @@ func (p *SocksParser) Parse(proxy string) (P.Proxy, error) {
}
}
tls, udp := link.Query().Get("tls"), link.Query().Get("udp")
return P.Proxy{
Type: p.GetType(),
Name: remarks,
@ -94,6 +81,8 @@ func (p *SocksParser) Parse(proxy string) (P.Proxy, error) {
Port: port,
UserName: username,
Password: password,
TLS: tls == "true",
UDP: udp == "true",
},
}, nil
}

View File

@ -28,43 +28,27 @@ func (p *TrojanParser) GetType() string {
func (p *TrojanParser) Parse(proxy string) (P.Proxy, error) {
if !hasPrefix(proxy, p.GetPrefixes()) {
return P.Proxy{}, &ParseError{Type: ErrInvalidPrefix, Raw: proxy}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidPrefix, proxy)
}
link, err := url.Parse(proxy)
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "url parse error",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, err.Error())
}
password := link.User.Username()
server := link.Hostname()
if server == "" {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "missing server host",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, "missing server host")
}
portStr := link.Port()
if portStr == "" {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "missing server port",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, "missing server port")
}
port, err := ParsePort(portStr)
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidPort,
Message: err.Error(),
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidPort, err.Error())
}
remarks := link.Fragment
@ -74,7 +58,7 @@ func (p *TrojanParser) Parse(proxy string) (P.Proxy, error) {
remarks = strings.TrimSpace(remarks)
query := link.Query()
network, security, alpnStr, sni, pbk, sid, fp, path, host, serviceName := query.Get("type"), query.Get("security"), query.Get("alpn"), query.Get("sni"), query.Get("pbk"), query.Get("sid"), query.Get("fp"), query.Get("path"), query.Get("host"), query.Get("serviceName")
network, security, alpnStr, sni, pbk, sid, fp, path, host, serviceName, udp := query.Get("type"), query.Get("security"), query.Get("alpn"), query.Get("sni"), query.Get("pbk"), query.Get("sid"), query.Get("fp"), query.Get("path"), query.Get("host"), query.Get("serviceName"), query.Get("udp")
var alpn []string
if strings.Contains(alpnStr, ",") {
@ -88,6 +72,7 @@ func (p *TrojanParser) Parse(proxy string) (P.Proxy, error) {
Port: port,
Password: password,
Network: network,
UDP: udp == "true",
}
if security == "xtls" || security == "tls" {

View File

@ -28,39 +28,27 @@ func (p *VlessParser) GetType() string {
func (p *VlessParser) Parse(proxy string) (P.Proxy, error) {
if !hasPrefix(proxy, p.GetPrefixes()) {
return P.Proxy{}, &ParseError{Type: ErrInvalidPrefix, Raw: proxy}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidPrefix, proxy)
}
link, err := url.Parse(proxy)
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "url parse error",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, err.Error())
}
server := link.Hostname()
if server == "" {
return P.Proxy{}, &ParseError{
Type: ErrInvalidStruct,
Message: "missing server host",
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, "missing server host")
}
portStr := link.Port()
port, err := ParsePort(portStr)
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidPort,
Message: err.Error(),
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidPort, err.Error())
}
query := link.Query()
uuid := link.User.Username()
flow, security, alpnStr, sni, insecure, fp, pbk, sid, path, host, serviceName, _type := query.Get("flow"), query.Get("security"), query.Get("alpn"), query.Get("sni"), query.Get("allowInsecure"), query.Get("fp"), query.Get("pbk"), query.Get("sid"), query.Get("path"), query.Get("host"), query.Get("serviceName"), query.Get("type")
flow, security, alpnStr, sni, insecure, fp, pbk, sid, path, host, serviceName, _type, udp := query.Get("flow"), query.Get("security"), query.Get("alpn"), query.Get("sni"), query.Get("allowInsecure"), query.Get("fp"), query.Get("pbk"), query.Get("sid"), query.Get("path"), query.Get("host"), query.Get("serviceName"), query.Get("type"), query.Get("udp")
insecureBool := insecure == "1"
var alpn []string
@ -80,13 +68,15 @@ func (p *VlessParser) Parse(proxy string) (P.Proxy, error) {
Port: port,
UUID: uuid,
Flow: flow,
UDP: udp == "true",
}
if security == "tls" {
result.TLS = true
result.ALPN = alpn
result.SkipCertVerify = insecureBool
result.ClientFingerprint = fp
result.Fingerprint = fp
result.ServerName = sni
}
if security == "reality" {
@ -96,7 +86,7 @@ func (p *VlessParser) Parse(proxy string) (P.Proxy, error) {
PublicKey: pbk,
ShortID: sid,
}
result.ClientFingerprint = fp
result.Fingerprint = fp
}
if _type == "ws" {
@ -125,11 +115,7 @@ func (p *VlessParser) Parse(proxy string) (P.Proxy, error) {
hosts, err := url.QueryUnescape(host)
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrCannotParseParams,
Raw: proxy,
Message: err.Error(),
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrCannotParseParams, err.Error())
}
result.Network = "http"
if hosts != "" {

View File

@ -2,6 +2,7 @@ package parser
import (
"encoding/json"
"fmt"
"net/url"
"strconv"
"strings"
@ -47,7 +48,7 @@ func (p *VmessParser) GetType() string {
func (p *VmessParser) Parse(proxy string) (P.Proxy, error) {
if !hasPrefix(proxy, p.GetPrefixes()) {
return P.Proxy{}, &ParseError{Type: ErrInvalidPrefix, Raw: proxy}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidPrefix, proxy)
}
for _, prefix := range p.GetPrefixes() {
@ -58,13 +59,13 @@ func (p *VmessParser) Parse(proxy string) (P.Proxy, error) {
}
base64, err := DecodeBase64(proxy)
if err != nil {
return P.Proxy{}, &ParseError{Type: ErrInvalidBase64, Raw: proxy, Message: err.Error()}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidBase64, err.Error())
}
var vmess VmessJson
err = json.Unmarshal([]byte(base64), &vmess)
if err != nil {
return P.Proxy{}, &ParseError{Type: ErrInvalidStruct, Raw: proxy, Message: err.Error()}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, err.Error())
}
var port int
@ -72,11 +73,7 @@ func (p *VmessParser) Parse(proxy string) (P.Proxy, error) {
case string:
port, err = ParsePort(vmess.Port.(string))
if err != nil {
return P.Proxy{}, &ParseError{
Type: ErrInvalidPort,
Message: err.Error(),
Raw: proxy,
}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidPort, err.Error())
}
case float64:
port = int(vmess.Port.(float64))
@ -87,7 +84,7 @@ func (p *VmessParser) Parse(proxy string) (P.Proxy, error) {
case string:
aid, err = strconv.Atoi(vmess.Aid.(string))
if err != nil {
return P.Proxy{}, &ParseError{Type: ErrInvalidStruct, Raw: proxy, Message: err.Error()}
return P.Proxy{}, fmt.Errorf("%w: %s", ErrInvalidStruct, err.Error())
}
case float64:
aid = int(vmess.Aid.(float64))