mirror of
https://github.com/imjasonh/csvstruct
synced 2026-07-18 14:56:23 +00:00
support non-string values, add skipped test for pointers
This commit is contained in:
parent
e351bdc1ec
commit
3eb5423212
2 changed files with 63 additions and 8 deletions
27
csvstruct.go
27
csvstruct.go
|
|
@ -1,7 +1,6 @@
|
||||||
// TODO: support DecodeNext(nil) to skip a line
|
// TODO: support DecodeNext(nil) to skip a line
|
||||||
// TODO: NewEncoder/EncodeNext -- header will be fields in first item...
|
// TODO: NewEncoder/EncodeNext -- header will be fields in first item...
|
||||||
// TODO: Encode/Decode map[string]string
|
// TODO: Encode/Decode map[string]string
|
||||||
// TODO: Encode/Decode non-string values?
|
|
||||||
|
|
||||||
// Package csvstruct provides methods to decode a CSV file into a struct.
|
// Package csvstruct provides methods to decode a CSV file into a struct.
|
||||||
package csvstruct
|
package csvstruct
|
||||||
|
|
@ -12,6 +11,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Decoder reads and decodes CSV rows from an input stream.
|
// Decoder reads and decodes CSV rows from an input stream.
|
||||||
|
|
@ -69,7 +69,30 @@ func (d *decoder) DecodeNext(v interface{}) error {
|
||||||
strv := line[idx]
|
strv := line[idx]
|
||||||
vf := rv.FieldByName(f.Name)
|
vf := rv.FieldByName(f.Name)
|
||||||
if vf.CanSet() {
|
if vf.CanSet() {
|
||||||
vf.SetString(strv)
|
switch vf.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
vf.SetString(strv)
|
||||||
|
case reflect.Int, reflect.Int64:
|
||||||
|
i, err := strconv.ParseInt(strv, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error decoding: %v", err)
|
||||||
|
}
|
||||||
|
vf.SetInt(i)
|
||||||
|
case reflect.Float64:
|
||||||
|
f, err := strconv.ParseFloat(strv, 64)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error decoding: %v", err)
|
||||||
|
}
|
||||||
|
vf.SetFloat(f)
|
||||||
|
case reflect.Bool:
|
||||||
|
b, err := strconv.ParseBool(strv)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error decoding: %v", err)
|
||||||
|
}
|
||||||
|
vf.SetBool(b)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("can't decode type %v", vf.Type())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,9 @@ func TestDecode_Unexported(t *testing.T) {
|
||||||
type row struct {
|
type row struct {
|
||||||
Exported, unexported string
|
Exported, unexported string
|
||||||
}
|
}
|
||||||
d := NewDecoder(strings.NewReader(`Exported,unexported
|
|
||||||
a,b`))
|
|
||||||
var r row
|
var r row
|
||||||
if err := d.DecodeNext(&r); err != nil {
|
if err := NewDecoder(strings.NewReader(`Exported,unexported
|
||||||
|
a,b`)).DecodeNext(&r); err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
exp := row{Exported: "a"}
|
exp := row{Exported: "a"}
|
||||||
|
|
@ -82,10 +81,9 @@ func TestDecode_Tags(t *testing.T) {
|
||||||
Bar string
|
Bar string
|
||||||
Ignored string `csv:"-"`
|
Ignored string `csv:"-"`
|
||||||
}
|
}
|
||||||
d := NewDecoder(strings.NewReader(`renamed_foo,Bar,Ignored
|
|
||||||
a,b,c`))
|
|
||||||
var r row
|
var r row
|
||||||
if err := d.DecodeNext(&r); err != nil {
|
if err := NewDecoder(strings.NewReader(`renamed_foo,Bar,Ignored
|
||||||
|
a,b,c`)).DecodeNext(&r); err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
exp := row{"a", "b", ""}
|
exp := row{"a", "b", ""}
|
||||||
|
|
@ -93,3 +91,37 @@ a,b,c`))
|
||||||
t.Errorf("unexpected results, got %v, want %v", r, exp)
|
t.Errorf("unexpected results, got %v, want %v", r, exp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDecode_NonStrings(t *testing.T) {
|
||||||
|
type row struct {
|
||||||
|
Int int
|
||||||
|
Int64 int64
|
||||||
|
Float64 float64
|
||||||
|
Bool bool
|
||||||
|
}
|
||||||
|
var r row
|
||||||
|
if err := NewDecoder(strings.NewReader(`Int,Int64,Float64,Bool
|
||||||
|
123,123456789,123.456,true`)).DecodeNext(&r); err != nil {
|
||||||
|
t.Errorf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
exp := row{123, 123456789, 123.456, true}
|
||||||
|
if !reflect.DeepEqual(r, exp) {
|
||||||
|
t.Errorf("unexpected results, got %v, want %v", r, exp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDecode_Pointers(t *testing.T) {
|
||||||
|
t.Skip("pointers are not yet supported")
|
||||||
|
type row struct {
|
||||||
|
S string
|
||||||
|
SP *string
|
||||||
|
}
|
||||||
|
var r row
|
||||||
|
if err := NewDecoder(strings.NewReader(`S,SP
|
||||||
|
a,b`)).DecodeNext(&r); err != nil {
|
||||||
|
t.Errorf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if r.S != "a" || r.SP == nil || *r.SP != "b" {
|
||||||
|
t.Errorf("unexpected results, got %v", r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue