diff --git a/src/plugin/validate/main.go b/src/plugin/validate/main.go index 5b47ddf..1cfafb3 100644 --- a/src/plugin/validate/main.go +++ b/src/plugin/validate/main.go @@ -2,7 +2,6 @@ package validate import ( "bufio" - "embed" "encoding/csv" "encoding/json" "fmt" @@ -11,14 +10,12 @@ import ( "strings" "github.com/realsunyz/geofeed-tools/plugin/color" + "github.com/realsunyz/geofeed-tools/plugin/isocode" ) -//go:embed data/*.json -var dataFS embed.FS - const ( - countryFile = "data/iso3166-1.json" - subdivisionFile = "data/iso3166-2.json" + countryFile = "iso3166-1.json" + subdivisionFile = "iso3166-2.json" ) type Country struct { @@ -35,7 +32,7 @@ var countries []Country var subdivisions SubdivisionMap func readJSON(filename string, v interface{}) error { - data, err := dataFS.ReadFile(filename) + data, err := isocode.DataFS.ReadFile(filename) if err != nil { return err } @@ -151,7 +148,7 @@ func Execute(filePath string) { scanner, file, err := readCSV(filePath) if err != nil { - fmt.Printf("Failed to %v\n", err) + fmt.Printf("Failed to open geofeed file: %v\n", err) return } defer func() { diff --git a/src/validator.go b/src/validator.go deleted file mode 100644 index d555d4e..0000000 --- a/src/validator.go +++ /dev/null @@ -1,164 +0,0 @@ -// validator.go -// author: Yanzheng SUN (realSunyz) - -package main - -import ( - "bufio" - "embed" - "encoding/csv" - "encoding/json" - "fmt" - "net" - "os" - "strings" -) - -const ( - Reset = "\033[0m" - Red = "\033[31m" - Green = "\033[32m" - Yellow = "\033[33m" - Magenta = "\033[35m" - Cyan = "\033[36m" -) - -type Country struct { - Name string `json:"name"` - Code string `json:"code"` -} - -type Subdivision struct { - Name string `json:"name"` - Code string `json:"code"` -} - -type SubdivisionMap map[string][]Subdivision - -//go:embed data/*.json -var dataFS embed.FS - -func readJSON(filename string, v interface{}) error { - data, err := dataFS.ReadFile(filename) - if err != nil { - return err - } - return json.Unmarshal(data, v) -} - -func validateGeofeed(geofeedFile string, countries []Country, subdivisions SubdivisionMap) []string { - - countryMap := make(map[string]bool) - for _, country := range countries { - countryMap[country.Code] = true - } - - file, err := os.Open(geofeedFile) - if err != nil { - return []string{fmt.Sprintf("Failed to open geofeed file: %v", err)} - } - defer file.Close() - - scanner := bufio.NewScanner(file) - lineNumber := 0 - var errors []string - - for scanner.Scan() { - lineNumber++ - line := scanner.Text() - - // Skip blank lines - if strings.TrimSpace(line) == "" { - continue - } - - // Skip comment lines - if strings.HasPrefix(strings.TrimSpace(line), "#") { - continue - } - - reader := csv.NewReader(strings.NewReader(line)) - reader.FieldsPerRecord = -1 - record, _ := reader.Read() - - // Validate geofeed format (prefix, country_code, subdivision_code, city, postal_code) - if len(record) < 5 { - errors = append(errors, fmt.Sprintf("Line %d: invalid "+Magenta+"geofeed "+Reset+"format", lineNumber)) - continue - } - prefix, countryCode, subdivisionCode := record[0], record[1], record[2] - - // Validate prefix format - _, _, prefixErr := net.ParseCIDR(prefix) - if prefixErr != nil { - errors = append(errors, fmt.Sprintf("Line %d: invalid "+Magenta+"prefix "+Reset+"format ("+Cyan+"%s"+Reset+")", lineNumber, prefix)) - // continue - } - - // Skip empty country code - if countryCode == "" { - continue - } - - // Validate country code - if !countryMap[countryCode] { - errors = append(errors, fmt.Sprintf("Line %d: invalid "+Magenta+"country code "+Reset+"("+Cyan+"%s"+Reset+")", lineNumber, countryCode)) - continue - } - - // Skip empty subdivision code - if subdivisionCode == "" { - continue - } - - // Validate subdivision code - validSubdivision := false - for _, subdivision := range subdivisions[countryCode] { - if subdivision.Code == subdivisionCode { - validSubdivision = true - break - } - } - if !validSubdivision { - errors = append(errors, fmt.Sprintf("Line %d: invalid "+Magenta+"subdivision code "+Reset+"("+Cyan+"%s"+Reset+") "+"for country ("+Cyan+"%s"+Reset+")", lineNumber, subdivisionCode, countryCode)) - } - } - - return errors -} - -func main() { - countryFile := "data/iso3166-1.json" - subdivisionFile := "data/iso3166-2.json" - - if len(os.Args) < 2 { - fmt.Println("Usage: ./geofeed-validator ") - os.Exit(1) - } - - geofeedFile := os.Args[1] - - var countries []Country - var subdivisions SubdivisionMap - - if err := readJSON(countryFile, &countries); err != nil { - fmt.Printf("Failed to load countries: %v\n", err) - return - } - - if err := readJSON(subdivisionFile, &subdivisions); err != nil { - fmt.Printf("Failed to load subdivisions: %v\n", err) - return - } - - errors := validateGeofeed(geofeedFile, countries, subdivisions) - - if len(errors) == 0 { - fmt.Println("Congratulations! Your geofeed file is " + Green + "VALID" + Reset + ".") - } else { - fmt.Println("Your geofeed file is " + Red + "INVALID" + Reset + ":") - for _, err := range errors { - fmt.Println("- " + err) - } - } -}