cargo-platform/pkg/csv/csv.go
teguh nugroho 55d7dee111
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
stopimport job
2026-08-18 14:43:48 +07:00

103 lines
1.7 KiB
Go

package csv
import (
"context"
"encoding/csv"
"io"
"strings"
)
type RowHandler func(row []string, rowNumber int) error
func ReadCSV(file io.Reader, handler RowHandler) (int, []string, error) {
return ReadCSVWithContext(context.Background(), file, handler)
}
func ReadCSVWithContext(ctx context.Context, file io.Reader, handler RowHandler) (int, []string, error) {
reader := csv.NewReader(file)
reader.LazyQuotes = true
reader.TrimLeadingSpace = true
var errors []string
rowNumber := 0
totalRows := 0
for {
select {
case <-ctx.Done():
return totalRows, errors, ctx.Err()
default:
}
row, err := reader.Read()
if err == io.EOF {
break
}
rowNumber++
if err != nil {
errors = append(errors, "Row "+itoa(rowNumber)+": "+err.Error())
continue
}
if len(row) == 0 || (len(row) == 1 && strings.TrimSpace(row[0]) == "") {
continue
}
if rowNumber == 1 {
continue
}
if err := handler(row, rowNumber); err != nil {
if ctx.Err() != nil {
return totalRows, errors, ctx.Err()
}
errors = append(errors, "Row "+itoa(rowNumber)+": "+err.Error())
}
totalRows++
}
return totalRows, errors, nil
}
func CountRows(file io.Reader) (int, error) {
reader := csv.NewReader(file)
count := 0
for {
_, err := reader.Read()
if err == io.EOF {
break
}
if err != nil {
continue
}
count++
}
return count, nil
}
func WriteCSV(headers []string, rows [][]string) string {
var sb strings.Builder
writer := csv.NewWriter(&sb)
writer.Write(headers)
for _, row := range rows {
writer.Write(row)
}
writer.Flush()
return sb.String()
}
func itoa(i int) string {
if i == 0 {
return "0"
}
result := ""
for i > 0 {
result = string(rune('0'+i%10)) + result
i /= 10
}
return result
}