diff options
| author | openai-code-agent[bot] <[email protected]> | 2026-04-28 17:44:10 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-04-28 17:44:10 +0000 |
| commit | 60b366c1682009a246056aad7b4a9d30b2a3fd62 (patch) | |
| tree | d4c233ca2baad5395159a5d25b704dda58529ea7 /plugin | |
| parent | 9fc06ad2d090b76132859a61a04a1ff0437cc641 (diff) | |
refactor(plaintext): use functional options for text/json/clash/surge plugins
Co-authored-by: Loyalsoldier <[email protected]>
Diffstat (limited to 'plugin')
| -rw-r--r-- | plugin/plaintext/clash_in.go | 4 | ||||
| -rw-r--r-- | plugin/plaintext/clash_out.go | 4 | ||||
| -rw-r--r-- | plugin/plaintext/common_out.go | 121 | ||||
| -rw-r--r-- | plugin/plaintext/json_in.go | 2 | ||||
| -rw-r--r-- | plugin/plaintext/surge_in.go | 2 | ||||
| -rw-r--r-- | plugin/plaintext/surge_out.go | 2 | ||||
| -rw-r--r-- | plugin/plaintext/text_in.go | 147 | ||||
| -rw-r--r-- | plugin/plaintext/text_out.go | 2 |
8 files changed, 213 insertions, 71 deletions
diff --git a/plugin/plaintext/clash_in.go b/plugin/plaintext/clash_in.go index be77cc62..ae4f9a5b 100644 --- a/plugin/plaintext/clash_in.go +++ b/plugin/plaintext/clash_in.go @@ -21,14 +21,14 @@ const ( func init() { lib.RegisterInputConfigCreator(TypeClashRuleSetClassicalIn, func(action lib.Action, data json.RawMessage) (lib.InputConverter, error) { - return newTextIn(TypeClashRuleSetClassicalIn, DescClashRuleSetClassicalIn, action, data) + return NewTextInFromBytes(TypeClashRuleSetClassicalIn, DescClashRuleSetClassicalIn, action, data) }) lib.RegisterInputConverter(TypeClashRuleSetClassicalIn, &TextIn{ Description: DescClashRuleSetClassicalIn, }) lib.RegisterInputConfigCreator(TypeClashRuleSetIPCIDRIn, func(action lib.Action, data json.RawMessage) (lib.InputConverter, error) { - return newTextIn(TypeClashRuleSetIPCIDRIn, DescClashRuleSetIPCIDRIn, action, data) + return NewTextInFromBytes(TypeClashRuleSetIPCIDRIn, DescClashRuleSetIPCIDRIn, action, data) }) lib.RegisterInputConverter(TypeClashRuleSetIPCIDRIn, &TextIn{ Description: DescClashRuleSetIPCIDRIn, diff --git a/plugin/plaintext/clash_out.go b/plugin/plaintext/clash_out.go index e7a97f1b..36695cd0 100644 --- a/plugin/plaintext/clash_out.go +++ b/plugin/plaintext/clash_out.go @@ -21,14 +21,14 @@ const ( func init() { lib.RegisterOutputConfigCreator(TypeClashRuleSetClassicalOut, func(action lib.Action, data json.RawMessage) (lib.OutputConverter, error) { - return newTextOut(TypeClashRuleSetClassicalOut, DescClashRuleSetClassicalOut, action, data) + return NewTextOutFromBytes(TypeClashRuleSetClassicalOut, DescClashRuleSetClassicalOut, action, data) }) lib.RegisterOutputConverter(TypeClashRuleSetClassicalOut, &TextOut{ Description: DescClashRuleSetClassicalOut, }) lib.RegisterOutputConfigCreator(TypeClashRuleSetIPCIDROut, func(action lib.Action, data json.RawMessage) (lib.OutputConverter, error) { - return newTextOut(TypeClashRuleSetIPCIDROut, DescClashRuleSetIPCIDROut, action, data) + return NewTextOutFromBytes(TypeClashRuleSetIPCIDROut, DescClashRuleSetIPCIDROut, action, data) }) lib.RegisterOutputConverter(TypeClashRuleSetIPCIDROut, &TextOut{ Description: DescClashRuleSetIPCIDROut, diff --git a/plugin/plaintext/common_out.go b/plugin/plaintext/common_out.go index cc7ba41e..eff912f7 100644 --- a/plugin/plaintext/common_out.go +++ b/plugin/plaintext/common_out.go @@ -7,6 +7,7 @@ import ( "net" "os" "path/filepath" + "strings" "github.com/Loyalsoldier/geoip/lib" ) @@ -32,7 +33,83 @@ type TextOut struct { AddSuffixInLine string } -func newTextOut(iType string, iDesc string, action lib.Action, data json.RawMessage) (lib.OutputConverter, error) { +func NewTextOut(iType string, iDesc string, action lib.Action, opts ...lib.OutputOption) lib.OutputConverter { + t := &TextOut{ + Type: iType, + Action: action, + Description: iDesc, + OutputExt: ".txt", + } + + switch iType { + case TypeTextOut: + t.OutputDir = defaultOutputDirForTextOut + case TypeClashRuleSetClassicalOut: + t.OutputDir = defaultOutputDirForClashRuleSetClassicalOut + case TypeClashRuleSetIPCIDROut: + t.OutputDir = defaultOutputDirForClashRuleSetIPCIDROut + case TypeSurgeRuleSetOut: + t.OutputDir = defaultOutputDirForSurgeRuleSetOut + } + + for _, opt := range opts { + if opt != nil { + opt(t) + } + } + + return t +} + +func WithTextOutOutputDir(dir string) lib.OutputOption { + return func(c lib.OutputConverter) { + dir = strings.TrimSpace(dir) + if dir != "" { + c.(*TextOut).OutputDir = dir + } + } +} + +func WithTextOutOutputExt(ext string) lib.OutputOption { + return func(c lib.OutputConverter) { + ext = strings.TrimSpace(ext) + if ext != "" { + c.(*TextOut).OutputExt = ext + } + } +} + +func WithTextOutWantedList(lists []string) lib.OutputOption { + return func(c lib.OutputConverter) { + c.(*TextOut).Want = lists + } +} + +func WithTextOutExcludedList(lists []string) lib.OutputOption { + return func(c lib.OutputConverter) { + c.(*TextOut).Exclude = lists + } +} + +func WithTextOutOnlyIPType(onlyIPType lib.IPType) lib.OutputOption { + return func(c lib.OutputConverter) { + c.(*TextOut).OnlyIPType = onlyIPType + } +} + +func WithTextOutAddPrefixInLine(prefix string) lib.OutputOption { + return func(c lib.OutputConverter) { + c.(*TextOut).AddPrefixInLine = prefix + } +} + +func WithTextOutAddSuffixInLine(suffix string) lib.OutputOption { + return func(c lib.OutputConverter) { + c.(*TextOut).AddSuffixInLine = suffix + } +} + +func NewTextOutFromBytes(iType string, iDesc string, action lib.Action, data []byte) (lib.OutputConverter, error) { var tmp struct { OutputDir string `json:"outputDir"` OutputExt string `json:"outputExtension"` @@ -50,36 +127,18 @@ func newTextOut(iType string, iDesc string, action lib.Action, data json.RawMess } } - if tmp.OutputDir == "" { - switch iType { - case TypeTextOut: - tmp.OutputDir = defaultOutputDirForTextOut - case TypeClashRuleSetClassicalOut: - tmp.OutputDir = defaultOutputDirForClashRuleSetClassicalOut - case TypeClashRuleSetIPCIDROut: - tmp.OutputDir = defaultOutputDirForClashRuleSetIPCIDROut - case TypeSurgeRuleSetOut: - tmp.OutputDir = defaultOutputDirForSurgeRuleSetOut - } - } - - if tmp.OutputExt == "" { - tmp.OutputExt = ".txt" - } - - return &TextOut{ - Type: iType, - Action: action, - Description: iDesc, - OutputDir: tmp.OutputDir, - OutputExt: tmp.OutputExt, - Want: tmp.Want, - Exclude: tmp.Exclude, - OnlyIPType: tmp.OnlyIPType, - - AddPrefixInLine: tmp.AddPrefixInLine, - AddSuffixInLine: tmp.AddSuffixInLine, - }, nil + return NewTextOut( + iType, + iDesc, + action, + WithTextOutOutputDir(tmp.OutputDir), + WithTextOutOutputExt(tmp.OutputExt), + WithTextOutWantedList(tmp.Want), + WithTextOutExcludedList(tmp.Exclude), + WithTextOutOnlyIPType(tmp.OnlyIPType), + WithTextOutAddPrefixInLine(tmp.AddPrefixInLine), + WithTextOutAddSuffixInLine(tmp.AddSuffixInLine), + ), nil } func (t *TextOut) marshalBytes(entry *lib.Entry) ([]byte, error) { diff --git a/plugin/plaintext/json_in.go b/plugin/plaintext/json_in.go index a4643609..5ee355f9 100644 --- a/plugin/plaintext/json_in.go +++ b/plugin/plaintext/json_in.go @@ -13,7 +13,7 @@ const ( func init() { lib.RegisterInputConfigCreator(TypeJSONIn, func(action lib.Action, data json.RawMessage) (lib.InputConverter, error) { - return newTextIn(TypeJSONIn, DescJSONIn, action, data) + return NewTextInFromBytes(TypeJSONIn, DescJSONIn, action, data) }) lib.RegisterInputConverter(TypeJSONIn, &TextIn{ diff --git a/plugin/plaintext/surge_in.go b/plugin/plaintext/surge_in.go index 7621d0a1..e6250559 100644 --- a/plugin/plaintext/surge_in.go +++ b/plugin/plaintext/surge_in.go @@ -18,7 +18,7 @@ const ( func init() { lib.RegisterInputConfigCreator(TypeSurgeRuleSetIn, func(action lib.Action, data json.RawMessage) (lib.InputConverter, error) { - return newTextIn(TypeSurgeRuleSetIn, DescSurgeRuleSetIn, action, data) + return NewTextInFromBytes(TypeSurgeRuleSetIn, DescSurgeRuleSetIn, action, data) }) lib.RegisterInputConverter(TypeSurgeRuleSetIn, &TextIn{ Description: DescSurgeRuleSetIn, diff --git a/plugin/plaintext/surge_out.go b/plugin/plaintext/surge_out.go index 8fe62fb4..78d57ae9 100644 --- a/plugin/plaintext/surge_out.go +++ b/plugin/plaintext/surge_out.go @@ -18,7 +18,7 @@ const ( func init() { lib.RegisterOutputConfigCreator(TypeSurgeRuleSetOut, func(action lib.Action, data json.RawMessage) (lib.OutputConverter, error) { - return newTextOut(TypeSurgeRuleSetOut, DescSurgeRuleSetOut, action, data) + return NewTextOutFromBytes(TypeSurgeRuleSetOut, DescSurgeRuleSetOut, action, data) }) lib.RegisterOutputConverter(TypeSurgeRuleSetOut, &TextOut{ Description: DescSurgeRuleSetOut, diff --git a/plugin/plaintext/text_in.go b/plugin/plaintext/text_in.go index a75b1b12..7a7b9c07 100644 --- a/plugin/plaintext/text_in.go +++ b/plugin/plaintext/text_in.go @@ -3,6 +3,7 @@ package plaintext import ( "encoding/json" "fmt" + "log" "net/http" "os" "path/filepath" @@ -19,14 +20,108 @@ const ( func init() { lib.RegisterInputConfigCreator(TypeTextIn, func(action lib.Action, data json.RawMessage) (lib.InputConverter, error) { - return newTextIn(TypeTextIn, DescTextIn, action, data) + return NewTextInFromBytes(TypeTextIn, DescTextIn, action, data) }) lib.RegisterInputConverter(TypeTextIn, &TextIn{ Description: DescTextIn, }) } -func newTextIn(iType string, iDesc string, action lib.Action, data json.RawMessage) (lib.InputConverter, error) { +func NewTextIn(iType string, iDesc string, action lib.Action, opts ...lib.InputOption) lib.InputConverter { + t := &TextIn{ + Type: iType, + Action: action, + Description: iDesc, + } + + for _, opt := range opts { + if opt != nil { + opt(t) + } + } + + return t +} + +func WithTextInNameAndURI(name, uri string) lib.InputOption { + return func(c lib.InputConverter) { + t := c.(*TextIn) + name = strings.TrimSpace(name) + uri = strings.TrimSpace(uri) + if (name == "" || uri == "") && strings.TrimSpace(t.InputDir) == "" { + log.Fatalf("❌ [type %s | action %s] missing inputDir or name", t.Type, t.Action) + } + t.Name = name + t.URI = uri + } +} + +func WithTextInInputDir(dir string) lib.InputOption { + return func(c lib.InputConverter) { + t := c.(*TextIn) + dir = strings.TrimSpace(dir) + if dir == "" && strings.TrimSpace(t.Name) == "" { + log.Fatalf("❌ [type %s | action %s] missing inputDir or name", t.Type, t.Action) + } + if dir != "" && (strings.TrimSpace(t.Name) != "" || strings.TrimSpace(t.URI) != "" || len(t.IPOrCIDR) > 0) { + log.Fatalf("❌ [type %s | action %s] inputDir is not allowed to be used with name or uri or ipOrCIDR", t.Type, t.Action) + } + t.InputDir = dir + } +} + +func WithTextInIPOrCIDR(ipOrCIDR []string) lib.InputOption { + return func(c lib.InputConverter) { + t := c.(*TextIn) + if t.Type != TypeTextIn && len(ipOrCIDR) > 0 { + log.Fatalf("❌ [type %s | action %s] ipOrCIDR is invalid for this input format", t.Type, t.Action) + } + t.IPOrCIDR = ipOrCIDR + } +} + +func WithTextInWantedList(lists []string) lib.InputOption { + return func(c lib.InputConverter) { + t := c.(*TextIn) + wantList := make(map[string]bool) + for _, want := range lists { + if want = strings.ToUpper(strings.TrimSpace(want)); want != "" { + wantList[want] = true + } + } + t.Want = wantList + } +} + +func WithTextInOnlyIPType(onlyIPType lib.IPType) lib.InputOption { + return func(c lib.InputConverter) { + c.(*TextIn).OnlyIPType = onlyIPType + } +} + +func WithTextInJSONPath(paths []string) lib.InputOption { + return func(c lib.InputConverter) { + t := c.(*TextIn) + if t.Type == TypeJSONIn && len(paths) == 0 { + log.Fatalf("❌ [type %s | action %s] missing jsonPath", t.Type, t.Action) + } + t.JSONPath = paths + } +} + +func WithTextInRemovePrefixesInLine(prefixes []string) lib.InputOption { + return func(c lib.InputConverter) { + c.(*TextIn).RemovePrefixesInLine = prefixes + } +} + +func WithTextInRemoveSuffixesInLine(suffixes []string) lib.InputOption { + return func(c lib.InputConverter) { + c.(*TextIn).RemoveSuffixesInLine = suffixes + } +} + +func NewTextInFromBytes(iType string, iDesc string, action lib.Action, data []byte) (lib.InputConverter, error) { var tmp struct { Name string `json:"name"` URI string `json:"uri"` @@ -50,14 +145,6 @@ func newTextIn(iType string, iDesc string, action lib.Action, data json.RawMessa } } - if iType != TypeTextIn && len(tmp.IPOrCIDR) > 0 { - return nil, fmt.Errorf("❌ [type %s | action %s] ipOrCIDR is invalid for this input format", iType, action) - } - - if iType == TypeJSONIn && len(tmp.JSONPath) == 0 { - return nil, fmt.Errorf("❌ [type %s | action %s] missing jsonPath", iType, action) - } - if tmp.InputDir == "" { if tmp.Name == "" { return nil, fmt.Errorf("❌ [type %s | action %s] missing inputDir or name", iType, action) @@ -68,30 +155,26 @@ func newTextIn(iType string, iDesc string, action lib.Action, data json.RawMessa } else if tmp.Name != "" || tmp.URI != "" || len(tmp.IPOrCIDR) > 0 { return nil, fmt.Errorf("❌ [type %s | action %s] inputDir is not allowed to be used with name or uri or ipOrCIDR", iType, action) } - - // Filter want list - wantList := make(map[string]bool) - for _, want := range tmp.Want { - if want = strings.ToUpper(strings.TrimSpace(want)); want != "" { - wantList[want] = true - } + if iType != TypeTextIn && len(tmp.IPOrCIDR) > 0 { + return nil, fmt.Errorf("❌ [type %s | action %s] ipOrCIDR is invalid for this input format", iType, action) + } + if iType == TypeJSONIn && len(tmp.JSONPath) == 0 { + return nil, fmt.Errorf("❌ [type %s | action %s] missing jsonPath", iType, action) } - return &TextIn{ - Type: iType, - Action: action, - Description: iDesc, - Name: tmp.Name, - URI: tmp.URI, - IPOrCIDR: tmp.IPOrCIDR, - InputDir: tmp.InputDir, - Want: wantList, - OnlyIPType: tmp.OnlyIPType, - - JSONPath: tmp.JSONPath, - RemovePrefixesInLine: tmp.RemovePrefixesInLine, - RemoveSuffixesInLine: tmp.RemoveSuffixesInLine, - }, nil + return NewTextIn( + iType, + iDesc, + action, + WithTextInNameAndURI(tmp.Name, tmp.URI), + WithTextInIPOrCIDR(tmp.IPOrCIDR), + WithTextInInputDir(tmp.InputDir), + WithTextInWantedList(tmp.Want), + WithTextInOnlyIPType(tmp.OnlyIPType), + WithTextInJSONPath(tmp.JSONPath), + WithTextInRemovePrefixesInLine(tmp.RemovePrefixesInLine), + WithTextInRemoveSuffixesInLine(tmp.RemoveSuffixesInLine), + ), nil } func (t *TextIn) GetType() string { diff --git a/plugin/plaintext/text_out.go b/plugin/plaintext/text_out.go index 06f4df63..a949e07f 100644 --- a/plugin/plaintext/text_out.go +++ b/plugin/plaintext/text_out.go @@ -16,7 +16,7 @@ const ( func init() { lib.RegisterOutputConfigCreator(TypeTextOut, func(action lib.Action, data json.RawMessage) (lib.OutputConverter, error) { - return newTextOut(TypeTextOut, DescTextOut, action, data) + return NewTextOutFromBytes(TypeTextOut, DescTextOut, action, data) }) lib.RegisterOutputConverter(TypeTextOut, &TextOut{ Description: DescTextOut, |
