Skip to content

Commit

Permalink
New CsvOption - TagKey (#28)
Browse files Browse the repository at this point in the history
* feat: add tag key option

* feat: default tag key const

* feat: add tag key info to readme

* feat: more consistent readme wording
  • Loading branch information
abtmr authored Jan 19, 2024
1 parent f0066f9 commit 227d4c7
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 5 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 to 'csv'
})
```

Expand Down
3 changes: 3 additions & 0 deletions csvtag.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ package csvtag
type CsvOptions struct {
Separator rune
Header []string
TagKey string
}

const DefaultTagKey string = "csv"
21 changes: 21 additions & 0 deletions csvtag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
}
8 changes: 6 additions & 2 deletions dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,14 @@ func DumpToWriter(slice interface{}, writer io.Writer, options ...CsvOptions) er
option = options[0]
}

if option.TagKey == "" {
option.TagKey = DefaultTagKey
}

// 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)
}
Expand All @@ -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
Expand Down
4 changes: 4 additions & 0 deletions dump_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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},
}
Expand Down
10 changes: 7 additions & 3 deletions load.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ func LoadFromReader(file io.Reader, destination interface{}, options ...CsvOptio
option = options[0]
}

if option.TagKey == "" {
option.TagKey = DefaultTagKey
}

header, content, err := readFile(file, option.Separator, option.Header)
if err != nil {
return fmt.Errorf("error reading csv from io.Reader: %v", err)
Expand All @@ -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)
}
Expand Down Expand Up @@ -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")
}
Expand All @@ -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
}
Expand Down
6 changes: 6 additions & 0 deletions load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 227d4c7

Please sign in to comment.