wip: unmarshaler
This commit is contained in:
parent
07fabf1962
commit
b062eea7b6
@ -3,64 +3,70 @@ package gocsvparser
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
)
|
"strings"
|
||||||
|
|
||||||
type defaultRecordHandlerMode int
|
|
||||||
|
|
||||||
const (
|
|
||||||
single defaultRecordHandlerMode = 1
|
|
||||||
slice defaultRecordHandlerMode = 2
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type defaultRecordHandler struct {
|
type defaultRecordHandler struct {
|
||||||
structType reflect.Type
|
handlersByName map[string]reflect.StructField
|
||||||
mode defaultRecordHandlerMode
|
outType reflect.Type
|
||||||
slice reflect.Value
|
|
||||||
fieldByName map[string]FieldsHandlerByName
|
|
||||||
fieldByIndices map[int]FieldsHandlerByIndices
|
|
||||||
fieldsHandlers []FieldsHandler
|
fieldsHandlers []FieldsHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
type defaultFieldsHandlerByName struct {
|
func newDefaultHandler() *defaultRecordHandler {
|
||||||
|
newHander := new(defaultRecordHandler)
|
||||||
|
newHander.handlersByName = make(map[string]reflect.StructField)
|
||||||
|
return newHander
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDefaultRecordHandler(v interface{}) (*defaultRecordHandler, error) {
|
func (d *defaultRecordHandler) HandleRecord(v interface{}, record []string) error {
|
||||||
val := reflect.ValueOf(v)
|
//TODO: implementation
|
||||||
if val.Kind() == reflect.Pointer {
|
if d.outType == nil {
|
||||||
val = val.Elem()
|
|
||||||
|
|
||||||
recordHandler := &defaultRecordHandler{}
|
|
||||||
switch val.Kind() {
|
|
||||||
case reflect.Slice:
|
|
||||||
recordHandler.mode = slice
|
|
||||||
typ := val.Type().Elem()
|
|
||||||
if typ.Kind() == reflect.Struct {
|
|
||||||
recordHandler.slice = val
|
|
||||||
recordHandler.structType = typ
|
|
||||||
}
|
|
||||||
case reflect.Struct:
|
|
||||||
recordHandler.mode = single
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
return nil, fmt.Errorf("invalid value %v", val)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dr *defaultRecordHandler) buildFieldsHandler() {
|
func (d *defaultRecordHandler) FieldsHandlers() []FieldsHandler {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (df *defaultFieldsHandlerByName) FieldsName() string {
|
|
||||||
//TODO: implementation
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (df *defaultFieldsHandlerByName) NumFields() int {
|
|
||||||
//TODO: implementation
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (df *defaultFieldsHandlerByName) Fields(fields ...string) error {
|
|
||||||
//TODO: implementation
|
//TODO: implementation
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *defaultRecordHandler) SetFieldConfigs(configs []FieldsConfig) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *defaultRecordHandler) parseVal(v interface{}) error {
|
||||||
|
typ := reflect.TypeOf(v)
|
||||||
|
if typ.Kind() == reflect.Pointer {
|
||||||
|
typ = typ.Elem()
|
||||||
|
|
||||||
|
if typ.Kind() == reflect.Struct {
|
||||||
|
d.outType = typ
|
||||||
|
return d.buildStructHandlers()
|
||||||
|
} else if typ.Kind() == reflect.Map {
|
||||||
|
//TODO: implementation
|
||||||
|
} else if typ.Kind() == reflect.Slice {
|
||||||
|
//TODO: implementation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Errorf("v should be pointer of Struct, Map, or Slice: %+v", typ)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *defaultRecordHandler) buildStructHandlers() error {
|
||||||
|
//TODO: implementation
|
||||||
|
for _, field := range reflect.VisibleFields(d.outType) {
|
||||||
|
if csv, ok := field.Tag.Lookup(csvTag); ok {
|
||||||
|
s := strings.Split(csv, ",")
|
||||||
|
if len(s) == 0 {
|
||||||
|
return fmt.Errorf("invalid tag %+v", field.Tag)
|
||||||
|
}
|
||||||
|
if _, ok = d.handlersByName[s[0]]; ok {
|
||||||
|
return fmt.Errorf("problem with the receiving struct, multiple field with tag %s", s[0])
|
||||||
|
}
|
||||||
|
d.handlersByName[s[0]] = field
|
||||||
|
} else if csvIndex, ok := field.Tag.Lookup(csvIndexTag); ok {
|
||||||
|
_ = csvIndex //TODO: process tag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@ -1 +1,6 @@
|
|||||||
package gocsvparser
|
package gocsvparser
|
||||||
|
|
||||||
|
const (
|
||||||
|
csvTag string = "csv"
|
||||||
|
csvIndexTag string = "csv.index"
|
||||||
|
)
|
||||||
|
|||||||
11
unmarshal.go
11
unmarshal.go
@ -4,8 +4,14 @@ import (
|
|||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type FieldsConfig struct {
|
||||||
|
Name string
|
||||||
|
Num int
|
||||||
|
}
|
||||||
|
|
||||||
type FieldsHandlerByName interface {
|
type FieldsHandlerByName interface {
|
||||||
FieldsName() string
|
FieldName() string
|
||||||
|
FieldByName(name, field string) error
|
||||||
FieldsHandler
|
FieldsHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,6 +28,9 @@ type FieldsHandler interface {
|
|||||||
|
|
||||||
type RecordHandler interface {
|
type RecordHandler interface {
|
||||||
FieldsHandlers() []FieldsHandler
|
FieldsHandlers() []FieldsHandler
|
||||||
|
// SetFieldConfigs is only effective if a Map is passed to HandleRecord
|
||||||
|
SetFieldConfigs(configs []FieldsConfig)
|
||||||
|
HandleRecord(v interface{}, record []string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type Unmarshaler struct {
|
type Unmarshaler struct {
|
||||||
|
|||||||
@ -17,6 +17,10 @@ type anon struct {
|
|||||||
OutputY int64 `csv:"y"`
|
OutputY int64 `csv:"y"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParse(t *testing.T) {
|
||||||
|
newDefaultHandler().parseVal(&Coba{})
|
||||||
|
}
|
||||||
|
|
||||||
func TestRead(t *testing.T) {
|
func TestRead(t *testing.T) {
|
||||||
var coba []Coba
|
var coba []Coba
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user