From 4677738c634986349cca0aed844a6b0f12136b50 Mon Sep 17 00:00:00 2001 From: Chris Kruger <118869997+vgw-chriskruger@users.noreply.github.com> Date: Tue, 30 Apr 2024 15:24:11 +0800 Subject: [PATCH] fix quoted headers --- unmarshal.go | 16 ++++++++++++++++ unmarshal_test.go | 14 ++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/unmarshal.go b/unmarshal.go index 10f7a8f..adb4745 100644 --- a/unmarshal.go +++ b/unmarshal.go @@ -288,6 +288,8 @@ func (d *Decoder) Decode(v interface{}) error { // Decoder state required to map CSV records later on. func (d *Decoder) DecodeHeader(line string) ([]string, error) { d.headerKeys = strings.Split(line, string(d.sep)) + d.headerKeys = maybeTrimQuotes(d.headerKeys) + if len(d.headerKeys) == 0 { return nil, fmt.Errorf("csv: empty header") } @@ -560,3 +562,17 @@ func setValue(dst reflect.Value, src, fName string) error { } return nil } + +func maybeTrimQuotes(tokens []string) []string { + trimmed := make([]string, 0, len(tokens)) + for _, s := range tokens { + if len(s) > 0 && s[0] == '"' { + s = s[1:] + } + if len(s) > 0 && s[len(s)-1] == '"' { + s = s[:len(s)-1] + } + trimmed = append(trimmed, s) + } + return trimmed +} diff --git a/unmarshal_test.go b/unmarshal_test.go index 197001d..ed30dad 100644 --- a/unmarshal_test.go +++ b/unmarshal_test.go @@ -78,6 +78,8 @@ func (x SpecialStruct) String() string { const ( CsvWithHeader = `s,i,f,b +Hello,42,23.45,true` + CsvWithQuotedHeader = `"s","i","f","b" Hello,42,23.45,true` CsvWithoutHeader = `Hello,true,42,23.45` CsvWhitespace = ` Hello , true , 42 , 23.45` @@ -275,6 +277,18 @@ func TestUnmarshalFromByte(t *testing.T) { CheckA(t, a[0], A1) } +func TestUnmarshalQuotedFromByte(t *testing.T) { + a := make([]*A, 0) + if err := Unmarshal([]byte(CsvWithQuotedHeader), &a); err != nil { + t.Error(err) + } + if len(a) != 1 { + t.Errorf("invalid record count, got=%d expected=%d", len(a), 1) + return + } + CheckA(t, a[0], A1) +} + func TestUnmarshalFromReader(t *testing.T) { r := bytes.NewReader([]byte(CsvWithHeader)) dec := NewDecoder(r)