categraf/inputs/nvidiasmi/csv.go

91 lines
1.9 KiB
Go

package nvidiasmi
import (
"fmt"
"strings"
)
type table struct {
rows []row
rFields []rField
qFieldToCells map[qField][]cell
}
type row struct {
qFieldToCells map[qField]cell
cells []cell
}
type cell struct {
qField qField
rField rField
rawValue string
}
var ErrFieldCountMismatch = fmt.Errorf("field count mismatch")
func parseCSVIntoTable(queryResult string, qFields []qField) (table, error) {
lines := strings.Split(strings.TrimSpace(queryResult), "\n")
titlesLine := lines[0]
valuesLines := lines[1:]
rFields := toRFieldSlice(parseCSVLine(titlesLine))
numCols := len(qFields)
numRows := len(valuesLines)
rows := make([]row, numRows)
qFieldToCells := make(map[qField][]cell)
for _, q := range qFields {
qFieldToCells[q] = make([]cell, numRows)
}
for rowIndex, valuesLine := range valuesLines {
qFieldToCell := make(map[qField]cell, numCols)
cells := make([]cell, numCols)
rawValues := parseCSVLine(valuesLine)
if len(qFields) != len(rFields) {
return table{}, fmt.Errorf("%w: query fields: %d, returned fields: %d",
ErrFieldCountMismatch, len(qFields), len(rFields))
}
for colIndex, rawValue := range rawValues {
currentQField := qFields[colIndex]
currentRField := rFields[colIndex]
tableCell := cell{
qField: currentQField,
rField: currentRField,
rawValue: rawValue,
}
qFieldToCell[currentQField] = tableCell
cells[colIndex] = tableCell
qFieldToCells[currentQField][rowIndex] = tableCell
}
tableRow := row{
qFieldToCells: qFieldToCell,
cells: cells,
}
rows[rowIndex] = tableRow
}
return table{
rows: rows,
rFields: rFields,
qFieldToCells: qFieldToCells,
}, nil
}
func parseCSVLine(line string) []string {
values := strings.Split(line, ",")
result := make([]string, len(values))
for i, field := range values {
result[i] = strings.TrimSpace(field)
}
return result
}