gocarina / gocsv

The GoCSV package aims to provide easy CSV serialization and deserialization to the golang programming language

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

UnmarshalString cannot parse string from MarshalString

PatrLind opened this issue · comments

I get a panic trying to unmarshal a string marshaled by marshal.
This happens when I try to use json struct tag as the field name.

The output is:

$ go test /tmp/gocsv_test.go 
str name,subObj.a,subObj.b,subObjs
Obj1,a1,b1,"[{""a"":""a2"",""b"":""b2""},{""a"":""a3"",""b"":""b3""}]"

--- FAIL: TestCSV (0.00s)
    --- FAIL: TestCSV/test_1_json (0.00s)
panic: reflect: call of reflect.Value.Field on zero Value [recovered]
        panic: reflect: call of reflect.Value.Field on zero Value

goroutine 7 [running]:
testing.tRunner.func1.2({0x54b8a0, 0xc000012288})
        /usr/local/go/src/testing/testing.go:1545 +0x238
testing.tRunner.func1()
        /usr/local/go/src/testing/testing.go:1548 +0x397
panic({0x54b8a0?, 0xc000012288?})
        /usr/local/go/src/runtime/panic.go:914 +0x21f
reflect.Value.Field({0x0?, 0x0?, 0xc0000169f0?}, 0xc0000d39e0?)
        /usr/local/go/src/reflect/value.go:1278 +0xcf
reflect.Value.FieldByIndex({0x0?, 0x0?, 0x404da8?}, {0xc000014268?, 0x0?, 0xc0000169f0?})
        /usr/local/go/src/reflect/value.go:1311 +0x4e
github.com/gocarina/gocsv.setInnerField(0xc0000d3aa8?, 0xf0?, {0xc000014268?, 0x1, 0x1}, {0xc000020404, 0x2}, 0x28?)
        /home/patrik/go/pkg/mod/github.com/gocarina/gocsv@v0.0.0-20230616125104-99d496ca653d/decode.go:504 +0x69c
github.com/gocarina/gocsv.setInnerField(0x54d640?, 0x0?, {0xc000014260?, 0x2, 0x2}, {0xc000020404, 0x2}, 0x70?)
        /home/patrik/go/pkg/mod/github.com/gocarina/gocsv@v0.0.0-20230616125104-99d496ca653d/decode.go:502 +0x67c
github.com/gocarina/gocsv.readToWithErrorHandler({0x7fd9c18a2898, 0xc00002c590}, 0x0, {0x543400?, 0xc000012228?})
        /home/patrik/go/pkg/mod/github.com/gocarina/gocsv@v0.0.0-20230616125104-99d496ca653d/decode.go:226 +0x7c8
github.com/gocarina/gocsv.readTo(...)
        /home/patrik/go/pkg/mod/github.com/gocarina/gocsv@v0.0.0-20230616125104-99d496ca653d/decode.go:144
github.com/gocarina/gocsv.Unmarshal({0x5a9580?, 0xc00007e160?}, {0x543400, 0xc000012228})
        /home/patrik/go/pkg/mod/github.com/gocarina/gocsv@v0.0.0-20230616125104-99d496ca653d/csv.go:214 +0x7d
github.com/gocarina/gocsv.UnmarshalString(...)
        /home/patrik/go/pkg/mod/github.com/gocarina/gocsv@v0.0.0-20230616125104-99d496ca653d/csv.go:204
command-line-arguments.TestCSV.func1(0xc0000c24e0)
        /tmp/gocsv_test.go:57 +0x19b
testing.tRunner(0xc0000c24e0, 0xc000016690)
        /usr/local/go/src/testing/testing.go:1595 +0xff
created by testing.(*T).Run in goroutine 6
        /usr/local/go/src/testing/testing.go:1648 +0x3ad
FAIL    command-line-arguments  0.004s
FAIL

Test code:

package main

import (
	"fmt"
	"testing"

	"github.com/gocarina/gocsv"
)

type TestObj struct {
	Name    string     `json:"name,omitempty"`
	SubObj  *TestOb2   `json:"subObj,omitempty"`
	SubObjs []*TestOb2 `json:"subObjs,omitempty"`
}

type TestOb2 struct {
	A string `json:"a,omitempty"`
	B string `json:"b,omitempty"`
}

func TestCSV(t *testing.T) {
	obj1 := []*TestObj{
		{
			Name: "Obj1",
			SubObj: &TestOb2{
				A: "a1",
				B: "b1",
			},
			SubObjs: []*TestOb2{
				{
					A: "a2",
					B: "b2",
				},
				{
					A: "a3",
					B: "b3",
				},
			},
		},
	}

	testCases := []struct {
		TagName string
	}{
		{"json"}, {"csv"},
	}
	for i, tc := range testCases {
		tc := tc
		t.Run(fmt.Sprintf("test_%d_%s", i+1, tc.TagName), func(t *testing.T) {
			gocsv.TagName = tc.TagName
			str, err := gocsv.MarshalString(obj1)
			if err != nil {
				t.Error(err)
			}
			obj2 := []*TestObj{}
			fmt.Println("str", str)
			err = gocsv.UnmarshalString(str, &obj2)
			if err != nil {
				t.Error(err)
			}
		})
	}
}