json_p3 0.2.1 → 0.3.1
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 +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
|