diff --git a/get.go b/get.go index a57f3a5..8c1ffba 100644 --- a/get.go +++ b/get.go @@ -42,6 +42,10 @@ func (v *V) getFromObjectChildren(key string) (child *V, exist bool) { return child, true } + if v.children.lowerCaseKeys == nil { + return nil, false + } + lowerCaseKey := strings.ToLower(key) keys, exist := v.children.lowerCaseKeys[lowerCaseKey] if !exist { diff --git a/get_test.go b/get_test.go index 4a3f4d7..3a863d2 100644 --- a/get_test.go +++ b/get_test.go @@ -51,7 +51,7 @@ func TestGet(t *testing.T) { check(t, err, "GetInt32", i == -1234) } { - i, err := o.GetInt32("data", "negATive") // caseless + i, err := o.Caseless().GetInt32("data", "negATive") // caseless check(t, err, "GetInt32_caseless", i == -1234) } { diff --git a/insert_append_delete_test.go b/insert_append_delete_test.go index 85eabca..db96ff5 100644 --- a/insert_append_delete_test.go +++ b/insert_append_delete_test.go @@ -74,7 +74,7 @@ func TestDelete(t *testing.T) { return } - _, err = o.Get("object") + _, err = o.Caseless().Get("object") if err != nil { t.Errorf("unexpected error: %v", err) return diff --git a/jsonvalue.go b/jsonvalue.go index d4c9903..05de776 100644 --- a/jsonvalue.go +++ b/jsonvalue.go @@ -82,6 +82,7 @@ type children struct { // As official json package supports caseless key accessing, I decide to do it as well lowerCaseKeys map[string]map[string]struct{} + caseless bool } func new(t jsonparser.ValueType) *V { @@ -92,10 +93,9 @@ func new(t jsonparser.ValueType) *V { func newObject() *V { v := new(jsonparser.Object) - v.children = children{ - object: make(map[string]*V), - lowerCaseKeys: make(map[string]map[string]struct{}), - } + v.children.object = make(map[string]*V) + v.children.caseless = false + v.children.lowerCaseKeys = nil return v } @@ -106,6 +106,9 @@ func newArray() *V { } func (v *V) addCaselessKey(k string) { + if v.children.lowerCaseKeys == nil { + return + } lowerK := strings.ToLower(k) keys, exist := v.children.lowerCaseKeys[lowerK] if !exist { @@ -116,6 +119,9 @@ func (v *V) addCaselessKey(k string) { } func (v *V) delCaselessKey(k string) { + if v.children.lowerCaseKeys == nil { + return + } lowerK := strings.ToLower(k) keys, exist := v.children.lowerCaseKeys[lowerK] if !exist { @@ -912,3 +918,34 @@ func (v *V) bufArrChildren(buf *bytes.Buffer) { }) buf.WriteByte(']') } + +// Caseless mark current value to be caseless mode +func (v *V) Caseless() *V { + if v.children.caseless { + return v + } + + v.children.caseless = true + + switch v.valueType { + default: + return v + + case jsonparser.Array: + for _, child := range v.children.array { + child.Caseless() + } + return v + + case jsonparser.Object: + if v.children.lowerCaseKeys == nil { + v.children.lowerCaseKeys = make(map[string]map[string]struct{}, len(v.children.object)) + for k, child := range v.children.object { + child.Caseless() + v.addCaselessKey(k) + } + } + } + + return v +}