From d4a334696ebab6b9ad036358cfec15e4922b30f9 Mon Sep 17 00:00:00 2001 From: Andrew Nester Date: Fri, 11 Oct 2024 14:41:59 +0200 Subject: [PATCH] fixed key location --- libs/dyn/jsonloader/json.go | 13 ++++++++++--- libs/dyn/path.go | 5 ++++- libs/dyn/path_test.go | 4 ++++ libs/flags/json_flag_test.go | 2 +- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/libs/dyn/jsonloader/json.go b/libs/dyn/jsonloader/json.go index ee2d110f6..e30e722f7 100644 --- a/libs/dyn/jsonloader/json.go +++ b/libs/dyn/jsonloader/json.go @@ -34,7 +34,12 @@ func decodeValue(decoder *json.Decoder, o *Offset) (dyn.Value, error) { 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() 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") } - 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 val, err := decodeValue(decoder, o) 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 } default: - // Primitive types: string, number, bool, or null return dyn.NewValue(tok, []dyn.Location{location}), nil } diff --git a/libs/dyn/path.go b/libs/dyn/path.go index 76377e2dc..ec12d322c 100644 --- a/libs/dyn/path.go +++ b/libs/dyn/path.go @@ -91,8 +91,11 @@ func (p Path) HasPrefix(q Path) bool { // String returns a string representation of the path. func (p Path) String() string { - var buf bytes.Buffer + if len(p) == 0 { + return "." + } + var buf bytes.Buffer for i, c := range p { if i > 0 && c.key != "" { buf.WriteRune('.') diff --git a/libs/dyn/path_test.go b/libs/dyn/path_test.go index 44df2050b..d55e16ebb 100644 --- a/libs/dyn/path_test.go +++ b/libs/dyn/path_test.go @@ -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")) assert.Equal(t, "foo[1].bar[2].baz", p3.String()) } + +func TestPathStringEmpty(t *testing.T) { + assert.Equal(t, ".", dyn.EmptyPath.String()) +} diff --git a/libs/flags/json_flag_test.go b/libs/flags/json_flag_test.go index 8b783bf90..2cc9cfd9b 100644 --- a/libs/flags/json_flag_test.go +++ b/libs/flags/json_flag_test.go @@ -182,7 +182,7 @@ func TestJsonUnmarshalRequestMismatch(t *testing.T) { { File: "(inline)", Line: 3, - Column: 15, + Column: 6, }, }, Paths: []dyn.Path{{}},