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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 58f9239b2c34d2ad4b9bcd724f19cd2e6daab881befb2b568d44065ab3378864
4
- data.tar.gz: a76e4a183e830bbfab1f925efde9e9e6e4fb36b2687c13ab0c85b609b01b5baf
3
+ metadata.gz: afd5de1be45132d6071616dc7aa21425dc3d9beaed525315f017b343b434a42f
4
+ data.tar.gz: 19f0fc51ac0f8680e47808beda7f206ea9d911b33ebebaccb5803cd7bcd012c0
5
5
  SHA512:
6
- metadata.gz: c36a725f0856cfa9e2c8f91931a008db812dfd17b3d4ad1afad59cddf56afac0c91ad221d258950a2a755ffa988cef8ee0f5cf43f08ca0eccbf3c3be7facdf4f
7
- data.tar.gz: a17d419c6dbd96c15596052eaf12b0615725590b5e448d33ffc48e44082d95011ea3f119e0c2529b871c7be16ded8d5c7c1296c3479c03bc16c8e81d2ce33034
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 `-`.
@@ -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.to_s
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
- JSON.generate(@value)
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 @filter_depth.positive? ? :lex_inside_filter : :lex_segment
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) ? "['#{i}']" : "[#{i}]" }
24
+ segments = @location.flatten.map { |i| i.is_a?(String) ? "[#{JSONP3.canonical_string(i)}]" : "[#{i}]" }
23
25
  "$#{segments.join}"
24
26
  end
25
27
 
@@ -46,7 +46,7 @@ module JSONP3
46
46
  end
47
47
 
48
48
  def to_s
49
- @name.inspect
49
+ JSONP3.canonical_string(@name)
50
50
  end
51
51
 
52
52
  def ==(other)
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSONP3
4
- VERSION = "0.3.1"
4
+ VERSION = "0.3.2"
5
5
  end
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 expressin in the given context.
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 expreession lexical scanner.
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 optimisation.
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 indicies leading to _value_ in _root_.
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 assiciated with _value_.
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 seqeuences.
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 papointerth [JSONPointer]
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.1
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: 2024-12-05 00:00:00.000000000 Z
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.3.27
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