package parser import ( "bufio" "io" "net/netip" "strings" "git.maze.io/maze/styx/internal/sliceutil" ) func init() { RegisterDomainsParser(hostsDomainsParser{}) RegisterNetworksParser(hostsNetworksParser{}) } type hostsDomainsParser struct{} func (hostsDomainsParser) CanHandle(line string) bool { part := strings.Fields(line) return len(part) >= 2 && isIP(part[0]) } func (hostsDomainsParser) ParseDomains(r io.Reader) (domains []string, ignored int, err error) { scanner := bufio.NewScanner(r) for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) if isComment(line) { continue } part := strings.Fields(line) if len(part) >= 2 && isIP(part[0]) { domains = append(domains, part[1:]...) continue } ignored++ } if err = scanner.Err(); err != nil { return } return sliceutil.Unique(domains), ignored, nil } type hostsNetworksParser struct{} func (hostsNetworksParser) CanHandle(line string) bool { part := strings.Fields(line) return len(part) >= 2 && isIP(part[0]) } func (hostsNetworksParser) ParseNetworks(r io.Reader) (prefixes []netip.Prefix, ignored int, err error) { scanner := bufio.NewScanner(r) for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) if isComment(line) { continue } part := strings.Fields(line) if len(part) >= 2 && isIP(part[0]) { if addr, err := netip.ParseAddr(part[0]); err == nil && !addr.IsUnspecified() && addr.IsValid() { prefixes = append(prefixes, addrToPrefix(addr)) } continue } ignored++ } if err = scanner.Err(); err != nil { return } return sliceutil.Unique(prefixes), ignored, nil }