Merge pull request #486 from robmccoll/feature/overridejsontag
adding override for "json" in struct tags, tests
This commit is contained in:
commit
f45584bf54
|
@ -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() {
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user