fixed key location

This commit is contained in:
Andrew Nester 2024-10-11 14:41:59 +02:00
parent d25d95b70c
commit d4a334696e
No known key found for this signature in database
GPG Key ID: 12BC628A44B7DA57
4 changed files with 19 additions and 5 deletions

View File

@ -34,7 +34,12 @@ func decodeValue(decoder *json.Decoder, o *Offset) (dyn.Value, error) {
return dyn.InvalidValue, err return dyn.InvalidValue, err
} }
// Get the current byte offset // Get the current byte offset and the location.
// We will later use this location to store the location of the value in the file
// For objects and arrays, we will store the location of the opening '{' or '['
// For primitive types, we will store the location of the value itself (end of the value)
// We can't reliably calculate the beginning of the value for primitive types because
// the decoder doesn't provide the offset of the beginning of the value and the value might or might not be quoted.
offset := decoder.InputOffset() offset := decoder.InputOffset()
location := o.GetPosition(offset) location := o.GetPosition(offset)
@ -54,7 +59,10 @@ func decodeValue(decoder *json.Decoder, o *Offset) (dyn.Value, error) {
return invalidValueWithLocation(decoder, o), fmt.Errorf("expected string for object key") return invalidValueWithLocation(decoder, o), fmt.Errorf("expected string for object key")
} }
keyVal := dyn.NewValue(key, []dyn.Location{o.GetPosition(decoder.InputOffset())}) // Get the offset of the key by subtracting the length of the key and the '"' character
keyOffset := decoder.InputOffset() - int64(len(key)+1)
keyVal := dyn.NewValue(key, []dyn.Location{o.GetPosition(keyOffset)})
// Decode the value recursively // Decode the value recursively
val, err := decodeValue(decoder, o) val, err := decodeValue(decoder, o)
if err != nil { if err != nil {
@ -85,7 +93,6 @@ func decodeValue(decoder *json.Decoder, o *Offset) (dyn.Value, error) {
return dyn.NewValue(arr, []dyn.Location{location}), nil return dyn.NewValue(arr, []dyn.Location{location}), nil
} }
default: default:
// Primitive types: string, number, bool, or null
return dyn.NewValue(tok, []dyn.Location{location}), nil return dyn.NewValue(tok, []dyn.Location{location}), nil
} }

View File

@ -91,8 +91,11 @@ func (p Path) HasPrefix(q Path) bool {
// String returns a string representation of the path. // String returns a string representation of the path.
func (p Path) String() string { func (p Path) String() string {
var buf bytes.Buffer if len(p) == 0 {
return "."
}
var buf bytes.Buffer
for i, c := range p { for i, c := range p {
if i > 0 && c.key != "" { if i > 0 && c.key != "" {
buf.WriteRune('.') buf.WriteRune('.')

View File

@ -72,3 +72,7 @@ func TestPathString(t *testing.T) {
p3 := dyn.NewPath(dyn.Key("foo"), dyn.Index(1), dyn.Key("bar"), dyn.Index(2), dyn.Key("baz")) p3 := dyn.NewPath(dyn.Key("foo"), dyn.Index(1), dyn.Key("bar"), dyn.Index(2), dyn.Key("baz"))
assert.Equal(t, "foo[1].bar[2].baz", p3.String()) assert.Equal(t, "foo[1].bar[2].baz", p3.String())
} }
func TestPathStringEmpty(t *testing.T) {
assert.Equal(t, ".", dyn.EmptyPath.String())
}

View File

@ -182,7 +182,7 @@ func TestJsonUnmarshalRequestMismatch(t *testing.T) {
{ {
File: "(inline)", File: "(inline)",
Line: 3, Line: 3,
Column: 15, Column: 6,
}, },
}, },
Paths: []dyn.Path{{}}, Paths: []dyn.Path{{}},