package plaintext import ( "bytes" "log" "net" "os" "path/filepath" "github.com/Loyalsoldier/geoip/lib" ) var ( defaultOutputDirForTextOut = filepath.Join("./", "output", "text") defaultOutputDirForClashRuleSetClassicalOut = filepath.Join("./", "output", "clash", "classical") defaultOutputDirForClashRuleSetIPCIDROut = filepath.Join("./", "output", "clash", "ipcidr") defaultOutputDirForSurgeRuleSetOut = filepath.Join("./", "output", "surge") ) type text_out struct { Type string Action lib.Action Description string OutputDir string OutputExt string Want []string Exclude []string OnlyIPType lib.IPType AddPrefixInLine string AddSuffixInLine string } func (t *text_out) marshalBytes(entry *lib.Entry) ([]byte, error) { entryCidr, err := entry.MarshalText(lib.GetIgnoreIPType(t.OnlyIPType)) if err != nil { return nil, err } var buf bytes.Buffer switch t.Type { case TypeTextOut: err = t.marshalBytesForTextOut(&buf, entryCidr) case TypeClashRuleSetClassicalOut: err = t.marshalBytesForClashRuleSetClassicalOut(&buf, entryCidr) case TypeClashRuleSetIPCIDROut: err = t.marshalBytesForClashRuleSetIPCIDROut(&buf, entryCidr) case TypeSurgeRuleSetOut: err = t.marshalBytesForSurgeRuleSetOut(&buf, entryCidr) default: return nil, lib.ErrNotSupportedFormat } if err != nil { return nil, err } return buf.Bytes(), nil } func (t *text_out) marshalBytesForTextOut(buf *bytes.Buffer, entryCidr []string) error { for _, cidr := range entryCidr { if t.AddPrefixInLine != "" { buf.WriteString(t.AddPrefixInLine) } buf.WriteString(cidr) if t.AddSuffixInLine != "" { buf.WriteString(t.AddSuffixInLine) } buf.WriteString("\n") } return nil } func (t *text_out) marshalBytesForClashRuleSetClassicalOut(buf *bytes.Buffer, entryCidr []string) error { buf.WriteString("payload:\n") for _, cidr := range entryCidr { ip, _, err := net.ParseCIDR(cidr) if err != nil { return err } if ip.To4() != nil { buf.WriteString(" - IP-CIDR,") } else { buf.WriteString(" - IP-CIDR6,") } buf.WriteString(cidr) buf.WriteString("\n") } return nil } func (t *text_out) marshalBytesForClashRuleSetIPCIDROut(buf *bytes.Buffer, entryCidr []string) error { buf.WriteString("payload:\n") for _, cidr := range entryCidr { buf.WriteString(" - '") buf.WriteString(cidr) buf.WriteString("'\n") } return nil } func (t *text_out) marshalBytesForSurgeRuleSetOut(buf *bytes.Buffer, entryCidr []string) error { for _, cidr := range entryCidr { ip, _, err := net.ParseCIDR(cidr) if err != nil { return err } if ip.To4() != nil { buf.WriteString("IP-CIDR,") } else { buf.WriteString("IP-CIDR6,") } buf.WriteString(cidr) if t.AddSuffixInLine != "" { buf.WriteString(t.AddSuffixInLine) } buf.WriteString("\n") } return nil } func (t *text_out) writeFile(filename string, data []byte) error { if err := os.MkdirAll(t.OutputDir, 0755); err != nil { return err } if err := os.WriteFile(filepath.Join(t.OutputDir, filename), data, 0644); err != nil { return err } log.Printf("✅ [%s] %s --> %s", t.Type, filename, t.OutputDir) return nil }