json_p3 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +6 -0
- data/lib/json_p3/filter.rb +36 -3
- data/lib/json_p3/lexer.rb +1 -1
- data/lib/json_p3/node.rb +3 -1
- data/lib/json_p3/selector.rb +1 -1
- data/lib/json_p3/serialize.rb +13 -0
- data/lib/json_p3/version.rb +1 -1
- data/sig/json_p3.rbs +13 -7
- data.tar.gz.sig +0 -0
- metadata +5 -3
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: afd5de1be45132d6071616dc7aa21425dc3d9beaed525315f017b343b434a42f
|
4
|
+
data.tar.gz: 19f0fc51ac0f8680e47808beda7f206ea9d911b33ebebaccb5803cd7bcd012c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c6458e2fc86fa09988edbc032ad434cca4125f1d6a368e2f8e37e79e65b80fb404d12a3ec9dfb42ef007dbfc2977a4492814c9a8d689900921e2cfa885b6c11
|
7
|
+
data.tar.gz: 54580931a9a37165dcbb10f8a240c8142a8de013cbc9e76776f59a5f60b43743f98db65daae7d85968d61a6eda1983df26f9ae8d8aaf1571b3a45106236a8ed1
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.3.6
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
## [0.3.2] - 2025-01-29
|
2
|
+
|
3
|
+
- Fix normalized string representations of node locations as returned by `JSONPathNode.path`.
|
4
|
+
- Fix canonical string representations of instances of `JSONPath`, as returned by `to_s`.
|
5
|
+
- Fixed filter queries with multiple bracketed segments. Previously we were failing to tokenize queries like `$[?@[0][0]]`. See [#15](https://github.com/jg-rp/ruby-json-p3/issues/15).
|
6
|
+
|
1
7
|
## [0.3.1] - 2024-12-05
|
2
8
|
|
3
9
|
- Fix JSON Patch `move` and `copy` operations when using the special JSON Pointer token `-`.
|
data/lib/json_p3/filter.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "json"
|
4
3
|
require_relative "function"
|
4
|
+
require_relative "serialize"
|
5
5
|
|
6
6
|
module JSONP3 # rubocop:disable Style/Documentation
|
7
7
|
# Base class for all filter expression nodes.
|
@@ -33,7 +33,7 @@ module JSONP3 # rubocop:disable Style/Documentation
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def to_s
|
36
|
-
@expression
|
36
|
+
to_canonical_string(@expression, Precedence::LOWEST)
|
37
37
|
end
|
38
38
|
|
39
39
|
def ==(other)
|
@@ -47,6 +47,39 @@ module JSONP3 # rubocop:disable Style/Documentation
|
|
47
47
|
def hash
|
48
48
|
[@expression, @token].hash
|
49
49
|
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
class Precedence
|
54
|
+
LOWEST = 1
|
55
|
+
LOGICAL_OR = 3
|
56
|
+
LOGICAL_AND = 4
|
57
|
+
PREFIX = 7
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_canonical_string(expression, parent_precedence)
|
61
|
+
if expression.instance_of? LogicalAndExpression
|
62
|
+
left = to_canonical_string(expression.left, Precedence::LOGICAL_AND)
|
63
|
+
right = to_canonical_string(expression.right, Precedence::LOGICAL_AND)
|
64
|
+
expr = "#{left} && #{right}"
|
65
|
+
return parent_precedence >= Precedence::LOGICAL_AND ? "(#{expr})" : expr
|
66
|
+
end
|
67
|
+
|
68
|
+
if expression.instance_of? LogicalOrExpression
|
69
|
+
left = to_canonical_string(expression.left, Precedence::LOGICAL_OR)
|
70
|
+
right = to_canonical_string(expression.right, Precedence::LOGICAL_OR)
|
71
|
+
expr = "#{left} || #{right}"
|
72
|
+
return parent_precedence >= Precedence::LOGICAL_OR ? "(#{expr})" : expr
|
73
|
+
end
|
74
|
+
|
75
|
+
if expression.instance_of? LogicalNotExpression
|
76
|
+
operand = to_canonical_string(expression.expression, Precedence::PREFIX)
|
77
|
+
expr = "!#{operand}"
|
78
|
+
return parent_precedence > Precedence::PREFIX ? `(#{expr})` : expr
|
79
|
+
end
|
80
|
+
|
81
|
+
expression.to_s
|
82
|
+
end
|
50
83
|
end
|
51
84
|
|
52
85
|
# Base class for expression literals.
|
@@ -85,7 +118,7 @@ module JSONP3 # rubocop:disable Style/Documentation
|
|
85
118
|
# A double or single quoted string literal.
|
86
119
|
class StringLiteral < FilterExpressionLiteral
|
87
120
|
def to_s
|
88
|
-
|
121
|
+
JSONP3.canonical_string(@value)
|
89
122
|
end
|
90
123
|
end
|
91
124
|
|
data/lib/json_p3/lexer.rb
CHANGED
@@ -209,7 +209,7 @@ module JSONP3 # rubocop:disable Style/Documentation
|
|
209
209
|
case c
|
210
210
|
when "]"
|
211
211
|
emit(:token_rbracket, "]")
|
212
|
-
return
|
212
|
+
return :lex_segment
|
213
213
|
when ""
|
214
214
|
error "unclosed bracketed selection"
|
215
215
|
return nil
|
data/lib/json_p3/node.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "serialize"
|
4
|
+
|
3
5
|
module JSONP3
|
4
6
|
# A JSON-like value and its location.
|
5
7
|
class JSONPathNode
|
@@ -19,7 +21,7 @@ module JSONP3
|
|
19
21
|
# Return the normalized path to this node.
|
20
22
|
# @return [String] the normalized path.
|
21
23
|
def path
|
22
|
-
segments = @location.flatten.map { |i| i.is_a?(String) ? "[
|
24
|
+
segments = @location.flatten.map { |i| i.is_a?(String) ? "[#{JSONP3.canonical_string(i)}]" : "[#{i}]" }
|
23
25
|
"$#{segments.join}"
|
24
26
|
end
|
25
27
|
|
data/lib/json_p3/selector.rb
CHANGED
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
module JSONP3 # rubocop:disable Style/Documentation
|
6
|
+
TRANS = { "\\\"" => "\"", "'" => "\\'" }.freeze
|
7
|
+
|
8
|
+
# Return _value_ formatted as a canonical string literal.
|
9
|
+
# @param value [String]
|
10
|
+
def self.canonical_string(value)
|
11
|
+
"'#{(JSON.dump(value)[1..-2] || raise).gsub(/('|\\")/, TRANS)}'"
|
12
|
+
end
|
13
|
+
end
|
data/lib/json_p3/version.rb
CHANGED
data/sig/json_p3.rbs
CHANGED
@@ -126,7 +126,7 @@ module JSONP3
|
|
126
126
|
|
127
127
|
def initialize: (Token token) -> void
|
128
128
|
|
129
|
-
# Evaluate the filter
|
129
|
+
# Evaluate the filter expression in the given context.
|
130
130
|
def evaluate: (FilterContext _context) -> untyped
|
131
131
|
end
|
132
132
|
|
@@ -147,6 +147,10 @@ module JSONP3
|
|
147
147
|
alias eql? ==
|
148
148
|
|
149
149
|
def hash: () -> Integer
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
def to_canonical_string: (Expression expression, Integer parent_precedence) -> String
|
150
154
|
end
|
151
155
|
|
152
156
|
# Base class for expression literals.
|
@@ -394,7 +398,7 @@ module JSONP3
|
|
394
398
|
# @return [Array<Token>]
|
395
399
|
def self.tokenize: (String query) -> Array[Token]
|
396
400
|
|
397
|
-
# JSONPath query
|
401
|
+
# JSONPath query expression lexical scanner.
|
398
402
|
#
|
399
403
|
# @see tokenize
|
400
404
|
class Lexer
|
@@ -428,7 +432,7 @@ module JSONP3
|
|
428
432
|
# Generate a new token with the given type.
|
429
433
|
# @param token_type [Symbol] one of the constants defined on the _Token_ class.
|
430
434
|
# @param value [String | nil] a the token's value, if it is known, otherwise the
|
431
|
-
# value will be sliced from @query. This is a performance
|
435
|
+
# value will be sliced from @query. This is a performance optimization.
|
432
436
|
def emit: (token_t token_type, ?untyped value) -> void
|
433
437
|
|
434
438
|
def next: () -> String
|
@@ -488,7 +492,7 @@ module JSONP3
|
|
488
492
|
|
489
493
|
# @param value [JSON-like] the value at this node.
|
490
494
|
# @param location [Array<String | Integer | Array<String | Integer>>] the sequence of
|
491
|
-
# names and/or
|
495
|
+
# names and/or indices leading to _value_ in _root_.
|
492
496
|
# @param root [JSON-like] the root value containing _value_ at _location_.
|
493
497
|
def initialize: (untyped value, Array[location_element] location, untyped root) -> void
|
494
498
|
|
@@ -498,7 +502,7 @@ module JSONP3
|
|
498
502
|
|
499
503
|
# Return a new node that is a child of this node.
|
500
504
|
# @param value the JSON-like value at the new node.
|
501
|
-
# @param key [Integer, String] the array index or hash key
|
505
|
+
# @param key [Integer, String] the array index or hash key associated with _value_.
|
502
506
|
def new_child: (untyped value, String | Integer key) -> JSONPathNode
|
503
507
|
|
504
508
|
def to_s: () -> ::String
|
@@ -926,7 +930,7 @@ module JSONP3
|
|
926
930
|
# @param value [String]
|
927
931
|
# @param quote [String] one of '"' or "'".
|
928
932
|
# @param token [Token]
|
929
|
-
# @return [String] A new string without escape
|
933
|
+
# @return [String] A new string without escape sequences.
|
930
934
|
def self.unescape_string: (String value, String quote, Token token) -> String
|
931
935
|
|
932
936
|
def self.decode_hex_char: (untyped value, untyped index, Token token) -> ::Array[untyped]
|
@@ -938,6 +942,8 @@ module JSONP3
|
|
938
942
|
def self.low_surrogate?: (untyped code_point) -> untyped
|
939
943
|
|
940
944
|
def self.code_point_to_string: (untyped code_point, Token token) -> untyped
|
945
|
+
|
946
|
+
def self.canonical_string: (untyped String) -> ::String
|
941
947
|
end
|
942
948
|
|
943
949
|
module JSONP3
|
@@ -1162,7 +1168,7 @@ module JSONP3
|
|
1162
1168
|
class OpRemove < Op
|
1163
1169
|
@pointer: JSONPointer
|
1164
1170
|
|
1165
|
-
# @param
|
1171
|
+
# @param pointer [JSONPointer]
|
1166
1172
|
def initialize: (JSONPointer pointer) -> void
|
1167
1173
|
|
1168
1174
|
def name: () -> "remove"
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json_p3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Prior
|
@@ -36,7 +36,7 @@ cert_chain:
|
|
36
36
|
6dM18fnfBc3yA4KI7AO8UAmRkTscMYV6f/K4YZR6ZYCNWRpY7rkg+arhf05aoSQf
|
37
37
|
vn9bO1bzwdnG
|
38
38
|
-----END CERTIFICATE-----
|
39
|
-
date:
|
39
|
+
date: 2025-01-29 00:00:00.000000000 Z
|
40
40
|
dependencies: []
|
41
41
|
description: JSONPath following RFC 9535
|
42
42
|
email:
|
@@ -46,6 +46,7 @@ extensions: []
|
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
48
|
- ".rubocop.yml"
|
49
|
+
- ".ruby-version"
|
49
50
|
- ".yardopts"
|
50
51
|
- CHANGELOG.md
|
51
52
|
- LICENCE
|
@@ -73,6 +74,7 @@ files:
|
|
73
74
|
- lib/json_p3/pointer.rb
|
74
75
|
- lib/json_p3/segment.rb
|
75
76
|
- lib/json_p3/selector.rb
|
77
|
+
- lib/json_p3/serialize.rb
|
76
78
|
- lib/json_p3/token.rb
|
77
79
|
- lib/json_p3/unescape.rb
|
78
80
|
- lib/json_p3/version.rb
|
@@ -106,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
108
|
- !ruby/object:Gem::Version
|
107
109
|
version: '0'
|
108
110
|
requirements: []
|
109
|
-
rubygems_version: 3.
|
111
|
+
rubygems_version: 3.5.22
|
110
112
|
signing_key:
|
111
113
|
specification_version: 4
|
112
114
|
summary: 'JSONPath: Query Expressions for JSON in Ruby'
|
metadata.gz.sig
CHANGED
Binary file
|