1
0
Fork 0
mirror of https://github.com/imjasonh/csvstruct synced 2026-07-10 04:12:12 +00:00
csvstruct/csvstruct.go

65 lines
1.1 KiB
Go
Raw Normal View History

package csvstruct
2014-01-08 06:34:16 -08:00
import (
"encoding/csv"
"io"
"reflect"
)
type Decoder interface {
DecodeNext(v interface{}) error
2014-01-08 06:34:16 -08:00
}
type decoder struct {
hm map[string]int
r csv.Reader
2014-01-08 06:34:16 -08:00
}
func NewDecoder(r io.Reader) Decoder {
return decoder{
r: *csv.NewReader(r),
2014-01-08 06:34:16 -08:00
}
}
func (d decoder) DecodeNext(in interface{}) error {
if len(d.hm) == 0 {
// First run; read header row
header, err := d.r.Read()
2014-01-08 06:34:16 -08:00
if err != nil {
return err
}
d.hm = reverse(header)
}
t := reflect.TypeOf(in)
line, err := d.r.Read()
if err != nil {
return err
}
out := reflect.ValueOf(in)
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
n := f.Name
// TODO: f.Tag.Get("csv")
val := line[d.hm[n]]
v := reflect.ValueOf(&val)
v.Elem().SetString(line[d.hm[n]])
out.Elem().Set(v)
2014-01-08 06:34:16 -08:00
}
return nil
}
func reverse(in []string) map[string]int {
m := make(map[string]int, len(in))
for i, v := range in {
m[v] = i
}
return m
}
2014-05-14 21:11:21 -04:00
// TODO: NewEncoder/EncodeNext -- header will be fields in first item...
// TODO: Encode/Decode map[string]interface{} ?
// TODO: Encode/Decode non-string values?