Skip to content

Commit

Permalink
Merge pull request #6 from intelligentpos/feature/tag_mappings
Browse files Browse the repository at this point in the history
Implemented TagMapping
  • Loading branch information
geototti21 authored Oct 16, 2017
2 parents c9a6e52 + b7fa4f2 commit f54f423
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 0 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ go get github.com/intelligentpos/structextract
//FieldValueFromTagMap will return a map of tag value to value, map[string]interface{}
//{"field1":"value 1","field2":"value 2","field3":true,"field4":123}
tagmap, _ := extract.FieldValueFromTagMap("json")

// Mapping between different tags
//{"field1":"field_1_db","field2":"field_2_db","field3":"field_3_db"}
mapping, _ := extract.TagMapping("json", "db")


```
#### Ignore Fields
Expand Down
26 changes: 26 additions & 0 deletions extract.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,32 @@ func (e *Extractor) FieldValueFromTagMap(tag string) (out map[string]interface{}
return
}

// TagMapping returns a map that maps tagged fields from one tag to another.
// This can help with mapping partial JSON objects to some other kind of a
// mapping, such as SQL. It only maps existing field pairs, if either field
// does not have a tag, it's left out.
func (e *Extractor) TagMapping(from, to string) (out map[string]string, err error) {
if err := e.isValidStruct(); err != nil {
return nil, err
}

out = make(map[string]string)
s := reflect.ValueOf(e.StructAddr).Elem()
for i := 0; i < s.NumField(); i++ {
if isIgnored(s.Type().Field(i).Name, e.ignoredFields) {
continue
}

fromTag, fromOk := s.Type().Field(i).Tag.Lookup(from)
toTag, toOk := s.Type().Field(i).Tag.Lookup(to)
if toOk && fromOk {
out[fromTag] = toTag
}
}

return
}

// IgnoreField checks if the given fields are valid based on the given struct,
// then append them on the ignore list
// e.g. ext := structextract.New(&business).IgnoreField("ID","DateModified")
Expand Down
75 changes: 75 additions & 0 deletions extract_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,3 +358,78 @@ func TestExtractor_IgnoreField_NotValidField(t *testing.T) {
t.Fatalf("unexpected struct")
}
}

func TestTagMapping(t *testing.T) {
type test struct {
FieldA string `json:"fieldA" sql:"field_a"`
FieldB string `json:"fieldB" sql:"field_b"`
FieldC string `sql:"field_c"`
FieldD string `json:"fieldD"`
}

ext := New(&test{})
expected := map[string]string{
"fieldA": "field_a",
"fieldB": "field_b",
}

mapping, err := ext.TagMapping("json", "sql")
if err != nil {
t.Fatalf("encountered error (%s) whilst mapping tagged fields", err)
}

for k, v := range expected {
value, ok := mapping[k]
if !ok {
t.Errorf("mapping for key %s not found", k)
continue
}
if value != v {
t.Errorf("expected mapping mapping to be %s -> %s, got %s -> %s", k, v, k, value)
}
}

}

func TestTagMapping_ignoredFields(t *testing.T) {
type test struct {
FieldA string `json:"fieldA" sql:"field_a"`
FieldB string `json:"fieldB" sql:"field_b"`
FieldC string `sql:"field_c"`
FieldD string `json:"fieldD"`
}

ext := New(&test{}).IgnoreField("FieldA")
expected := map[string]string{
"fieldB": "field_b",
}

mapping, err := ext.TagMapping("json", "sql")
if err != nil {
t.Fatalf("encountered error (%s) whilst mapping tagged fields", err)
}

for k, v := range expected {
value, ok := mapping[k]
if !ok {
t.Errorf("mapping for key %s not found", k)
continue
}
if value != v {
t.Errorf("expected mapping mapping to be %s -> %s, got %s -> %s", k, v, k, value)
}
}

}

func TestTagMapping_invalidStruct(t *testing.T) {
type test struct {
Field string
}

ext := New(test{})
_, err := ext.TagMapping("json", "sql")
if err == nil {
t.Fatal("Passed value is not a valid struct")
}
}

0 comments on commit f54f423

Please sign in to comment.