json_p3 0.2.1 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.rubocop.yml +19 -0
- data/CHANGELOG.md +9 -0
- data/README.md +149 -17
- data/certs/jgrp.pem +27 -0
- data/lib/json_p3/cache.rb +1 -1
- data/lib/json_p3/environment.rb +1 -1
- data/lib/json_p3/errors.rb +9 -1
- data/lib/json_p3/filter.rb +4 -4
- data/lib/json_p3/function.rb +0 -6
- data/lib/json_p3/function_extensions/count.rb +2 -2
- data/lib/json_p3/function_extensions/length.rb +2 -2
- data/lib/json_p3/function_extensions/match.rb +3 -3
- data/lib/json_p3/function_extensions/pattern.rb +1 -1
- data/lib/json_p3/function_extensions/search.rb +3 -3
- data/lib/json_p3/function_extensions/value.rb +2 -2
- data/lib/json_p3/lexer.rb +54 -55
- data/lib/json_p3/parser.rb +112 -112
- data/lib/json_p3/patch.rb +449 -0
- data/lib/json_p3/pointer.rb +236 -0
- data/lib/json_p3/segment.rb +3 -3
- data/lib/json_p3/selector.rb +4 -4
- data/lib/json_p3/token.rb +0 -38
- data/lib/json_p3/unescape.rb +5 -5
- data/lib/json_p3/version.rb +1 -1
- data/lib/json_p3.rb +10 -0
- data/sig/json_p3.rbs +322 -104
- data.tar.gz.sig +0 -0
- metadata +6 -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: 58f9239b2c34d2ad4b9bcd724f19cd2e6daab881befb2b568d44065ab3378864
|
4
|
+
data.tar.gz: a76e4a183e830bbfab1f925efde9e9e6e4fb36b2687c13ab0c85b609b01b5baf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c36a725f0856cfa9e2c8f91931a008db812dfd17b3d4ad1afad59cddf56afac0c91ad221d258950a2a755ffa988cef8ee0f5cf43f08ca0eccbf3c3be7facdf4f
|
7
|
+
data.tar.gz: a17d419c6dbd96c15596052eaf12b0615725590b5e448d33ffc48e44082d95011ea3f119e0c2529b871c7be16ded8d5c7c1296c3479c03bc16c8e81d2ce33034
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/.rubocop.yml
CHANGED
@@ -12,3 +12,22 @@ Style/StringLiterals:
|
|
12
12
|
|
13
13
|
Style/StringLiteralsInInterpolation:
|
14
14
|
EnforcedStyle: double_quotes
|
15
|
+
|
16
|
+
Metrics/AbcSize:
|
17
|
+
Max: 50
|
18
|
+
|
19
|
+
Metrics/ClassLength:
|
20
|
+
Max: 500
|
21
|
+
|
22
|
+
Metrics/CyclomaticComplexity:
|
23
|
+
Max: 15
|
24
|
+
|
25
|
+
Metrics/MethodLength:
|
26
|
+
Max: 50
|
27
|
+
|
28
|
+
Metrics/PerceivedComplexity:
|
29
|
+
Max: 20
|
30
|
+
|
31
|
+
Naming/MethodParameterName:
|
32
|
+
AllowedNames:
|
33
|
+
- op
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## [0.3.1] - 2024-12-05
|
2
|
+
|
3
|
+
- Fix JSON Patch `move` and `copy` operations when using the special JSON Pointer token `-`.
|
4
|
+
|
5
|
+
## [0.3.0] - 2024-11-25
|
6
|
+
|
7
|
+
- Implement JSON Pointer and Relative JSON Pointer
|
8
|
+
- Implement JSON Patch
|
9
|
+
|
1
10
|
## [0.2.1] - 2024-10-24
|
2
11
|
|
3
12
|
- Rename project and gem
|
data/README.md
CHANGED
@@ -11,6 +11,13 @@ We follow <a href="https://datatracker.ietf.org/doc/html/rfc9535">RFC 9535</a> s
|
|
11
11
|
<a href="https://github.com/jg-rp/ruby-json-p3/actions">
|
12
12
|
<img src="https://img.shields.io/github/actions/workflow/status/jg-rp/ruby-json-p3/main.yml?branch=main&label=tests&style=flat-square" alt="Tests">
|
13
13
|
</a>
|
14
|
+
<br>
|
15
|
+
<a href="https://rubygems.org/gems/json_p3">
|
16
|
+
<img alt="Gem Version" src="https://img.shields.io/gem/v/json_p3?style=flat-square">
|
17
|
+
</a>
|
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">
|
20
|
+
</a>
|
14
21
|
</p>
|
15
22
|
|
16
23
|
---
|
@@ -21,12 +28,38 @@ We follow <a href="https://datatracker.ietf.org/doc/html/rfc9535">RFC 9535</a> s
|
|
21
28
|
- [Example](#example)
|
22
29
|
- [Links](#links)
|
23
30
|
- [Related projects](#related-projects)
|
24
|
-
- [
|
31
|
+
- [Quick start](#quick-start)
|
25
32
|
- [Contributing](#contributing)
|
26
33
|
|
27
34
|
## Install
|
28
35
|
|
29
|
-
|
36
|
+
Add `'json_p3'` to your Gemfile:
|
37
|
+
|
38
|
+
```
|
39
|
+
gem 'json_p3', '~> 0.2.1'
|
40
|
+
```
|
41
|
+
|
42
|
+
Or
|
43
|
+
|
44
|
+
```
|
45
|
+
gem install json_p3
|
46
|
+
```
|
47
|
+
|
48
|
+
### Checksum
|
49
|
+
|
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
|
+
|
52
|
+
```
|
53
|
+
gem cert --add <(curl -Ls https://raw.githubusercontent.com/jg-rp/ruby-json-p3/refs/heads/main/certs/jgrp.pem)
|
54
|
+
```
|
55
|
+
|
56
|
+
Followed by:
|
57
|
+
|
58
|
+
```
|
59
|
+
gem install json_p3 -P MediumSecurity
|
60
|
+
```
|
61
|
+
|
62
|
+
JSON P3 has no runtime dependencies, so `-P HighSecurity` is OK too. See https://guides.rubygems.org/security/ for more information.
|
30
63
|
|
31
64
|
## Example
|
32
65
|
|
@@ -97,7 +130,7 @@ end
|
|
97
130
|
## Links
|
98
131
|
|
99
132
|
- Change log: https://github.com/jg-rp/ruby-json-p3/blob/main/CHANGELOG.md
|
100
|
-
-
|
133
|
+
- RubyGems: https://rubygems.org/gems/json_p3
|
101
134
|
- Source code: https://github.com/jg-rp/ruby-json-p3
|
102
135
|
- Issue tracker: https://github.com/jg-rp/ruby-json-p3/issues
|
103
136
|
|
@@ -107,13 +140,13 @@ end
|
|
107
140
|
- [Python JSONPath](https://github.com/jg-rp/python-jsonpath) - Another Python package implementing JSONPath, but with additional features and customization options.
|
108
141
|
- [JSON P3](https://github.com/jg-rp/json-p3) - RFC 9535 implemented in TypeScript.
|
109
142
|
|
110
|
-
##
|
143
|
+
## Quick start
|
111
144
|
|
112
145
|
### find
|
113
146
|
|
114
|
-
`find(query, value) -> Array
|
147
|
+
`find(query, value) -> Array<JSONPathNode>`
|
115
148
|
|
116
|
-
Apply JSONPath expression _query_ to JSON-like data _value_. An array of JSONPathNode
|
149
|
+
Apply JSONPath expression _query_ to JSON-like data _value_. An array of JSONPathNode instances is returned, one node for each value matched by _query_. The returned array will be empty if there were no matches.
|
117
150
|
|
118
151
|
Each `JSONPathNode` has:
|
119
152
|
|
@@ -229,7 +262,7 @@ nodes = jsonpath.find("$.*", { "a" => "b", "c" => "d" })
|
|
229
262
|
pp nodes.map(&:value) # ["b", "d"]
|
230
263
|
```
|
231
264
|
|
232
|
-
To configure an environment with custom filter functions or non-standard selectors, inherit from `JSONPathEnvironment` and override some of its constants or `#setup_function_extensions` method.
|
265
|
+
To configure an environment with custom filter functions or non-standard selectors, inherit from `JSONPathEnvironment` and override some of its constants or the `#setup_function_extensions` method.
|
233
266
|
|
234
267
|
```ruby
|
235
268
|
class MyJSONPathEnvironment < JSONP3::JSONPathEnvironment
|
@@ -253,7 +286,7 @@ class MyJSONPathEnvironment < JSONP3::JSONPathEnvironment
|
|
253
286
|
NAME_SELECTOR = NameSelector
|
254
287
|
|
255
288
|
# An implementation of the _index selector_. The default implementation will
|
256
|
-
# select
|
289
|
+
# select values from arrays only. Implement your own by inheriting from
|
257
290
|
# {IndexSelector} and overriding `#resolve`.
|
258
291
|
INDEX_SELECTOR = IndexSelector
|
259
292
|
|
@@ -286,45 +319,138 @@ JSONP3::JSONPathSyntaxError: unexpected trailing whitespace
|
|
286
319
|
| ^ unexpected trailing whitespace
|
287
320
|
```
|
288
321
|
|
322
|
+
### resolve
|
323
|
+
|
324
|
+
`resolve(pointer, value) -> Object`
|
325
|
+
|
326
|
+
Resolve a JSON Pointer (RFC 6901) against some data using `JSONP3.resolve()`.
|
327
|
+
|
328
|
+
```ruby
|
329
|
+
require "json_p3"
|
330
|
+
require "json"
|
331
|
+
|
332
|
+
data = JSON.parse <<~JSON
|
333
|
+
{
|
334
|
+
"users": [
|
335
|
+
{
|
336
|
+
"name": "Sue",
|
337
|
+
"score": 100
|
338
|
+
},
|
339
|
+
{
|
340
|
+
"name": "Sally",
|
341
|
+
"score": 84,
|
342
|
+
"admin": false
|
343
|
+
},
|
344
|
+
{
|
345
|
+
"name": "John",
|
346
|
+
"score": 86,
|
347
|
+
"admin": true
|
348
|
+
},
|
349
|
+
{
|
350
|
+
"name": "Jane",
|
351
|
+
"score": 55
|
352
|
+
}
|
353
|
+
],
|
354
|
+
"moderator": "John"
|
355
|
+
}
|
356
|
+
JSON
|
357
|
+
|
358
|
+
puts JSONP3.resolve("/users/1", data)
|
359
|
+
# {"name"=>"Sally", "score"=>84, "admin"=>false}
|
360
|
+
```
|
361
|
+
|
362
|
+
If a pointer can not be resolved, `JSONP3::JSONPointer::UNDEFINED` is returned instead. You can use your own default value using the `default:` keyword argument.
|
363
|
+
|
364
|
+
```ruby
|
365
|
+
# continued from above
|
366
|
+
|
367
|
+
pp JSONP3.resolve("/no/such/thing", data, default: nil) # nil
|
368
|
+
```
|
369
|
+
|
370
|
+
### apply
|
371
|
+
|
372
|
+
`apply(ops, value) -> Object`
|
373
|
+
|
374
|
+
Apply a JSON Patch ([RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902)) with `JSONP3.apply()`. **Data is modified in place**.
|
375
|
+
|
376
|
+
```ruby
|
377
|
+
require "json"
|
378
|
+
require "json_p3"
|
379
|
+
|
380
|
+
ops = <<~JSON
|
381
|
+
[
|
382
|
+
{ "op": "add", "path": "/some/foo", "value": { "foo": {} } },
|
383
|
+
{ "op": "add", "path": "/some/foo", "value": { "bar": [] } },
|
384
|
+
{ "op": "copy", "from": "/some/other", "path": "/some/foo/else" },
|
385
|
+
{ "op": "add", "path": "/some/foo/bar/-", "value": 1 }
|
386
|
+
]
|
387
|
+
JSON
|
388
|
+
|
389
|
+
data = { "some" => { "other" => "thing" } }
|
390
|
+
JSONP3.apply(JSON.parse(ops), data)
|
391
|
+
pp data
|
392
|
+
# {"some"=>{"other"=>"thing", "foo"=>{"bar"=>[1], "else"=>"thing"}}}
|
393
|
+
```
|
394
|
+
|
395
|
+
`JSONP3.apply(ops, value)` is a convenience method equivalent to `JSONP3::JSONPatch.new(ops).apply(value)`. Use the `JSONPatch` constructor when you need to apply the same patch to different data.
|
396
|
+
|
397
|
+
As well as passing an array of hashes following RFC 6902 as ops to `JSONPatch`, we offer a builder API to construct JSON Patch documents programmatically.
|
398
|
+
|
399
|
+
```ruby
|
400
|
+
require "json_p3"
|
401
|
+
|
402
|
+
data = { "some" => { "other" => "thing" } }
|
403
|
+
|
404
|
+
patch = JSONP3::JSONPatch.new
|
405
|
+
.add("/some/foo", { "foo" => [] })
|
406
|
+
.add("/some/foo", { "bar" => [] })
|
407
|
+
.copy("/some/other", "/some/foo/else")
|
408
|
+
.copy("/some/foo/else", "/some/foo/bar/-")
|
409
|
+
|
410
|
+
patch.apply(data)
|
411
|
+
pp data
|
412
|
+
# {"some"=>{"other"=>"thing", "foo"=>{"bar"=>["thing"], "else"=>"thing"}}}
|
413
|
+
```
|
414
|
+
|
289
415
|
## Contributing
|
290
416
|
|
291
417
|
Your contributions and questions are always welcome. Feel free to ask questions, report bugs or request features on the [issue tracker](https://github.com/jg-rp/ruby-json-p3/issues) or on [Github Discussions](https://github.com/jg-rp/ruby-json-p3/discussions). Pull requests are welcome too.
|
292
418
|
|
293
419
|
### Development
|
294
420
|
|
295
|
-
The [JSONPath Compliance Test Suite](https://github.com/jsonpath-standard/jsonpath-compliance-test-suite) is included as a git [submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules). Clone the
|
421
|
+
The [JSONPath Compliance Test Suite](https://github.com/jsonpath-standard/jsonpath-compliance-test-suite) is included as a git [submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules). Clone the JSON P3 git repository and initialize the CTS submodule.
|
296
422
|
|
297
423
|
```shell
|
298
424
|
$ git clone git@github.com:jg-rp/ruby-json-p3.git
|
299
|
-
$ cd ruby-json-p3
|
425
|
+
$ cd ruby-json-p3
|
300
426
|
$ git submodule update --init
|
301
427
|
```
|
302
428
|
|
303
|
-
We use [Bundler](https://bundler.io/) and [Rake](https://ruby.github.io/rake/). Install development dependencies with
|
429
|
+
We use [Bundler](https://bundler.io/) and [Rake](https://ruby.github.io/rake/). Install development dependencies with:
|
304
430
|
|
305
431
|
```
|
306
432
|
bundle install
|
307
433
|
```
|
308
434
|
|
309
|
-
Run tests with
|
435
|
+
Run tests with:
|
310
436
|
|
311
437
|
```
|
312
438
|
bundle exec rake test
|
313
439
|
```
|
314
440
|
|
315
|
-
Lint with
|
441
|
+
Lint with:
|
316
442
|
|
317
443
|
```
|
318
444
|
bundle exec rubocop
|
319
445
|
```
|
320
446
|
|
321
|
-
And type check with
|
447
|
+
And type check with:
|
322
448
|
|
323
449
|
```
|
324
450
|
bundle exec steep
|
325
451
|
```
|
326
452
|
|
327
|
-
Run one of the benchmarks with
|
453
|
+
Run one of the benchmarks with:
|
328
454
|
|
329
455
|
```
|
330
456
|
bundle exec ruby performance/benchmark_ips.rb
|
@@ -334,7 +460,7 @@ bundle exec ruby performance/benchmark_ips.rb
|
|
334
460
|
|
335
461
|
#### CPU profile
|
336
462
|
|
337
|
-
Dump profile data with `bundle exec ruby performance/profile.rb`, then generate an HTML flame graph with
|
463
|
+
Dump profile data with `bundle exec ruby performance/profile.rb`, then generate an HTML flame graph with:
|
338
464
|
|
339
465
|
```
|
340
466
|
bundle exec stackprof --d3-flamegraph .stackprof-cpu-just-compile.dump > flamegraph-cpu-just-compile.html
|
@@ -348,6 +474,12 @@ Print memory usage to the terminal.
|
|
348
474
|
bundle exec ruby performance/memory_profile.rb
|
349
475
|
```
|
350
476
|
|
351
|
-
###
|
477
|
+
### Notes to self
|
478
|
+
|
479
|
+
#### Build
|
480
|
+
|
481
|
+
`bundle exec rake release` and `bundle exec rake build` will look for `gem-private_key.pem` and `gem-public_cert.pem` in `~/.gem`.
|
482
|
+
|
483
|
+
#### TruffleRuby
|
352
484
|
|
353
485
|
On macOS Sonoma using MacPorts and `rbenv`, `LIBYAML_PREFIX=/opt/local/lib` is needed to install TruffleRuby and when executing any `bundle` command.
|
data/certs/jgrp.pem
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIEhTCCAu2gAwIBAgIBATANBgkqhkiG9w0BAQsFADBEMRYwFAYDVQQDDA1qYW1l
|
3
|
+
c2dyLnByaW9yMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZ
|
4
|
+
FgNjb20wHhcNMjQxMDI0MDcxNDAzWhcNMjUxMDI0MDcxNDAzWjBEMRYwFAYDVQQD
|
5
|
+
DA1qYW1lc2dyLnByaW9yMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJ
|
6
|
+
k/IsZAEZFgNjb20wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDvtEeN
|
7
|
+
ZNN153v2ZK+U+Tj7kfRgl52GzmZS7lIG83xvT5/K8xEG5G4Tqiq/aGuDdbnxtd/t
|
8
|
+
TQf6CtkixPzwj7WGIwoV28AUHKOJ7UjqRhXIuAn3nmzRLRNK2gVYpvzLTNCyLhIb
|
9
|
+
jyZqgvtjR9mmW/Uuq+9LcLN4iFfkW+4dSmcABnkZHWMWGZYMIwoYYpluEUS1KiRZ
|
10
|
+
mIALPEGO5JcpVvjpDwaP6GqV0khgnLixz9KlAF+2DCyki21wxtJoxJTuL9H5Ogb+
|
11
|
+
k+nDQd9ELFYfbn73UKYGPtoUxkQeNF/ajJAkb/8t0cwUeSgtpSPhWIITWBgdLq11
|
12
|
+
svViBlK9UZZC+dWG9x1lueVTG9fXBl69NJ9VA7MaxmHVY133sEySqwZMCrtDYjPX
|
13
|
+
wIzLI2U8iSDIsjxTq3F3pbxeD4ee85ZY/xAV9M6fpjmKJERibRZTUPQo9ujHAhVM
|
14
|
+
YNbfAHhPRGphT64/ocBjCmonrvA0fB3jP5wduEa5vD3JPOSb7dtCnNzNvDcCAwEA
|
15
|
+
AaOBgTB/MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBSswivEK7I4
|
16
|
+
DrAJcSgIMhgedOJm5DAiBgNVHREEGzAZgRdqYW1lc2dyLnByaW9yQGdtYWlsLmNv
|
17
|
+
bTAiBgNVHRIEGzAZgRdqYW1lc2dyLnByaW9yQGdtYWlsLmNvbTANBgkqhkiG9w0B
|
18
|
+
AQsFAAOCAYEAdq8q0kDj14XNFMVYdjv1dG6Zaom3hEIkWv7+AsaPVw33puAnffQU
|
19
|
+
lb2H1FG0LOGailuzPUadop6w/7oHO2jefj/85V0Tk6Hhk8cQpYQrtQgOHA3nsbmJ
|
20
|
+
9JksJ+Y8RbyZP5dDTyZjTG4N3kgwZeNozcLeLj2ONBZRvGAjh8fyHOdLMPVNpM2K
|
21
|
+
naRHKdSqWSU728nHDiVvLlGVkRInDmC+gC1msKqSEnQrLiBl27jMbsce9GKi2cb7
|
22
|
+
DNjDwDg37yrbWgU5LS97+DU6dbMGVE3zPpuZGPZMTdXqzWWy2VlTPXMvAVt3Y4YG
|
23
|
+
90hO1nDIwLn/1w9+Vb76b/5xc8AWWLozK4IPjh3pTvL6tCDiZw7tOQYp2uIO1Id1
|
24
|
+
hKbb8cJaj/A6UsTE00yz5CUyQMcLz3LaL9k7Ek0u7vCcJLicl1HbAeq1ah7ePLLX
|
25
|
+
6dM18fnfBc3yA4KI7AO8UAmRkTscMYV6f/K4YZR6ZYCNWRpY7rkg+arhf05aoSQf
|
26
|
+
vn9bO1bzwdnG
|
27
|
+
-----END CERTIFICATE-----
|
data/lib/json_p3/cache.rb
CHANGED
data/lib/json_p3/environment.rb
CHANGED
@@ -35,7 +35,7 @@ module JSONP3
|
|
35
35
|
NAME_SELECTOR = NameSelector
|
36
36
|
|
37
37
|
# An implementation of the _index selector_. The default implementation will
|
38
|
-
# select
|
38
|
+
# select values from arrays only. Implement your own by inheriting from
|
39
39
|
# {IndexSelector} and overriding `#resolve`.
|
40
40
|
INDEX_SELECTOR = IndexSelector
|
41
41
|
|
data/lib/json_p3/errors.rb
CHANGED
@@ -13,7 +13,7 @@ module JSONP3
|
|
13
13
|
@token = token
|
14
14
|
end
|
15
15
|
|
16
|
-
def detailed_message(highlight: true, **_kwargs)
|
16
|
+
def detailed_message(highlight: true, **_kwargs)
|
17
17
|
if @token.query.strip.empty?
|
18
18
|
"empty query"
|
19
19
|
else
|
@@ -46,4 +46,12 @@ module JSONP3
|
|
46
46
|
class JSONPathTypeError < JSONPathError; end
|
47
47
|
class JSONPathNameError < JSONPathError; end
|
48
48
|
class JSONPathRecursionError < JSONPathError; end
|
49
|
+
|
50
|
+
class JSONPointerError < StandardError; end
|
51
|
+
class JSONPointerIndexError < JSONPointerError; end
|
52
|
+
class JSONPointerSyntaxError < JSONPointerError; end
|
53
|
+
class JSONPointerTypeError < JSONPointerError; end
|
54
|
+
|
55
|
+
class JSONPatchError < StandardError; end
|
56
|
+
class JSONPatchTestFailure < JSONPatchError; end
|
49
57
|
end
|
data/lib/json_p3/filter.rb
CHANGED
@@ -356,10 +356,10 @@ module JSONP3 # rubocop:disable Style/Documentation
|
|
356
356
|
# @param func [Proc]
|
357
357
|
# @param args [Array<Object>]
|
358
358
|
# @return [Array<Object>]
|
359
|
-
def unpack_node_lists(func, args)
|
359
|
+
def unpack_node_lists(func, args)
|
360
360
|
unpacked_args = []
|
361
361
|
args.each_with_index do |arg, i|
|
362
|
-
unless arg.is_a?(JSONPathNodeList) && func.class::ARG_TYPES[i] !=
|
362
|
+
unless arg.is_a?(JSONPathNodeList) && func.class::ARG_TYPES[i] != :nodes_expression
|
363
363
|
unpacked_args << arg
|
364
364
|
next
|
365
365
|
end
|
@@ -384,7 +384,7 @@ module JSONP3 # rubocop:disable Style/Documentation
|
|
384
384
|
obj != false
|
385
385
|
end
|
386
386
|
|
387
|
-
def self.eq?(left, right)
|
387
|
+
def self.eq?(left, right)
|
388
388
|
left = left.first.value if left.is_a?(JSONPathNodeList) && left.length == 1
|
389
389
|
right = right.first.value if right.is_a?(JSONPathNodeList) && right.length == 1
|
390
390
|
|
@@ -403,7 +403,7 @@ module JSONP3 # rubocop:disable Style/Documentation
|
|
403
403
|
left == right
|
404
404
|
end
|
405
405
|
|
406
|
-
def self.lt?(left, right)
|
406
|
+
def self.lt?(left, right)
|
407
407
|
left = left.first.value if left.is_a?(JSONPathNodeList) && left.length == 1
|
408
408
|
right = right.first.value if right.is_a?(JSONPathNodeList) && right.length == 1
|
409
409
|
return left < right if left.is_a?(String) && right.is_a?(String)
|
data/lib/json_p3/function.rb
CHANGED
@@ -1,12 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module JSONP3
|
4
|
-
class ExpressionType
|
5
|
-
VALUE = :value_expression
|
6
|
-
LOGICAL = :logical_expression
|
7
|
-
NODES = :nodes_expression
|
8
|
-
end
|
9
|
-
|
10
4
|
# Base class for all filter functions.
|
11
5
|
class FunctionExtension
|
12
6
|
def call(*_args, **_kwargs)
|
@@ -5,8 +5,8 @@ require_relative "../function"
|
|
5
5
|
module JSONP3
|
6
6
|
# The standard `count` function.
|
7
7
|
class Count < FunctionExtension
|
8
|
-
ARG_TYPES = [
|
9
|
-
RETURN_TYPE =
|
8
|
+
ARG_TYPES = [:nodes_expression].freeze
|
9
|
+
RETURN_TYPE = :value_expression
|
10
10
|
|
11
11
|
def call(node_list)
|
12
12
|
node_list.length
|
@@ -5,8 +5,8 @@ require_relative "../function"
|
|
5
5
|
module JSONP3
|
6
6
|
# The standard `length` function.
|
7
7
|
class Length < FunctionExtension
|
8
|
-
ARG_TYPES = [
|
9
|
-
RETURN_TYPE =
|
8
|
+
ARG_TYPES = [:value_expression].freeze
|
9
|
+
RETURN_TYPE = :value_expression
|
10
10
|
|
11
11
|
def call(obj)
|
12
12
|
return :nothing unless obj.is_a?(Array) || obj.is_a?(Hash) || obj.is_a?(String)
|
@@ -7,8 +7,8 @@ require_relative "pattern"
|
|
7
7
|
module JSONP3
|
8
8
|
# The standard `match` function.
|
9
9
|
class Match < FunctionExtension
|
10
|
-
ARG_TYPES = [
|
11
|
-
RETURN_TYPE =
|
10
|
+
ARG_TYPES = %i[value_expression value_expression].freeze
|
11
|
+
RETURN_TYPE = :logical_expression
|
12
12
|
|
13
13
|
# @param cache_size [Integer] the maximum size of the regexp cache. Set it to
|
14
14
|
# zero or negative to disable the cache.
|
@@ -24,7 +24,7 @@ module JSONP3
|
|
24
24
|
# @param value [String]
|
25
25
|
# @param pattern [String]
|
26
26
|
# @return Boolean
|
27
|
-
def call(value, pattern)
|
27
|
+
def call(value, pattern)
|
28
28
|
return false unless pattern.is_a?(String) && value.is_a?(String)
|
29
29
|
|
30
30
|
if @cache_size.positive?
|
@@ -4,7 +4,7 @@ module JSONP3 # rubocop:disable Style/Documentation
|
|
4
4
|
# Map I-Regexp pattern to Ruby regex pattern.
|
5
5
|
# @param pattern [String]
|
6
6
|
# @return [String]
|
7
|
-
def self.map_iregexp(pattern)
|
7
|
+
def self.map_iregexp(pattern)
|
8
8
|
escaped = false
|
9
9
|
char_class = false
|
10
10
|
mapped = String.new(encoding: "UTF-8")
|
@@ -7,8 +7,8 @@ require_relative "pattern"
|
|
7
7
|
module JSONP3
|
8
8
|
# The standard `search` function.
|
9
9
|
class Search < FunctionExtension
|
10
|
-
ARG_TYPES = [
|
11
|
-
RETURN_TYPE =
|
10
|
+
ARG_TYPES = %i[value_expression value_expression].freeze
|
11
|
+
RETURN_TYPE = :logical_expression
|
12
12
|
|
13
13
|
# @param cache_size [Integer] the maximum size of the regexp cache. Set it to
|
14
14
|
# zero or negative to disable the cache.
|
@@ -24,7 +24,7 @@ module JSONP3
|
|
24
24
|
# @param value [String]
|
25
25
|
# @param pattern [String]
|
26
26
|
# @return Boolean
|
27
|
-
def call(value, pattern)
|
27
|
+
def call(value, pattern)
|
28
28
|
return false unless pattern.is_a?(String) && value.is_a?(String)
|
29
29
|
|
30
30
|
if @cache_size.positive?
|
@@ -5,8 +5,8 @@ require_relative "../function"
|
|
5
5
|
module JSONP3
|
6
6
|
# The standard `value` function.
|
7
7
|
class Value < FunctionExtension
|
8
|
-
ARG_TYPES = [
|
9
|
-
RETURN_TYPE =
|
8
|
+
ARG_TYPES = [:nodes_expression].freeze
|
9
|
+
RETURN_TYPE = :value_expression
|
10
10
|
|
11
11
|
def call(node_list)
|
12
12
|
node_list.length == 1 ? node_list.first.value : :nothing
|