Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ linters:
- testpackage
- varnamelen
- wsl
- wsl_v5
- noinlineerr
settings:
dupword:
ignore:
Expand Down
25 changes: 24 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,30 @@ All notable changes to this project will be documented in this file. It uses the
[Semantic Versioning]: https://semver.org/spec/v2.0.0.html
"Semantic Versioning 2.0.0"

## [v0.9.0] — Unreleased
## [v0.10.0] — Unreleased

### ⚡ Improvements

* Added text and binary encoding interface methods to `Path`:
* [encoding.TextMarshaler]
* [encoding.TextUnmarshaler]
* [encoding.BinaryMarshaler]
* [encoding.BinaryUnmarshaler]
Thanks to @rkosegi for the suggestion ([#20])

### 📔 Notes

* Upgraded to `golangci-lint` v2.2.2.

[v0.10.0]: https://github.com/theory/jsonpath/compare/v0.9.0...v0.10.0
[encoding.TextMarshaler]: https://pkg.go.dev/encoding#TextMarshaler
[encoding.TextUnmarshaler]: https://pkg.go.dev/encoding#TextUnmarshaler
[encoding.BinaryMarshaler]: https://pkg.go.dev/encoding#BinaryMarshaler
[encoding.BinaryUnmarshaler]: https://pkg.go.dev/encoding#BinaryUnmarshaler
[#20]: https://github.com/theory/jsonpath/issues/20
"theory/jsonpath#20: Implement encoding.TextUnmarshaler in Path"

## [v0.9.0] — 2025-05-05

### ⚡ Improvements

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ brew-lint-depends:

.PHONY: debian-lint-depends # Install linting tools on Debian
debian-lint-depends:
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sudo sh -s -- -b /usr/bin v2.1.5
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sudo sh -s -- -b /usr/bin v2.2.2

.PHONY: install-generators # Install Go code generators
install-generators:
Expand Down
29 changes: 29 additions & 0 deletions path.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,35 @@ func MustParse(path string) *Path {
return NewParser().MustParse(path)
}

// MarshalText encodes p into UTF-8-encoded text and returns the result.
// Implements [encoding.TextMarshaler].
func (p *Path) MarshalText() ([]byte, error) {
return []byte(p.q.String()), nil
}

// UnmarshalText decodes UTF-8-encoded text into p. Implements
// [encoding.TextUnmarshaler].
func (p *Path) UnmarshalText(data []byte) error {
parsed, err := NewParser().Parse(string(data))
if err != nil {
return err
}
p.q = parsed.q
return nil
}

// MarshalBinary encodes p into UTF-8-encoded bytes and returns the result.
// Implements [encoding.BinaryMarshaler].
func (p *Path) MarshalBinary() ([]byte, error) {
return p.MarshalText()
}

// UnmarshalBinary decodes UTF-8-encoded bytes into p. Implements
// [encoding.BinaryUnmarshaler].
func (p *Path) UnmarshalBinary(data []byte) error {
return p.UnmarshalText(data)
}

// String returns a string representation of p.
func (p *Path) String() string {
return p.q.String()
Expand Down
42 changes: 42 additions & 0 deletions path_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package jsonpath

import (
"encoding"
"encoding/json"
"fmt"
"os"
Expand All @@ -21,6 +22,7 @@ func book(idx int) spec.NormalizedPath {
func TestParseSpecExamples(t *testing.T) {
t.Parallel()
a := assert.New(t)
r := require.New(t)
val := specExampleJSON(t)
store, _ := val["store"].(map[string]any)
books, _ := store["book"].([]any)
Expand Down Expand Up @@ -126,9 +128,35 @@ func TestParseSpecExamples(t *testing.T) {
} {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()

// Test parsing.
p := MustParse(tc.path)
a.Equal(p.q, p.Query())
a.Equal(p.q.String(), p.String())

// Test text encoding.
a.Implements((*encoding.TextMarshaler)(nil), p)
a.Implements((*encoding.TextUnmarshaler)(nil), p)
text, err := p.MarshalText()
r.NoError(err)
a.Equal(p.q.String(), string(text))
p.q = nil
r.NoError(p.UnmarshalText(text))
a.Equal(p.q, p.Query())
a.Equal(p.q.String(), p.String())

// Test binary encoding.
a.Implements((*encoding.BinaryMarshaler)(nil), p)
a.Implements((*encoding.BinaryUnmarshaler)(nil), p)
data, err := p.MarshalBinary()
r.NoError(err)
a.Equal(p.q.String(), string(data))
p.q = nil
r.NoError(p.UnmarshalBinary(text))
a.Equal(p.q, p.Query())
a.Equal(p.q.String(), p.String())

// Test execution.
res := p.Select(val)
loc := p.SelectLocated(val)

Expand Down Expand Up @@ -333,6 +361,20 @@ func TestParser(t *testing.T) {
a.PanicsWithError(tc.err, func() { parser.MustParse(tc.path) })
}
}

// Test text and binary decoding.
if tc.err == "" {
p = &Path{}
r.NoError(p.UnmarshalText([]byte(tc.path)))
a.Equal(tc.exp, p)
p = &Path{}
r.NoError(p.UnmarshalBinary([]byte(tc.path)))
a.Equal(tc.exp, p)
} else {
p = &Path{}
r.EqualError(p.UnmarshalText([]byte(tc.path)), tc.err)
r.EqualError(p.UnmarshalBinary([]byte(tc.path)), tc.err)
}
})
}
}
Expand Down
Loading