package internal import ( "encoding/csv" "errors" "io" "os" "strconv" ) type Headings []string func (h Headings) IndexOf(heading string) int { for i, value := range h { if value == heading { return i } } return -1 } func ReadCsvRedirects(file string) (Redirects, error) { reader, err := os.Open(file) if err != nil { return nil, err } csvReader := csv.NewReader(reader) // Process headings textHeadings, err := csvReader.Read() if err != nil { return nil, err } headings := Headings(textHeadings) fromCol := headings.IndexOf("From") toCol := headings.IndexOf("To") statusCol := headings.IndexOf("Status Code") if fromCol == -1 || toCol == -1 || statusCol == -1 { return nil, errors.New("CSV must contain From, To, and Status Code headings") } // Read data redirects := Redirects{} for { row, err := csvReader.Read() if err != nil { if errors.Is(err, io.EOF) { break } return nil, err } if row == nil { break } statusCode, err := strconv.Atoi(row[statusCol]) if err != nil { return nil, err } redirect := &Redirect{ From: row[fromCol], To: row[toCol], StatusCode: statusCode, } redirects = append(redirects, redirect) } return redirects, nil }