wip: unmarshaler

This commit is contained in:
Suyono 2023-06-23 11:46:38 +10:00
parent 07fabf1962
commit b062eea7b6
4 changed files with 71 additions and 47 deletions

View File

@ -3,64 +3,70 @@ package gocsvparser
import (
"fmt"
"reflect"
)
type defaultRecordHandlerMode int
const (
single defaultRecordHandlerMode = 1
slice defaultRecordHandlerMode = 2
"strings"
)
type defaultRecordHandler struct {
structType reflect.Type
mode defaultRecordHandlerMode
slice reflect.Value
fieldByName map[string]FieldsHandlerByName
fieldByIndices map[int]FieldsHandlerByIndices
handlersByName map[string]reflect.StructField
outType reflect.Type
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) {
val := reflect.ValueOf(v)
if val.Kind() == reflect.Pointer {
val = val.Elem()
func (d *defaultRecordHandler) HandleRecord(v interface{}, record []string) error {
//TODO: implementation
if d.outType == nil {
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, fmt.Errorf("invalid value %v", val)
return nil
}
func (dr *defaultRecordHandler) buildFieldsHandler() {
}
func (df *defaultFieldsHandlerByName) FieldsName() string {
//TODO: implementation
return ""
}
func (df *defaultFieldsHandlerByName) NumFields() int {
//TODO: implementation
return 0
}
func (df *defaultFieldsHandlerByName) Fields(fields ...string) error {
func (d *defaultRecordHandler) FieldsHandlers() []FieldsHandler {
//TODO: implementation
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
}

View File

@ -1 +1,6 @@
package gocsvparser
const (
csvTag string = "csv"
csvIndexTag string = "csv.index"
)

View File

@ -4,8 +4,14 @@ import (
"encoding/csv"
)
type FieldsConfig struct {
Name string
Num int
}
type FieldsHandlerByName interface {
FieldsName() string
FieldName() string
FieldByName(name, field string) error
FieldsHandler
}
@ -22,6 +28,9 @@ type FieldsHandler interface {
type RecordHandler interface {
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 {

View File

@ -17,6 +17,10 @@ type anon struct {
OutputY int64 `csv:"y"`
}
func TestParse(t *testing.T) {
newDefaultHandler().parseVal(&Coba{})
}
func TestRead(t *testing.T) {
var coba []Coba