package csvimport import ( "encoding/csv" "fmt" "io" "strings" ) type Row struct { SrcLogin string SrcPass string DstLogin string DstPass string } func Parse(r io.Reader) ([]Row, error) { cr := csv.NewReader(r) cr.FieldsPerRecord = -1 // проверяем сами var rows []Row seen := map[string]bool{} for { rec, err := cr.Read() if err == io.EOF { break } if err != nil { return nil, err } line, _ := cr.FieldPos(0) if len(rec) == 1 && strings.TrimSpace(rec[0]) == "" { continue // encoding/csv уже пропускает голые пустые строки; это ветка ловит строки из одних пробелов } if len(rec) != 4 { return nil, fmt.Errorf("line %d: expected 4 columns, got %d", line, len(rec)) } for i := range rec { rec[i] = strings.TrimSpace(rec[i]) if rec[i] == "" { return nil, fmt.Errorf("line %d: column %d is empty", line, i+1) } } if seen[rec[0]] { return nil, fmt.Errorf("line %d: duplicate src_login %q", line, rec[0]) } seen[rec[0]] = true rows = append(rows, Row{SrcLogin: rec[0], SrcPass: rec[1], DstLogin: rec[2], DstPass: rec[3]}) } if len(rows) == 0 { return nil, fmt.Errorf("no rows parsed") } return rows, nil }