janeway-jsonpath 0.4.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ee00e4f5c1c77042409d76e6de5a287dfe0d5bcdaa2c150db2d11fa7e4037228
4
- data.tar.gz: 7b95f568aa555bb5b9959a2ced3677d7ab7b0e877c69e34db29abbdff5211e50
3
+ metadata.gz: 210bad818f98217873f0055d2ed46432b2b56087442e371671c22f00e51ff0f8
4
+ data.tar.gz: 1a2fd7d80573323fb3cb6c6b8c28ddf5182585bf05cd2540816d29faf637ed87
5
5
  SHA512:
6
- metadata.gz: 57a64e5946f8375ef13bc634dd9e860588fd7ff7d2c6b2f3b6c14de640ba1ba26e4a4fcc12ba71958853728626d846ed067392ca876efd94f02f0a41c2d2ac5b
7
- data.tar.gz: 238e8cdb81ddab8674c22eb2150c5b7522e7012eac965f264486017c7e51328a0eea23d3d352698c72eeb0275a1924a1b89575104eaf64d3796a52cdb76499dd
6
+ metadata.gz: 35c927af0528d849acf86691fb7b2fa0ec16d69ce6819ad37f231b3918394f9459ceb7ec4340cb65cf4feb48792c251317af111072bb8e23f8cc2d8da6407cf1
7
+ data.tar.gz: 22337b8703744e1428632635dcfb1eb25c57042d069b37ecf0ee0b13b70554d2b5fd1c3bc59af75f4ec0d4a23876e8aeb1421bc35c82ed8b652c0ac3ff0baf4a
data/README.md CHANGED
@@ -77,7 +77,7 @@ Example:
77
77
 
78
78
 
79
79
  ### Find and return matching values
80
- $ janeway '$..book[?(@["price"] == 8.95 || @["price"] == 8.99)].title' store.json
80
+ $ janeway '$..book[? @.price==8.95 || @.price==8.99].title' store.json
81
81
  [
82
82
  "Sayings of the Century",
83
83
  "Moby Dick"
@@ -97,7 +97,7 @@ Example:
97
97
 
98
98
  You can also pipe JSON into it:
99
99
  ```
100
- $ cat store.json | janeway '$..book[?(@.price<10)]'
100
+ $ cat store.json | janeway '$..book[? @.price<10]'
101
101
  ```
102
102
 
103
103
  See the help message for more capabilities: `janeway --help`
@@ -122,7 +122,7 @@ Following are examples showing how to work with the Enumerator methods.
122
122
  Returns all values that match the query.
123
123
 
124
124
  ```ruby
125
- results = Janeway.enum_for('$..book[?(@.price<10)]', data).search
125
+ results = Janeway.enum_for('$..book[? @.price<10]', data).search
126
126
  # Returns every book in the store cheaper than $10
127
127
  ```
128
128
 
@@ -140,7 +140,7 @@ Alternatively, compile the query once, and share it between threads or ractors w
140
140
  end
141
141
 
142
142
  # Construct JSONPath query object and send it to each ractor
143
- query = Janeway.compile('$..book[?(@.price<10)]')
143
+ query = Janeway.compile('$..book[? @.price<10]')
144
144
  ractors.each { |ractor| ractor.send(query).take }
145
145
  ```
146
146
 
@@ -159,7 +159,7 @@ The matched value is yielded:
159
159
  end
160
160
  ```
161
161
 
162
- This allows the matched value to be modified in place:
162
+ Strings values can be modified in place:
163
163
  ```ruby
164
164
  Janeway.enum_for('$.birds[? @=="storck"]', data).each do |bird|
165
165
  bird.gsub!('ck', 'k') # Fix a typo: "storck" => "stork"
@@ -167,7 +167,8 @@ This allows the matched value to be modified in place:
167
167
  # input list is now ['eagle', 'stork', 'cormorant']
168
168
  ```
169
169
 
170
- However, this is not enough to replace the matched value:
170
+ However, this doesn't work with numeric values because they can't be modified in place.
171
+ Here's an example illustrating the same problem but using strings:
171
172
  ```ruby
172
173
  Janeway.enum_for('$.birds', data).each do |bird|
173
174
  bird = "bald eagle" if bird == 'eagle'
@@ -176,7 +177,8 @@ However, this is not enough to replace the matched value:
176
177
  # input list is still ['eagle', 'stork', 'cormorant']
177
178
  ```
178
179
 
179
- The second and third yield parameters are the object that contains the value, and the array index or hash key of the value.
180
+ To replace list values, you need access to the parent object (a Hash or Array) and the array index / hash key.
181
+ These are available as the second and third yield parameters.
180
182
  This allows the list or hash to be modified:
181
183
  ```ruby
182
184
  Janeway.enum_for('$.birds[? @=="eagle"]', data).each do |_bird, parent, index|
@@ -185,7 +187,15 @@ This allows the list or hash to be modified:
185
187
  # input list is now ['golden eagle', 'stork', 'cormorant']
186
188
  ```
187
189
 
188
- Lastly, the #each iterator's fourth yield parameter is the [normalized path](https://www.rfc-editor.org/rfc/rfc9535.html#name-normalized-paths) to the matched value.
190
+ The parent / index parameters can also be used to delete values, but this requires caution to avoid index errors.
191
+ For example, iterating over an array may yield index values 1, 2 and 3.
192
+ Deleting the value at index 1 would change the index for the remaining values.
193
+ Next iteration might yield index 2, but since 1 was deleted it is now really at index 1.
194
+
195
+ To avoid having to deal with such problems, use the built in `#delete` method below.
196
+
197
+
198
+ Lastly, the `#each` iterator's fourth yield parameter is the [normalized path](https://www.rfc-editor.org/rfc/rfc9535.html#name-normalized-paths) to the matched value.
189
199
  This is a jsonpath query string that uniquely points to the matched value.
190
200
 
191
201
  ```ruby
@@ -195,15 +205,16 @@ This is a jsonpath query string that uniquely points to the matched value.
195
205
  paths << path
196
206
  end
197
207
  paths
198
- # ["$['birds']", "$['dogs']", "$['birds'][0]", "$['birds'][1]", "$['birds'][2]", "$['dogs'][0]", "$['dogs'][1]", "$['dogs'][2]"]
208
+ # [ # "$['birds']", "$['dogs']", "$['birds'][0]", "$['birds'][1]", "$['birds'][2]",
209
+ # "$['dogs'][0]", "$['dogs'][1]", "$['dogs'][2]"]
199
210
  ```
200
211
 
201
212
  ##### #delete
202
213
 
203
- The '#delete' method deletes matched values from the input.
214
+ The `#delete` method deletes matched values from the input.
204
215
  ```ruby
205
- # delete any bird whose name is "eagle" or starts with "s"
206
- Janeway.enum_for('$.birds[? @=="eagle" || search(@, "^s")]', data).delete
216
+ # delete any bird whose name starts with "s" or is "eagle"
217
+ Janeway.enum_for('$.birds[? search(@, "^s") || @=="eagle"]', data).delete
207
218
  # input bird list is now ['cormorant']
208
219
 
209
220
  # delete all dog names
@@ -212,13 +223,13 @@ The '#delete' method deletes matched values from the input.
212
223
  ```
213
224
 
214
225
 
215
- The `Janeway.enum_for` and `Janeway::Query#on` methods return an enumerator, so you can use the usual ruby enumerator methods, such as:
226
+ The `Janeway.enum_for` and `Janeway::Query#enum_for` methods return an enumerator, so you can use the usual ruby enumerator methods, such as:
216
227
 
217
228
  ##### #map
218
229
  Return the matched elements, as modified by the block.
219
230
 
220
231
  ```ruby
221
- # take a dollar off every price in the store
232
+ # return all store prices, but take a dollar off each one
222
233
  sale_prices = Janeway.enum_for('$.store..price', data).map { |price| price - 1 }
223
234
  # [7.95, 11.99, 7.99, 21.99, 398]
224
235
  ```
@@ -256,15 +267,27 @@ Return only values that match the JSONPath query and also return false from the
256
267
 
257
268
  ##### #filter_map
258
269
 
259
- Combines #select and #map.
260
270
  Return values that match the jsonpath query and return truthy values from the block.
261
- Instead of returning the value from the data, return the result of the block.
271
+ Instead of returning the value from the data, return the result of the block:
262
272
 
263
- ##### #find
273
+ ```ruby
274
+ # Return titles of books by certain authors which cost more than the minimum price
275
+ APPROVED_AUTHORS = ['Evelyn Waugh', 'Herman Melville']
276
+ Janeway.enum_for('$.store.book[? @.price >= 8.99]', data).filter_map do |book|
277
+ book['title'] if APPROVED_AUTHORS.include?(book['author'])
278
+ end
279
+ # [ "Moby Dick", "Sword of Honour" ]
280
+ ```
281
+
282
+ Combines functionality of `#select` and `#map`.
264
283
 
265
- Return the first value that matches the jsonpath query and also returns a truthy value from the block
284
+ ##### #find
285
+
286
+ Return the first value that matches the jsonpath query and also returns a truthy value from the block:
266
287
  ```ruby
267
- Janeway.enum_for('$.store.book[? @.price >= 10.99]', data).find { |book| book['title'].start_with?('T') }
288
+ Janeway.enum_for('$.store.book[? @.price >= 10.99]', data).find do |book|
289
+ book['title'].start_with?('T')
290
+ end
268
291
  # [ "The Lord of the Rings" ]
269
292
  ```
270
293
 
@@ -44,17 +44,6 @@ module Janeway
44
44
  raise "Unknown jsonpath function #{name}"
45
45
  end
46
46
  end
47
-
48
- # True if the function's return value is a boolean
49
- # @return [Boolean]
50
- def logical?
51
- case name
52
- when 'length', 'count', 'value' then false
53
- when 'search', 'match' then true
54
- else
55
- raise "Unknown jsonpath function #{name}"
56
- end
57
- end
58
47
  end
59
48
  end
60
49
  end
data/lib/janeway/error.rb CHANGED
@@ -8,13 +8,15 @@ module Janeway
8
8
  # Lexer errors may also include the index into the query string that
9
9
  # points at which token was being lexed at the time of the error.
10
10
  class Error < StandardError
11
+ # JSONPath query
11
12
  # @return [String]
12
13
  attr_reader :query
13
14
 
15
+ # For lexer errors, this is the index on the query string where the error was encountered
14
16
  # @return [Location, nil]
15
17
  attr_reader :location
16
18
 
17
- # @param message [String] error message
19
+ # @param msg [String] error message
18
20
  # @param query [String] entire query string
19
21
  # @param location [Location] location of error
20
22
  def initialize(msg, query = nil, location = nil)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'base'
3
+ require_relative 'array_slice_selector_interpreter'
4
4
 
5
5
  module Janeway
6
6
  module Interpreters
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'base'
3
+ require_relative 'filter_selector_interpreter'
4
4
 
5
5
  module Janeway
6
6
  module Interpreters
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'name_selector_interpreter'
3
+ require_relative 'index_selector_interpreter'
4
4
 
5
5
  module Janeway
6
6
  module Interpreters
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'wildcard_selector_interpreter'
3
+ require_relative 'root_node_interpreter'
4
4
 
5
5
  module Janeway
6
6
  module Interpreters
data/lib/janeway/query.rb CHANGED
@@ -26,7 +26,7 @@ module Janeway
26
26
  # This can be used to iterate over results with #each, #map, etc.
27
27
  #
28
28
  # @return [Janeway::Enumerator]
29
- def on(input)
29
+ def enum_for(input)
30
30
  Janeway::Enumerator.new(self, input)
31
31
  end
32
32
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Janeway
4
- VERSION = '0.4.0'
4
+ VERSION = '0.5.0'
5
5
  end
data/lib/janeway.rb CHANGED
@@ -25,11 +25,11 @@ module Janeway
25
25
 
26
26
  # Compile a JSONPath query into an Abstract Syntax Tree.
27
27
  #
28
- # This can be combined with inputs (using #on) to create Enumerators.
28
+ # This can be combined with inputs (using #enum_for) to create Enumerators.
29
29
  # @example
30
30
  # query = Janeway.compile('$.store.books[? length(@.title) > 20]')
31
- # long_title_books = query.on(local_json).search
32
- # query.on(remote_json).each do |book|
31
+ # long_title_books = query.enum_for(some_data).search
32
+ # query.enum_for(other_data).each do |book|
33
33
  # long_title_books << book
34
34
  # end
35
35
  #
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: janeway-jsonpath
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fraser Hanson
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-01-29 00:00:00.000000000 Z
10
+ date: 2025-01-30 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: |+
13
13
  JSONPath is a query language for selecting and extracting values from a JSON text.