json_p3 0.3.2 → 0.4.0
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/.rubocop.yml +1 -1
- data/CHANGELOG.md +5 -0
- data/README.md +36 -3
- data/lib/json_p3/environment.rb +35 -0
- data/lib/json_p3/filter.rb +1 -1
- data/lib/json_p3/function_extensions/match.rb +1 -1
- data/lib/json_p3/parser.rb +2 -2
- data/lib/json_p3/path.rb +31 -1
- data/lib/json_p3/segment.rb +56 -0
- data/lib/json_p3/selector.rb +55 -34
- data/lib/json_p3/version.rb +1 -1
- data/lib/json_p3.rb +16 -0
- data/performance/benchmark_ips.rb +4 -0
- data/performance/benchmark_small_citylots.rb +8 -0
- data/sig/json_p3.rbs +54 -11
- data.tar.gz.sig +0 -0
- metadata +2 -2
- 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: db1ec71125b99bc877ba9856434a65e3f8e1c11a48b9566443c3b1a8b6860169
|
4
|
+
data.tar.gz: ad176fdda64b4f741e9f86ab48d4c8e3ccd767187fc0fc0fe28a4e6967a071d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b153a665f534891e1ed1976ca6c180cd1c2427786b9f7b74fcea1953d7337135db669b3541d5eaba7fd2829dbd6c94e6c36236a4a6c6221d1bd5c0ac45f5a04
|
7
|
+
data.tar.gz: 52303daa1cd27c3f3ed7187949f6b9a2cf2c95483e61cd8cf7ced438f5511ad9067f39496b1fe53a85932a3de2be15ebfa2c791fdbc9002aceb0c85395c04839
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## [0.4.0] - 2025-02-10
|
2
|
+
|
3
|
+
- Added `JSONP3.find_enum`, `JSONP3::JSONPathEnvironment.find_enum` and `JSONP3::JSONPath.find_enum`. `find_enum` is like `find`, but returns an Enumerable (usually an Enumerator) of `JSONPathNode` instances instead of a `JSONPathNodeList`. `find_enum` can be more efficient for some combinations of query and data, especially for large data and recursive queries.
|
4
|
+
- Added `JSONP3.match`, `JSONP3.match?`, `JSONP3.first` and equivalent methods for `JSONPathEnvironment` and `JSONPath`.
|
5
|
+
|
1
6
|
## [0.3.2] - 2025-01-29
|
2
7
|
|
3
8
|
- Fix normalized string representations of node locations as returned by `JSONPathNode.path`.
|
data/README.md
CHANGED
@@ -16,7 +16,7 @@ We follow <a href="https://datatracker.ietf.org/doc/html/rfc9535">RFC 9535</a> s
|
|
16
16
|
<img alt="Gem Version" src="https://img.shields.io/gem/v/json_p3?style=flat-square">
|
17
17
|
</a>
|
18
18
|
<a href="https://github.com/jg-rp/ruby-json-p3">
|
19
|
-
<img alt="Static Badge" src="https://img.shields.io/badge/Ruby-3.1%20%7C%203.2%20%7C%203.3-CC342D?style=flat-square">
|
19
|
+
<img alt="Static Badge" src="https://img.shields.io/badge/Ruby-3.1%20%7C%203.2%20%7C%203.3%20%7C%203.4-CC342D?style=flat-square">
|
20
20
|
</a>
|
21
21
|
</p>
|
22
22
|
|
@@ -47,7 +47,7 @@ gem install json_p3
|
|
47
47
|
|
48
48
|
### Checksum
|
49
49
|
|
50
|
-
JSON P3 is cryptographically signed. To be sure the gem you install hasn
|
50
|
+
JSON P3 is cryptographically signed. To be sure the gem you install hasn't been tampered with, add my public key (if you haven't already) as a trusted certificate:
|
51
51
|
|
52
52
|
```
|
53
53
|
gem cert --add <(curl -Ls https://raw.githubusercontent.com/jg-rp/ruby-json-p3/refs/heads/main/certs/jgrp.pem)
|
@@ -192,6 +192,23 @@ end
|
|
192
192
|
# {"name"=>"John", "score"=>86, "admin"=>true} at $['users'][2]
|
193
193
|
```
|
194
194
|
|
195
|
+
### find_enum
|
196
|
+
|
197
|
+
`find_enum(query, value) -> Enumerable<JSONPathNode>`
|
198
|
+
|
199
|
+
`find_enum` is an alternative to `find` which returns an enumerable (usually an enumerator) of `JSONPathNode` instances instead of an array. Depending on the query and the data the query is applied to, `find_enum` can be more efficient than `find`, especially for large data and queries using recursive descent segments.
|
200
|
+
|
201
|
+
```ruby
|
202
|
+
# ... continued from above
|
203
|
+
|
204
|
+
JSONP3.find_enum("$.users[?@.score > 85]", data).each do |node|
|
205
|
+
puts "#{node.value} at #{node.path}"
|
206
|
+
end
|
207
|
+
|
208
|
+
# {"name"=>"Sue", "score"=>100} at $['users'][0]
|
209
|
+
# {"name"=>"John", "score"=>86, "admin"=>true} at $['users'][2]
|
210
|
+
```
|
211
|
+
|
195
212
|
### compile
|
196
213
|
|
197
214
|
`compile(query) -> JSONPath`
|
@@ -238,14 +255,30 @@ end
|
|
238
255
|
# {"name"=>"John", "score"=>86, "admin"=>true} at $['users'][2]
|
239
256
|
```
|
240
257
|
|
258
|
+
### match / first
|
259
|
+
|
260
|
+
`match(query, value) -> JSONPathNode | nil`
|
261
|
+
|
262
|
+
`match` (alias `first`) returns a node for the first available match when applying _query_ to _value_, or `nil` if there were no matches.
|
263
|
+
|
264
|
+
### match?
|
265
|
+
|
266
|
+
`match?(query, value) -> bool`
|
267
|
+
|
268
|
+
`match?` returns `true` if there was at least one match from applying _query_ to _value_, or `false` otherwise.
|
269
|
+
|
241
270
|
### JSONPathEnvironment
|
242
271
|
|
243
|
-
The `find` and `compile` methods described above are convenience methods equivalent to
|
272
|
+
The `find`, `find_enum` and `compile` methods described above are convenience methods equivalent to:
|
244
273
|
|
245
274
|
```
|
246
275
|
JSONP3::DEFAULT_ENVIRONMENT.find(query, data)
|
247
276
|
```
|
248
277
|
|
278
|
+
```
|
279
|
+
JSONP3::DEFAULT_ENVIRONMENT.find_enum(query, data)
|
280
|
+
```
|
281
|
+
|
249
282
|
and
|
250
283
|
|
251
284
|
```
|
data/lib/json_p3/environment.rb
CHANGED
@@ -63,6 +63,41 @@ module JSONP3
|
|
63
63
|
compile(query).find(value)
|
64
64
|
end
|
65
65
|
|
66
|
+
# Apply JSONPath expression _query_ to _value_.
|
67
|
+
# @param query [String] the JSONPath expression
|
68
|
+
# @param value [JSON-like data] the target JSON "document"
|
69
|
+
# @return [Enumerable<JSONPath>]
|
70
|
+
def find_enum(query, value)
|
71
|
+
compile(query).find_enum(value)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Apply JSONPath expression _query_ to _value_ an return the first
|
75
|
+
# available node.
|
76
|
+
# @param query [String] the JSONPath expression
|
77
|
+
# @param value [JSON-like data] the target JSON "document"
|
78
|
+
# @return [JSONPathNode | nil]
|
79
|
+
def match(path, value)
|
80
|
+
find_enum(path, value).first
|
81
|
+
end
|
82
|
+
|
83
|
+
# Apply JSONPath expression _query_ to _value_ an return `true` if there's at
|
84
|
+
# least one node, or nil if there were no matches.
|
85
|
+
# @param query [String] the JSONPath expression
|
86
|
+
# @param value [JSON-like data] the target JSON "document"
|
87
|
+
# @return [bool]
|
88
|
+
def match?(path, value)
|
89
|
+
!find_enum(path, value).first.nil?
|
90
|
+
end
|
91
|
+
|
92
|
+
# Apply JSONPath expression _query_ to _value_ an return the first
|
93
|
+
# available node, or nil if there were no matches.
|
94
|
+
# @param query [String] the JSONPath expression
|
95
|
+
# @param value [JSON-like data] the target JSON "document"
|
96
|
+
# @return [JSONPathNode | nil]
|
97
|
+
def first(path, value)
|
98
|
+
find_enum(path, value).first
|
99
|
+
end
|
100
|
+
|
66
101
|
# Override this function to configure JSONPath function extensions.
|
67
102
|
# By default, only the standard functions described in RFC 9535 are enabled.
|
68
103
|
def setup_function_extensions
|
data/lib/json_p3/filter.rb
CHANGED
@@ -390,7 +390,7 @@ module JSONP3 # rubocop:disable Style/Documentation
|
|
390
390
|
# @param args [Array<Object>]
|
391
391
|
# @return [Array<Object>]
|
392
392
|
def unpack_node_lists(func, args)
|
393
|
-
unpacked_args = []
|
393
|
+
unpacked_args = [] # : Array[Object]
|
394
394
|
args.each_with_index do |arg, i|
|
395
395
|
unless arg.is_a?(JSONPathNodeList) && func.class::ARG_TYPES[i] != :nodes_expression
|
396
396
|
unpacked_args << arg
|
data/lib/json_p3/parser.rb
CHANGED
@@ -245,7 +245,7 @@ module JSONP3
|
|
245
245
|
FilterSelector.new(@env, token, FilterExpression.new(token, expression))
|
246
246
|
end
|
247
247
|
|
248
|
-
def parse_filter_expression(stream, precedence = Precedence::LOWEST)
|
248
|
+
def parse_filter_expression(stream, precedence = Precedence::LOWEST)
|
249
249
|
left = case stream.peek.type
|
250
250
|
when :token_double_quote_string, :token_single_quote_string
|
251
251
|
token = stream.next
|
@@ -477,7 +477,7 @@ module JSONP3
|
|
477
477
|
expression.token)
|
478
478
|
end
|
479
479
|
|
480
|
-
def validate_function_extension_signature(token, args)
|
480
|
+
def validate_function_extension_signature(token, args)
|
481
481
|
func = @env.function_extensions.fetch(token.value)
|
482
482
|
count = func.class::ARG_TYPES.length
|
483
483
|
|
data/lib/json_p3/path.rb
CHANGED
@@ -20,11 +20,41 @@ module JSONP3
|
|
20
20
|
def find(root)
|
21
21
|
nodes = [JSONPathNode.new(root, [], root)]
|
22
22
|
@segments.each { |segment| nodes = segment.resolve(nodes) }
|
23
|
-
JSONPathNodeList.new(nodes)
|
23
|
+
JSONPathNodeList.new(nodes) # TODO: use JSONPathNodeList internally?
|
24
24
|
end
|
25
25
|
|
26
26
|
alias apply find
|
27
27
|
|
28
|
+
# Apply this JSONPath expression to JSON-like value _root_.
|
29
|
+
# @param root [Array, Hash, String, Integer, nil] the root JSON-like value to apply this query to.
|
30
|
+
# @return [Enumerable<JSONPathNode>] the sequence of nodes found while applying this query to _root_.
|
31
|
+
def find_enum(root)
|
32
|
+
nodes = [JSONPathNode.new(root, [], root)] # : Enumerable[JSONPathNode]
|
33
|
+
@segments.each { |segment| nodes = segment.resolve_enum(nodes) }
|
34
|
+
nodes
|
35
|
+
end
|
36
|
+
|
37
|
+
# Return the first node from applying this JSONPath expression to JSON-like value _root_.
|
38
|
+
# @param root [Array, Hash, String, Integer, nil] the root JSON-like value to apply this query to.
|
39
|
+
# @return [JSONPathNode | nil] the first available node or nil if there were no matches.
|
40
|
+
def match(root)
|
41
|
+
find_enum(root).first
|
42
|
+
end
|
43
|
+
|
44
|
+
# Return `true` if this query results in at least one node, or `false` otherwise.
|
45
|
+
# @param root [Array, Hash, String, Integer, nil] the root JSON-like value to apply this query to.
|
46
|
+
# @return [bool] `true` if this query results in at least one node, or `false` otherwise.
|
47
|
+
def match?(root)
|
48
|
+
!find_enum(root).first.nil?
|
49
|
+
end
|
50
|
+
|
51
|
+
# Return the first node from applying this JSONPath expression to JSON-like value _root_.
|
52
|
+
# @param root [Array, Hash, String, Integer, nil] the root JSON-like value to apply this query to.
|
53
|
+
# @return [JSONPathNode | nil] the first available node or nil if there were no matches.
|
54
|
+
def first(root)
|
55
|
+
find_enum(root).first
|
56
|
+
end
|
57
|
+
|
28
58
|
# Return _true_ if this JSONPath expression is a singular query.
|
29
59
|
def singular?
|
30
60
|
@segments.each do |segment|
|
data/lib/json_p3/segment.rb
CHANGED
@@ -13,9 +13,16 @@ module JSONP3
|
|
13
13
|
end
|
14
14
|
|
15
15
|
# Select the children of each node in _nodes_.
|
16
|
+
# @return [Array<JSONPathNode>]
|
16
17
|
def resolve(_nodes)
|
17
18
|
raise "segments must implement resolve(nodes)"
|
18
19
|
end
|
20
|
+
|
21
|
+
# Select the children of each node in _nodes_.
|
22
|
+
# @return [Enumerable<JSONPathNode>]
|
23
|
+
def resolve_enum(_nodes)
|
24
|
+
raise "segments must implement resolve_enum(nodes)"
|
25
|
+
end
|
19
26
|
end
|
20
27
|
|
21
28
|
# The child selection segment.
|
@@ -30,6 +37,18 @@ module JSONP3
|
|
30
37
|
rv
|
31
38
|
end
|
32
39
|
|
40
|
+
def resolve_enum(nodes)
|
41
|
+
Enumerator.new do |yielder|
|
42
|
+
nodes.each do |node|
|
43
|
+
@selectors.each do |selector|
|
44
|
+
selector.resolve(node).each do |item|
|
45
|
+
yielder << item
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
33
52
|
def to_s
|
34
53
|
"[#{@selectors.map(&:to_s).join(", ")}]"
|
35
54
|
end
|
@@ -61,6 +80,20 @@ module JSONP3
|
|
61
80
|
rv
|
62
81
|
end
|
63
82
|
|
83
|
+
def resolve_enum(nodes)
|
84
|
+
Enumerator.new do |yielder|
|
85
|
+
nodes.each do |node|
|
86
|
+
visit_enum(node).each do |descendant|
|
87
|
+
@selectors.each do |selector|
|
88
|
+
selector.resolve(descendant).each do |item|
|
89
|
+
yielder << item
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
64
97
|
def to_s
|
65
98
|
"..[#{@selectors.map(&:to_s).join(", ")}]"
|
66
99
|
end
|
@@ -98,5 +131,28 @@ module JSONP3
|
|
98
131
|
|
99
132
|
rv
|
100
133
|
end
|
134
|
+
|
135
|
+
def visit_enum(node, depth = 1)
|
136
|
+
raise JSONPathRecursionError.new("recursion limit exceeded", @token) if depth > @env.class::MAX_RECURSION_DEPTH
|
137
|
+
|
138
|
+
Enumerator.new do |yielder|
|
139
|
+
yielder << node
|
140
|
+
if node.value.is_a? Array
|
141
|
+
node.value.each_with_index do |value, i|
|
142
|
+
child = JSONPathNode.new(value, [node.location, i], node.root)
|
143
|
+
visit_enum(child, depth + 1).each do |item|
|
144
|
+
yielder << item
|
145
|
+
end
|
146
|
+
end
|
147
|
+
elsif node.value.is_a? Hash
|
148
|
+
node.value.each do |key, value|
|
149
|
+
child = JSONPathNode.new(value, [node.location, key], node.root)
|
150
|
+
visit_enum(child, depth + 1).each do |item|
|
151
|
+
yielder << item
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
101
157
|
end
|
102
158
|
end
|
data/lib/json_p3/selector.rb
CHANGED
@@ -17,6 +17,12 @@ module JSONP3
|
|
17
17
|
raise "selectors must implement resolve(node)"
|
18
18
|
end
|
19
19
|
|
20
|
+
# Apply this selector to _node_.
|
21
|
+
# @return [Enumerable<JSONPathNode>]
|
22
|
+
def resolve_enum(node)
|
23
|
+
resolve(node)
|
24
|
+
end
|
25
|
+
|
20
26
|
# Return true if this selector is a singular selector.
|
21
27
|
def singular?
|
22
28
|
false
|
@@ -145,6 +151,24 @@ module JSONP3
|
|
145
151
|
end
|
146
152
|
end
|
147
153
|
|
154
|
+
def resolve_enum(node)
|
155
|
+
if node.value.is_a? Hash
|
156
|
+
Enumerator.new do |yielder|
|
157
|
+
node.value.each do |k, v|
|
158
|
+
yielder << node.new_child(v, k)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
elsif node.value.is_a? Array
|
162
|
+
Enumerator.new do |yielder|
|
163
|
+
node.value.each.with_index do |e, i|
|
164
|
+
yielder << node.new_child(e, i)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
else
|
168
|
+
[]
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
148
172
|
def to_s
|
149
173
|
"*"
|
150
174
|
end
|
@@ -178,24 +202,23 @@ module JSONP3
|
|
178
202
|
length = node.value.length
|
179
203
|
return [] if length.zero? || @step.zero?
|
180
204
|
|
181
|
-
|
182
|
-
|
205
|
+
normalized_start = if @start.nil?
|
206
|
+
@step.negative? ? length - 1 : 0
|
207
|
+
elsif @start&.negative?
|
208
|
+
[length + (@start || raise), 0].max
|
209
|
+
else
|
210
|
+
[@start || raise, length - 1].min
|
211
|
+
end
|
183
212
|
|
184
|
-
|
213
|
+
normalized_stop = if @stop.nil?
|
214
|
+
@step.negative? ? -1 : length
|
215
|
+
elsif @stop&.negative?
|
216
|
+
[length + (@stop || raise), -1].max
|
217
|
+
else
|
218
|
+
[@stop || raise, length].min
|
219
|
+
end
|
185
220
|
|
186
|
-
|
187
|
-
|
188
|
-
for i in (norm_start...norm_stop).step(@step) # rubocop:disable Style/For
|
189
|
-
nodes << node.new_child(node.value[i], i)
|
190
|
-
end
|
191
|
-
else
|
192
|
-
i = norm_start
|
193
|
-
while i > norm_stop
|
194
|
-
nodes << node.new_child(node.value[i], i)
|
195
|
-
i += @step
|
196
|
-
end
|
197
|
-
end
|
198
|
-
nodes
|
221
|
+
(normalized_start...normalized_stop).step(@step).map { |i| node.new_child(node.value[i], i) }
|
199
222
|
end
|
200
223
|
|
201
224
|
def to_s
|
@@ -218,24 +241,6 @@ module JSONP3
|
|
218
241
|
def hash
|
219
242
|
[@start, @stop, @step, @token].hash
|
220
243
|
end
|
221
|
-
|
222
|
-
private
|
223
|
-
|
224
|
-
def normalized_start(length)
|
225
|
-
# NOTE: trying to please the type checker :(
|
226
|
-
return @step.negative? ? length - 1 : 0 if @start.nil?
|
227
|
-
return [length + (@start || raise), 0].max if @start&.negative?
|
228
|
-
|
229
|
-
[@start || raise, length - 1].min
|
230
|
-
end
|
231
|
-
|
232
|
-
def normalized_stop(length)
|
233
|
-
# NOTE: trying to please the type checker :(
|
234
|
-
return @step.negative? ? -1 : length if @stop.nil?
|
235
|
-
return [length + (@stop || raise), -1].max if @stop&.negative?
|
236
|
-
|
237
|
-
[@stop || raise, length].min
|
238
|
-
end
|
239
244
|
end
|
240
245
|
|
241
246
|
# Select array elements or hash values according to a filter expression.
|
@@ -266,6 +271,22 @@ module JSONP3
|
|
266
271
|
nodes
|
267
272
|
end
|
268
273
|
|
274
|
+
def resolve_enum(node)
|
275
|
+
Enumerator.new do |yielder|
|
276
|
+
if node.value.is_a?(Array)
|
277
|
+
node.value.each_with_index do |e, i|
|
278
|
+
context = FilterContext.new(@env, e, node.root)
|
279
|
+
yielder << node.new_child(e, i) if @expression.evaluate(context)
|
280
|
+
end
|
281
|
+
elsif node.value.is_a?(Hash)
|
282
|
+
node.value.each_pair do |k, v|
|
283
|
+
context = FilterContext.new(@env, v, node.root)
|
284
|
+
yielder << node.new_child(v, k) if @expression.evaluate(context)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
269
290
|
def to_s
|
270
291
|
"?#{@expression}"
|
271
292
|
end
|
data/lib/json_p3/version.rb
CHANGED
data/lib/json_p3.rb
CHANGED
@@ -13,10 +13,26 @@ module JSONP3
|
|
13
13
|
DefaultEnvironment.find(path, data)
|
14
14
|
end
|
15
15
|
|
16
|
+
def self.find_enum(path, data)
|
17
|
+
DefaultEnvironment.find_enum(path, data)
|
18
|
+
end
|
19
|
+
|
16
20
|
def self.compile(path)
|
17
21
|
DefaultEnvironment.compile(path)
|
18
22
|
end
|
19
23
|
|
24
|
+
def self.match(path, data)
|
25
|
+
DefaultEnvironment.match(path, data)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.match?(path, data)
|
29
|
+
DefaultEnvironment.match?(path, data)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.first(path, data)
|
33
|
+
DefaultEnvironment.first(path, data)
|
34
|
+
end
|
35
|
+
|
20
36
|
def self.resolve(pointer, value, default: JSONPointer::UNDEFINED)
|
21
37
|
JSONPointer.new(pointer).resolve(value, default: default)
|
22
38
|
end
|
@@ -15,4 +15,12 @@ Benchmark.bm(15) do |x|
|
|
15
15
|
x.report("shallow:") do
|
16
16
|
JSONP3.find("$.features..properties", DATA)
|
17
17
|
end
|
18
|
+
|
19
|
+
x.report("enum deep:") do
|
20
|
+
JSONP3.find_enum("$.features..properties.BLOCK_NUM", DATA).to_a
|
21
|
+
end
|
22
|
+
|
23
|
+
x.report("enum shallow:") do
|
24
|
+
JSONP3.find_enum("$.features..properties", DATA).to_a
|
25
|
+
end
|
18
26
|
end
|
data/sig/json_p3.rbs
CHANGED
@@ -3,9 +3,17 @@ module JSONP3
|
|
3
3
|
DefaultEnvironment: JSONPathEnvironment
|
4
4
|
|
5
5
|
def self.find: (String path, untyped data) -> JSONPathNodeList
|
6
|
+
|
7
|
+
def self.find_enum: (String path, untyped data) -> Enumerable[JSONPathNode]
|
6
8
|
|
7
9
|
def self.compile: (String path) -> JSONPath
|
8
10
|
|
11
|
+
def self.match: (String path, untyped data) -> (JSONPathNode | nil)
|
12
|
+
|
13
|
+
def self.first: (String path, untyped data) -> (JSONPathNode | nil)
|
14
|
+
|
15
|
+
def self.match?: (String path, untyped data) -> bool
|
16
|
+
|
9
17
|
def self.resolve: (String pointer, untyped value, ?default: untyped) -> untyped
|
10
18
|
|
11
19
|
def self.apply: (Array[Op | Hash[String, untyped]] ops, untyped value) -> untyped
|
@@ -65,6 +73,14 @@ module JSONP3
|
|
65
73
|
# @param value [JSON-like data]
|
66
74
|
# @return [Array<JSONPath>]
|
67
75
|
def find: (String query, untyped value) -> JSONPathNodeList
|
76
|
+
|
77
|
+
def find_enum: (String query, untyped value) -> Enumerable[JSONPathNode]
|
78
|
+
|
79
|
+
def match: (String query, untyped value) -> (JSONPathNode | nil)
|
80
|
+
|
81
|
+
def match?: (String query, untyped value) -> bool
|
82
|
+
|
83
|
+
def first: (String query, untyped value) -> (JSONPathNode | nil)
|
68
84
|
|
69
85
|
def setup_function_extensions: () -> void
|
70
86
|
end
|
@@ -150,6 +166,16 @@ module JSONP3
|
|
150
166
|
|
151
167
|
private
|
152
168
|
|
169
|
+
class Precedence
|
170
|
+
LOWEST: 1
|
171
|
+
|
172
|
+
LOGICAL_OR: 3
|
173
|
+
|
174
|
+
LOGICAL_AND: 4
|
175
|
+
|
176
|
+
PREFIX: 7
|
177
|
+
end
|
178
|
+
|
153
179
|
def to_canonical_string: (Expression expression, Integer parent_precedence) -> String
|
154
180
|
end
|
155
181
|
|
@@ -626,7 +652,15 @@ module JSONP3
|
|
626
652
|
# Apply this JSONPath expression to JSON-like value _root_.
|
627
653
|
# @param root [Array, Hash, String, Integer] the root JSON-like value to apply this query to.
|
628
654
|
# @return [Array<JSONPathNode>] the sequence of nodes found while applying this query to _root_.
|
629
|
-
def find: (untyped root) ->
|
655
|
+
def find: (untyped root) -> JSONPathNodeList
|
656
|
+
|
657
|
+
def find_enum: (untyped root) -> Enumerable[JSONPathNode]
|
658
|
+
|
659
|
+
def match: (untyped root) -> (JSONPathNode | nil)
|
660
|
+
|
661
|
+
def match?: (untyped root) -> bool
|
662
|
+
|
663
|
+
def first: (untyped root) -> (JSONPathNode | nil)
|
630
664
|
|
631
665
|
alias apply find
|
632
666
|
|
@@ -657,11 +691,16 @@ module JSONP3
|
|
657
691
|
|
658
692
|
# Select the children of each node in _nodes_.
|
659
693
|
def resolve: (Array[JSONPathNode] _nodes) -> Array[JSONPathNode]
|
694
|
+
|
695
|
+
# Select the children of each node in _nodes_.
|
696
|
+
def resolve_enum: (Enumerable[JSONPathNode] _nodes) -> Enumerable[JSONPathNode]
|
660
697
|
end
|
661
698
|
|
662
699
|
# The child selection segment.
|
663
700
|
class ChildSegment < Segment
|
664
701
|
def resolve: (Array[JSONPathNode] nodes) -> Array[JSONPathNode]
|
702
|
+
|
703
|
+
def resolve_enum: (Enumerable[JSONPathNode] nodes) -> Enumerable[JSONPathNode]
|
665
704
|
|
666
705
|
def to_s: () -> ::String
|
667
706
|
|
@@ -675,6 +714,8 @@ module JSONP3
|
|
675
714
|
# The recursive descent segment
|
676
715
|
class RecursiveDescentSegment < Segment
|
677
716
|
def resolve: (Array[JSONPathNode] nodes) -> Array[JSONPathNode]
|
717
|
+
|
718
|
+
def resolve_enum: (Enumerable[JSONPathNode] nodes) -> Enumerable[JSONPathNode]
|
678
719
|
|
679
720
|
def to_s: () -> ::String
|
680
721
|
|
@@ -685,6 +726,7 @@ module JSONP3
|
|
685
726
|
def hash: () -> Integer
|
686
727
|
|
687
728
|
def visit: (JSONPathNode node, ?::Integer depth) -> Array[JSONPathNode]
|
729
|
+
def visit_enum: (JSONPathNode node, ?::Integer depth) -> Enumerable[JSONPathNode]
|
688
730
|
end
|
689
731
|
end
|
690
732
|
|
@@ -703,6 +745,7 @@ module JSONP3
|
|
703
745
|
# Apply this selector to _node_.
|
704
746
|
# @return [Array<JSONPathNode>]
|
705
747
|
def resolve: (JSONPathNode _node) -> Array[JSONPathNode]
|
748
|
+
def resolve_enum: (JSONPathNode _node) -> Enumerable[JSONPathNode]
|
706
749
|
|
707
750
|
# Return true if this selector is a singular selector.
|
708
751
|
def singular?: () -> false
|
@@ -718,6 +761,7 @@ module JSONP3
|
|
718
761
|
def initialize: (JSONPathEnvironment env, Token token, String name) -> void
|
719
762
|
|
720
763
|
def resolve: (JSONPathNode node) -> ::Array[JSONPathNode]
|
764
|
+
def resolve_enum: (JSONPathNode node) -> Enumerable[JSONPathNode]
|
721
765
|
|
722
766
|
def singular?: () -> true
|
723
767
|
|
@@ -741,6 +785,7 @@ module JSONP3
|
|
741
785
|
def initialize: (JSONPathEnvironment env, Token token, String name) -> void
|
742
786
|
|
743
787
|
def resolve: (JSONPathNode node) -> ::Array[JSONPathNode]
|
788
|
+
def resolve_enum: (JSONPathNode node) -> Enumerable[JSONPathNode]
|
744
789
|
|
745
790
|
def singular?: () -> true
|
746
791
|
|
@@ -762,7 +807,8 @@ module JSONP3
|
|
762
807
|
|
763
808
|
def initialize: (JSONPathEnvironment env, Token token, Integer index) -> void
|
764
809
|
|
765
|
-
def resolve: (JSONPathNode node) -> Array[JSONPathNode]
|
810
|
+
def resolve: (JSONPathNode node) -> ::Array[JSONPathNode]
|
811
|
+
def resolve_enum: (JSONPathNode node) -> Enumerable[JSONPathNode]
|
766
812
|
|
767
813
|
def singular?: () -> true
|
768
814
|
|
@@ -781,7 +827,8 @@ module JSONP3
|
|
781
827
|
|
782
828
|
# The wildcard selector selects all elements from an array or values from a hash.
|
783
829
|
class WildcardSelector < Selector
|
784
|
-
def resolve: (JSONPathNode node) -> Array[JSONPathNode]
|
830
|
+
def resolve: (JSONPathNode node) -> ::Array[JSONPathNode]
|
831
|
+
def resolve_enum: (JSONPathNode node) -> Enumerable[JSONPathNode]
|
785
832
|
|
786
833
|
def to_s: () -> "*"
|
787
834
|
|
@@ -811,7 +858,8 @@ module JSONP3
|
|
811
858
|
|
812
859
|
def initialize: (JSONPathEnvironment env, Token token, (Integer | nil) start, (Integer | nil) stop, (Integer | nil) step) -> void
|
813
860
|
|
814
|
-
def resolve: (JSONPathNode node) -> Array[JSONPathNode]
|
861
|
+
def resolve: (JSONPathNode node) -> ::Array[JSONPathNode]
|
862
|
+
def resolve_enum: (JSONPathNode node) -> Enumerable[JSONPathNode]
|
815
863
|
|
816
864
|
def to_s: () -> ::String
|
817
865
|
|
@@ -820,12 +868,6 @@ module JSONP3
|
|
820
868
|
alias eql? ==
|
821
869
|
|
822
870
|
def hash: () -> Integer
|
823
|
-
|
824
|
-
private
|
825
|
-
|
826
|
-
def normalized_start: (Integer length) -> Integer
|
827
|
-
|
828
|
-
def normalized_stop: (Integer length) -> Integer
|
829
871
|
end
|
830
872
|
|
831
873
|
# Select array elements or hash values according to a filter expression.
|
@@ -837,7 +879,8 @@ module JSONP3
|
|
837
879
|
|
838
880
|
def initialize: (JSONPathEnvironment env, Token token, Expression expression) -> void
|
839
881
|
|
840
|
-
def resolve: (JSONPathNode node) -> Array[JSONPathNode]
|
882
|
+
def resolve: (JSONPathNode node) -> ::Array[JSONPathNode]
|
883
|
+
def resolve_enum: (JSONPathNode node) -> Enumerable[JSONPathNode]
|
841
884
|
|
842
885
|
def to_s: () -> ::String
|
843
886
|
|
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.
|
4
|
+
version: 0.4.0
|
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: 2025-
|
39
|
+
date: 2025-02-10 00:00:00.000000000 Z
|
40
40
|
dependencies: []
|
41
41
|
description: JSONPath following RFC 9535
|
42
42
|
email:
|
metadata.gz.sig
CHANGED
Binary file
|