Files
Rogee 7fcabe0225
Some checks failed
CI/CD Pipeline / Test (push) Failing after 22m19s
CI/CD Pipeline / Security Scan (push) Failing after 5m57s
CI/CD Pipeline / Build (amd64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (amd64, linux) (push) Has been skipped
CI/CD Pipeline / Build (amd64, windows) (push) Has been skipped
CI/CD Pipeline / Build (arm64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (arm64, linux) (push) Has been skipped
CI/CD Pipeline / Build Docker Image (push) Has been skipped
CI/CD Pipeline / Create Release (push) Has been skipped
first commit
2025-09-28 10:05:07 +08:00

107 lines
2.6 KiB
Go

package generator
import (
"fmt"
"net/url"
"strconv"
"strings"
)
// GroupDefinition captures parsed custom proxy group metadata.
type GroupDefinition struct {
Name string
Type string
Proxies []string
UseProviders []string
URL string
Interval *int
Timeout *int
Tolerance *int
Extras map[string]string
}
// ParseGroupDefinition converts a custom group definition string into a GroupDefinition.
func ParseGroupDefinition(definition string) (*GroupDefinition, error) {
values, err := url.ParseQuery(definition)
if err != nil {
return nil, fmt.Errorf("invalid group definition: %v", err)
}
name := strings.TrimSpace(values.Get("name"))
if name == "" {
return nil, fmt.Errorf("custom group missing name")
}
typeVal := strings.TrimSpace(values.Get("type"))
if typeVal == "" {
typeVal = "select"
}
group := &GroupDefinition{
Name: name,
Type: typeVal,
Extras: make(map[string]string),
}
if proxyStr := strings.TrimSpace(values.Get("proxies")); proxyStr != "" {
parts := strings.Split(proxyStr, ",")
for _, entry := range parts {
entry = strings.TrimSpace(entry)
if entry != "" {
group.Proxies = append(group.Proxies, entry)
}
}
}
if useStr := strings.TrimSpace(values.Get("use")); useStr != "" {
parts := strings.Split(useStr, ",")
for _, entry := range parts {
entry = strings.TrimSpace(entry)
if entry != "" {
group.UseProviders = append(group.UseProviders, entry)
}
}
}
if raw := strings.TrimSpace(values.Get("url")); raw != "" {
group.URL = raw
}
if raw := strings.TrimSpace(values.Get("interval")); raw != "" {
if n, err := strconv.Atoi(raw); err == nil && n >= 0 {
group.Interval = &n
} else {
return nil, fmt.Errorf("invalid interval for group %s: %v", name, err)
}
}
if raw := strings.TrimSpace(values.Get("timeout")); raw != "" {
if n, err := strconv.Atoi(raw); err == nil && n >= 0 {
group.Timeout = &n
} else {
return nil, fmt.Errorf("invalid timeout for group %s: %v", name, err)
}
}
if raw := strings.TrimSpace(values.Get("tolerance")); raw != "" {
if n, err := strconv.Atoi(raw); err == nil && n >= 0 {
group.Tolerance = &n
} else {
return nil, fmt.Errorf("invalid tolerance for group %s: %v", name, err)
}
}
for key, vals := range values {
if key == "name" || key == "type" || key == "proxies" || key == "use" || key == "url" || key == "interval" || key == "timeout" || key == "tolerance" {
continue
}
if len(vals) == 0 {
continue
}
value := strings.TrimSpace(vals[len(vals)-1])
if value == "" {
continue
}
group.Extras[strings.ReplaceAll(key, "_", "-")] = value
}
return group, nil
}