158 lines
3.3 KiB
Go
158 lines
3.3 KiB
Go
package main
|
|
|
|
import "encoding/csv"
|
|
import "encoding/json"
|
|
import "io"
|
|
import "log"
|
|
import "os"
|
|
import "strconv"
|
|
|
|
type StateData struct {
|
|
Id int
|
|
Name string
|
|
Abbreviation string
|
|
Country string
|
|
Type_state string
|
|
Sort int
|
|
Status string
|
|
Occupied string
|
|
Notes string
|
|
Fips_state string
|
|
Assoc_press string
|
|
Standard_federal_region string
|
|
Census_region int
|
|
Census_region_name string
|
|
Census_division int
|
|
Census_division_name string
|
|
Circuit_court int
|
|
}
|
|
|
|
func readCsvHeader(line []string) (map[string]int, error) {
|
|
columns := make(map[string]int)
|
|
for i, col := range line {
|
|
columns[col] = i
|
|
}
|
|
return columns, nil
|
|
}
|
|
|
|
func readCsvLine(line []string, columns map[string]int) (*StateData, error) {
|
|
var err error
|
|
data := new(StateData)
|
|
for i, col := range line {
|
|
switch i {
|
|
case columns["id"]:
|
|
data.Id, err = strconv.Atoi(col)
|
|
if err != nil {
|
|
return data, err
|
|
}
|
|
case columns["name"]:
|
|
data.Name = col
|
|
case columns["abbreviation"]:
|
|
data.Abbreviation = col
|
|
case columns["country"]:
|
|
data.Country = col
|
|
case columns["type"]:
|
|
data.Type_state = col
|
|
case columns["sort"]:
|
|
data.Sort, err = strconv.Atoi(col)
|
|
if err != nil {
|
|
return data, err
|
|
}
|
|
case columns["status"]:
|
|
data.Status = col
|
|
case columns["occupied"]:
|
|
data.Occupied = col
|
|
case columns["notes"]:
|
|
data.Notes = col
|
|
case columns["fips_state"]:
|
|
data.Fips_state = col
|
|
case columns["assoc_press"]:
|
|
data.Assoc_press = col
|
|
case columns["standard_federal_region"]:
|
|
data.Standard_federal_region = col
|
|
case columns["census_region"]:
|
|
data.Census_region, err = strconv.Atoi(col)
|
|
if err != nil {
|
|
return data, err
|
|
}
|
|
case columns["census_region_name"]:
|
|
data.Census_region_name = col
|
|
case columns["census_division"]:
|
|
data.Census_division, err = strconv.Atoi(col)
|
|
if err != nil {
|
|
return data, err
|
|
}
|
|
case columns["census_division_name"]:
|
|
data.Census_division_name = col
|
|
case columns["circuit_court"]:
|
|
data.Circuit_court, err = strconv.Atoi(col)
|
|
if err != nil {
|
|
return data, err
|
|
}
|
|
}
|
|
}
|
|
return data, nil
|
|
}
|
|
|
|
func readCsv(in io.Reader) map[string]*StateData {
|
|
data := make(map[string]*StateData)
|
|
csvReader := csv.NewReader(in)
|
|
var header map[string]int
|
|
for {
|
|
line, err := csvReader.Read()
|
|
if err == io.EOF {
|
|
break
|
|
} else if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
if len(header) == 0 {
|
|
header, err = readCsvHeader(line)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
} else {
|
|
d, err := readCsvLine(line, header)
|
|
if err != nil {
|
|
log.Println("Invalid line", err) // skip
|
|
} else {
|
|
data[d.Abbreviation] = d
|
|
}
|
|
}
|
|
}
|
|
return data
|
|
}
|
|
|
|
func main() {
|
|
if len(os.Args) < 2 {
|
|
log.Fatalln("Usage statecsv <file>")
|
|
}
|
|
|
|
// read input
|
|
csv, err := os.Open(os.Args[1])
|
|
if err != nil {
|
|
log.Fatalln("Error reading file", err)
|
|
}
|
|
defer csv.Close()
|
|
|
|
// parse data
|
|
data := readCsv(csv)
|
|
|
|
// convert JSON
|
|
var writer io.Writer
|
|
if len(os.Args) > 2 {
|
|
f, ferr := os.Create(os.Args[2])
|
|
if ferr != nil {
|
|
panic(ferr)
|
|
}
|
|
defer f.Close()
|
|
writer = f
|
|
} else {
|
|
writer = os.Stdout
|
|
}
|
|
err = json.NewEncoder(writer).Encode(data)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
}
|