From e772ad89736bcd6b47b5d0638e1403a6cc690c0e Mon Sep 17 00:00:00 2001 From: Andy Bartelsmeier Date: Thu, 18 Jan 2024 20:24:42 +0000 Subject: [PATCH 1/4] feat: add tag key option --- csvtag.go | 1 + csvtag_test.go | 21 +++++++++++++++++++++ dump.go | 8 ++++++-- dump_test.go | 4 ++++ load.go | 10 +++++++--- load_test.go | 6 ++++++ 6 files changed, 45 insertions(+), 5 deletions(-) diff --git a/csvtag.go b/csvtag.go index 46d73e8..39e7d1b 100644 --- a/csvtag.go +++ b/csvtag.go @@ -4,4 +4,5 @@ package csvtag type CsvOptions struct { Separator rune Header []string + TagKey string } diff --git a/csvtag_test.go b/csvtag_test.go index e183e67..5fa68cc 100644 --- a/csvtag_test.go +++ b/csvtag_test.go @@ -25,3 +25,24 @@ func TestDumpAndLoad(t *testing.T) { t.Fail() } } + +func TestDumpAndLoadTagKey(t *testing.T) { + str, err := DumpToString(tabTestTagKey, CsvOptions{TagKey: "json"}) + if err != nil { + fmt.Println(err) + t.Fail() + } + + tabT := []testTagKey{} + err = LoadFromString(str, &tabT, CsvOptions{TagKey: "json"}) + if err != nil { + fmt.Println(err) + t.Fail() + } + + if tabT[0].ID != tabTestTagKey[0].ID || + tabT[0].Name != tabTestTagKey[0].Name || + tabT[0].Num != tabTestTagKey[0].Num { + t.Fail() + } +} diff --git a/dump.go b/dump.go index 5dd333d..52b474d 100644 --- a/dump.go +++ b/dump.go @@ -30,10 +30,14 @@ func DumpToWriter(slice interface{}, writer io.Writer, options ...CsvOptions) er option = options[0] } + if option.TagKey == "" { + option.TagKey = "csv" + } + // Generate the header. if option.Header == nil { for i := 0; i < reflectedValue.Type().Elem().NumField(); i++ { - name := reflectedValue.Type().Elem().Field(i).Tag.Get("csv") + name := reflectedValue.Type().Elem().Field(i).Tag.Get(option.TagKey) if name != "" { option.Header = append(option.Header, name) } @@ -58,7 +62,7 @@ func DumpToWriter(slice interface{}, writer io.Writer, options ...CsvOptions) er for j := 0; j < reflectedValue.Type().Elem().NumField(); j++ { valueRv := reflectedValue.Index(i) value := valueRv.Field(j) - tag := valueRv.Type().Field(j).Tag.Get("csv") + tag := valueRv.Type().Field(j).Tag.Get(option.TagKey) if tag == "" { continue diff --git a/dump_test.go b/dump_test.go index fa52044..eeb79c3 100644 --- a/dump_test.go +++ b/dump_test.go @@ -10,6 +10,10 @@ var tabTest = []test{ {"name", 1, 0.000001}, } +var tabTestTagKey = []testTagKey{ + {"name", 1, 0.000001}, +} + var tabTestNoID = []testNoID{ {"name", 1, 0.000001}, } diff --git a/load.go b/load.go index f48ffd6..abcb2c8 100644 --- a/load.go +++ b/load.go @@ -38,6 +38,10 @@ func LoadFromReader(file io.Reader, destination interface{}, options ...CsvOptio option = options[0] } + if option.TagKey == "" { + option.TagKey = "csv" + } + header, content, err := readFile(file, option.Separator, option.Header) if err != nil { return fmt.Errorf("error reading csv from io.Reader: %v", err) @@ -48,7 +52,7 @@ func LoadFromReader(file io.Reader, destination interface{}, options ...CsvOptio return nil } - err = mapToDestination(header, content, destination) + err = mapToDestination(header, content, destination, option.TagKey) if err != nil { return fmt.Errorf("error mapping the content to the destination\n ==> %v", err) } @@ -166,7 +170,7 @@ func skipBOM(file io.Reader) io.Reader { // @param header: the csv header to match with the struct's tags. // @param content: the content to put in destination. // @param destination: the destination where to put the file's content. -func mapToDestination(header []string, content [][]string, destination interface{}) error { +func mapToDestination(header []string, content [][]string, destination interface{}, tagKey string) error { if destination == nil { return fmt.Errorf("destination slice is nil") } @@ -192,7 +196,7 @@ func mapToDestination(header []string, content [][]string, destination interface emptyStruct := sliceRv.Index(i) for j := 0; j < emptyStruct.NumField(); j++ { - propertyTag := emptyStruct.Type().Field(j).Tag.Get("csv") + propertyTag := emptyStruct.Type().Field(j).Tag.Get(tagKey) if propertyTag == "" { continue } diff --git a/load_test.go b/load_test.go index 6abc4fc..5f1d654 100644 --- a/load_test.go +++ b/load_test.go @@ -10,6 +10,12 @@ type test struct { Num float64 `csv:"header3"` } +type testTagKey struct { + Name string `json:"header1"` + ID int `json:"header2"` + Num float64 `json:"header3"` +} + type testNoID struct { Name string `csv:"header1"` ID int From c9f15dbe30291d0fca35293e61517dd1c60adf09 Mon Sep 17 00:00:00 2001 From: Andy Bartelsmeier Date: Thu, 18 Jan 2024 20:43:47 +0000 Subject: [PATCH 2/4] feat: default tag key const --- csvtag.go | 2 ++ dump.go | 2 +- load.go | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/csvtag.go b/csvtag.go index 39e7d1b..20f3e8e 100644 --- a/csvtag.go +++ b/csvtag.go @@ -6,3 +6,5 @@ type CsvOptions struct { Header []string TagKey string } + +const DefaultTagKey string = "csv" diff --git a/dump.go b/dump.go index 52b474d..8fc0020 100644 --- a/dump.go +++ b/dump.go @@ -31,7 +31,7 @@ func DumpToWriter(slice interface{}, writer io.Writer, options ...CsvOptions) er } if option.TagKey == "" { - option.TagKey = "csv" + option.TagKey = DefaultTagKey } // Generate the header. diff --git a/load.go b/load.go index abcb2c8..962d63c 100644 --- a/load.go +++ b/load.go @@ -39,7 +39,7 @@ func LoadFromReader(file io.Reader, destination interface{}, options ...CsvOptio } if option.TagKey == "" { - option.TagKey = "csv" + option.TagKey = DefaultTagKey } header, content, err := readFile(file, option.Separator, option.Header) From af7dbba596d05deeef6382886bf1de3d615fe4ac Mon Sep 17 00:00:00 2001 From: Andy Bartelsmeier Date: Thu, 18 Jan 2024 21:02:55 +0000 Subject: [PATCH 3/4] feat: add tag key info to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9a2ff72..b68d81d 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ err := csvtag.LoadFromPath( csvtag.CsvOptions{ // Load your csv with optional options Separator: ';', // changes the values separator, default to ',' Header: []string{"name", "ID", "number"}, // specify custom headers + TagKey: "csv", // specify a custom tag key, default is 'csv' }) ``` From 7e49b376509c5cea5de2f8afe1cf0debe0fb9e43 Mon Sep 17 00:00:00 2001 From: Andy Bartelsmeier Date: Thu, 18 Jan 2024 21:04:46 +0000 Subject: [PATCH 4/4] feat: more consistent readme wording --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b68d81d..bf73eb3 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ err := csvtag.LoadFromPath( csvtag.CsvOptions{ // Load your csv with optional options Separator: ';', // changes the values separator, default to ',' Header: []string{"name", "ID", "number"}, // specify custom headers - TagKey: "csv", // specify a custom tag key, default is 'csv' + TagKey: "csv", // specify a custom tag key, default to 'csv' }) ```