Skip to content

Instantly share code, notes, and snippets.

@lotreal
Created August 7, 2015 13:48
Show Gist options
  • Save lotreal/be78972aceba59e4b867 to your computer and use it in GitHub Desktop.
Save lotreal/be78972aceba59e4b867 to your computer and use it in GitHub Desktop.
package main
import (
"encoding/csv"
"fmt"
"io"
"reflect"
"strconv"
"strings"
)
type Test struct {
Name string
Surname string
Age int
}
func Unmarshal(reader *csv.Reader, v interface{}) error {
record, err := reader.Read()
if err != nil {
return err
}
s := reflect.ValueOf(v).Elem()
if s.NumField() != len(record) {
return &FieldMismatch{s.NumField(), len(record)}
}
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
switch f.Type().String() {
case "string":
f.SetString(record[i])
case "int":
ival, err := strconv.ParseInt(record[i], 10, 0)
if err != nil {
return err
}
f.SetInt(ival)
default:
return &UnsupportedType{f.Type().String()}
}
}
return nil
}
func main() {
var source = "John;Smith;42\nPiter;Abel;50"
var reader = csv.NewReader(strings.NewReader(source))
reader.Comma = ';'
var test Test
for {
err := Unmarshal(reader, &test)
if err == io.EOF {
break
}
if err != nil {
panic(err)
}
fmt.Printf("%s %s has age of %d\n", test.Name, test.Surname, test.Age)
}
}
type FieldMismatch struct {
expected, found int
}
func (e *FieldMismatch) Error() string {
return "CSV line fields mismatch. Expected " + strconv.Itoa(e.expected) + " found " + strconv.Itoa(e.found)
}
type UnsupportedType struct {
Type string
}
func (e *UnsupportedType) Error() string {
return "Unsupported type: " + e.Type
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment