0
0
Fork 0

adding override for "json" in struct tags, tests

This commit is contained in:
rob mccoll 2016-10-25 10:42:40 -04:00
parent ef28c7f9e0
commit 43b5b36a19
3 changed files with 105 additions and 9 deletions

View File

@ -42,6 +42,9 @@ type DocumentMapping struct {
Properties map[string]*DocumentMapping `json:"properties,omitempty"`
Fields []*FieldMapping `json:"fields,omitempty"`
DefaultAnalyzer string `json:"default_analyzer"`
// StructTagKey overrides "json" when looking for field names in struct tags
StructTagKey string `json:"struct_tag_key,omitempty"`
}
func (dm *DocumentMapping) Validate(cache *registry.Cache) error {
@ -285,6 +288,11 @@ func (dm *DocumentMapping) UnmarshalJSON(data []byte) error {
if err != nil {
return err
}
case "struct_tag_key":
err := json.Unmarshal(v, &dm.StructTagKey)
if err != nil {
return err
}
default:
invalidKeys = append(invalidKeys, k)
}
@ -314,6 +322,12 @@ func (dm *DocumentMapping) defaultAnalyzerName(path []string) string {
}
func (dm *DocumentMapping) walkDocument(data interface{}, path []string, indexes []uint64, context *walkContext) {
// allow default "json" tag to be overriden
structTagKey := dm.StructTagKey
if structTagKey == "" {
structTagKey = "json"
}
val := reflect.ValueOf(data)
typ := val.Type()
switch typ.Kind() {
@ -335,15 +349,15 @@ func (dm *DocumentMapping) walkDocument(data interface{}, path []string, indexes
fieldName = ""
}
// if the field has a JSON name, prefer that
jsonTag := field.Tag.Get("json")
jsonFieldName := parseJSONTagName(jsonTag)
if jsonFieldName == "-" {
// if the field has a name under the specified tag, prefer that
tag := field.Tag.Get(structTagKey)
tagFieldName := parseTagName(tag)
if tagFieldName == "-" {
continue
}
// allow json tag to set field name to empty, only if anonymous
if field.Tag != "" && (jsonFieldName != "" || field.Anonymous) {
fieldName = jsonFieldName
// allow tag to set field name to empty, only if anonymous
if field.Tag != "" && (tagFieldName != "" || field.Anonymous) {
fieldName = tagFieldName
}
if val.Field(i).CanInterface() {

View File

@ -160,6 +160,88 @@ func TestMappingStructWithJSONTagsOneDisabled(t *testing.T) {
}
}
func TestMappingStructWithAlternateTags(t *testing.T) {
mapping := buildMapping()
mapping.(*IndexMappingImpl).DefaultMapping.StructTagKey = "bleve"
x := struct {
NoBLEVETag string
Name string `bleve:"name"`
}{
Name: "marty",
}
doc := document.NewDocument("1")
err := mapping.MapDocument(doc, x)
if err != nil {
t.Fatal(err)
}
foundBLEVEName := false
foundNoBLEVEName := false
count := 0
for _, f := range doc.Fields {
if f.Name() == "name" {
foundBLEVEName = true
}
if f.Name() == "NoBLEVETag" {
foundNoBLEVEName = true
}
count++
}
if !foundBLEVEName {
t.Errorf("expected to find field named 'name'")
}
if !foundNoBLEVEName {
t.Errorf("expected to find field named 'NoBLEVETag'")
}
if count != 2 {
t.Errorf("expected to find 2 find, found %d", count)
}
}
func TestMappingStructWithAlternateTagsTwoDisabled(t *testing.T) {
mapping := buildMapping()
mapping.(*IndexMappingImpl).DefaultMapping.StructTagKey = "bleve"
x := struct {
Name string `json:"-" bleve:"name"`
Title string `json:"-" bleve:"-"`
NoBLEVETag string `json:"-"`
Extra string `json:"extra" bleve:"-"`
}{
Name: "marty",
}
doc := document.NewDocument("1")
err := mapping.MapDocument(doc, x)
if err != nil {
t.Fatal(err)
}
foundBLEVEName := false
foundNoBLEVEName := false
count := 0
for _, f := range doc.Fields {
if f.Name() == "name" {
foundBLEVEName = true
}
if f.Name() == "NoBLEVETag" {
foundNoBLEVEName = true
}
count++
}
if !foundBLEVEName {
t.Errorf("expected to find field named 'name'")
}
if !foundNoBLEVEName {
t.Errorf("expected to find field named 'NoBLEVETag'")
}
if count != 2 {
t.Errorf("expected to find 2 find, found %d", count)
}
}
func TestMappingStructWithPointerToString(t *testing.T) {
mapping := buildMapping()

View File

@ -75,8 +75,8 @@ func mustString(data interface{}) (string, bool) {
return "", false
}
// parseJSONTagName extracts the JSON field name from a struct tag
func parseJSONTagName(tag string) string {
// parseTagName extracts the field name from a struct tag
func parseTagName(tag string) string {
if idx := strings.Index(tag, ","); idx != -1 {
return tag[:idx]
}