json_p3 0.4.0 → 1.0.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 +26 -7
- data/.ruby-version +1 -1
- data/CHANGELOG.md +58 -0
- data/README.md +125 -123
- data/Rakefile +3 -3
- data/certs/jgrp.pem +21 -21
- data/lib/json_p3/errors.rb +51 -43
- data/lib/json_p3/patch/op.rb +23 -0
- data/lib/json_p3/patch/op_add.rb +51 -0
- data/lib/json_p3/patch/op_copy.rb +64 -0
- data/lib/json_p3/patch/op_move.rb +74 -0
- data/lib/json_p3/patch/op_remove.rb +56 -0
- data/lib/json_p3/patch/op_replace.rb +54 -0
- data/lib/json_p3/patch/op_test.rb +31 -0
- data/lib/json_p3/patch.rb +15 -330
- data/lib/json_p3/path/environment.rb +113 -0
- data/lib/json_p3/path/filter.rb +463 -0
- data/lib/json_p3/path/function.rb +12 -0
- data/lib/json_p3/path/function_extensions/count.rb +15 -0
- data/lib/json_p3/path/function_extensions/length.rb +17 -0
- data/lib/json_p3/path/function_extensions/match.rb +62 -0
- data/lib/json_p3/path/function_extensions/pattern.rb +42 -0
- data/lib/json_p3/path/function_extensions/search.rb +44 -0
- data/lib/json_p3/path/function_extensions/value.rb +15 -0
- data/lib/json_p3/path/lexer.rb +220 -0
- data/lib/json_p3/path/node.rb +48 -0
- data/lib/json_p3/path/parser.rb +676 -0
- data/lib/json_p3/path/query.rb +74 -0
- data/lib/json_p3/path/segment.rb +172 -0
- data/lib/json_p3/path/selector.rb +304 -0
- data/lib/json_p3/path/serialize.rb +16 -0
- data/lib/json_p3/path/unescape.rb +134 -0
- data/lib/json_p3/pointer.rb +15 -76
- data/lib/json_p3/relative_pointer.rb +69 -0
- data/lib/json_p3/version.rb +1 -1
- data/lib/json_p3.rb +50 -13
- data/sig/json_p3/cache.rbs +21 -0
- data/sig/json_p3/errors.rbs +55 -0
- data/sig/json_p3/patch.rbs +145 -0
- data/sig/json_p3/path/environment.rbs +81 -0
- data/sig/json_p3/path/filter.rbs +196 -0
- data/sig/json_p3/path/function.rbs +94 -0
- data/sig/json_p3/path/lexer.rbs +62 -0
- data/sig/json_p3/path/node.rbs +46 -0
- data/sig/json_p3/path/parser.rbs +92 -0
- data/sig/json_p3/path/query.rbs +47 -0
- data/sig/json_p3/path/segment.rbs +54 -0
- data/sig/json_p3/path/selector.rbs +100 -0
- data/sig/json_p3/path/serialize.rbs +9 -0
- data/sig/json_p3/path/unescape.rbs +12 -0
- data/sig/json_p3/pointer.rbs +64 -0
- data/sig/json_p3/relative_pointer.rbs +30 -0
- data/sig/json_p3.rbs +24 -1313
- data.tar.gz.sig +0 -0
- metadata +66 -46
- metadata.gz.sig +0 -0
- data/lib/json_p3/environment.rb +0 -111
- data/lib/json_p3/filter.rb +0 -459
- data/lib/json_p3/function.rb +0 -10
- data/lib/json_p3/function_extensions/count.rb +0 -15
- data/lib/json_p3/function_extensions/length.rb +0 -17
- data/lib/json_p3/function_extensions/match.rb +0 -62
- data/lib/json_p3/function_extensions/pattern.rb +0 -39
- data/lib/json_p3/function_extensions/search.rb +0 -44
- data/lib/json_p3/function_extensions/value.rb +0 -15
- data/lib/json_p3/lexer.rb +0 -419
- data/lib/json_p3/node.rb +0 -44
- data/lib/json_p3/parser.rb +0 -553
- data/lib/json_p3/path.rb +0 -72
- data/lib/json_p3/segment.rb +0 -158
- data/lib/json_p3/selector.rb +0 -306
- data/lib/json_p3/serialize.rb +0 -13
- data/lib/json_p3/token.rb +0 -36
- data/lib/json_p3/unescape.rb +0 -112
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
module JSONP3
|
|
2
|
+
module Path
|
|
3
|
+
# Base class for all filter expression nodes.
|
|
4
|
+
class Expression
|
|
5
|
+
@token: t_token
|
|
6
|
+
|
|
7
|
+
# @dynamic token
|
|
8
|
+
attr_reader token: t_token
|
|
9
|
+
|
|
10
|
+
def initialize: (t_token token) -> void
|
|
11
|
+
|
|
12
|
+
# Evaluate the filter expression in the given context.
|
|
13
|
+
def evaluate: (FilterContext _context) -> untyped
|
|
14
|
+
|
|
15
|
+
def to_s: () -> String
|
|
16
|
+
|
|
17
|
+
def ==: (untyped other) -> bool
|
|
18
|
+
|
|
19
|
+
alias eql? ==
|
|
20
|
+
|
|
21
|
+
def hash: () -> Integer
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# An expression that evaluates to true or false.
|
|
25
|
+
class FilterExpression < Expression
|
|
26
|
+
@expression: Expression
|
|
27
|
+
|
|
28
|
+
attr_reader expression: Expression
|
|
29
|
+
|
|
30
|
+
def initialize: (t_token token, Expression expression) -> void
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
class Precedence
|
|
35
|
+
LOWEST: 1
|
|
36
|
+
|
|
37
|
+
LOGICAL_OR: 3
|
|
38
|
+
|
|
39
|
+
LOGICAL_AND: 4
|
|
40
|
+
|
|
41
|
+
PREFIX: 7
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def to_canonical_string: (Expression expression, Integer parent_precedence) -> String
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Base class for expression literals.
|
|
48
|
+
class FilterExpressionLiteral < Expression
|
|
49
|
+
@value: untyped
|
|
50
|
+
|
|
51
|
+
attr_reader value: untyped
|
|
52
|
+
|
|
53
|
+
def initialize: (t_token token, untyped value) -> void
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Literal true or false.
|
|
57
|
+
class BooleanLiteral < FilterExpressionLiteral
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# A double or single quoted string literal.
|
|
61
|
+
class StringLiteral < FilterExpressionLiteral
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# A literal integer.
|
|
65
|
+
class IntegerLiteral < FilterExpressionLiteral
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# A literal float
|
|
69
|
+
class FloatLiteral < FilterExpressionLiteral
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# A literal null
|
|
73
|
+
class NullLiteral < FilterExpressionLiteral
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# An expression prefixed with the logical not operator.
|
|
77
|
+
class LogicalNotExpression < Expression
|
|
78
|
+
@expression: Expression
|
|
79
|
+
|
|
80
|
+
attr_reader expression: Expression
|
|
81
|
+
|
|
82
|
+
def initialize: (t_token token, Expression expression) -> void
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Base class for expression with a left expression, operator and right expression.
|
|
86
|
+
class InfixExpression < Expression
|
|
87
|
+
@left: Expression
|
|
88
|
+
|
|
89
|
+
@right: Expression
|
|
90
|
+
|
|
91
|
+
attr_reader left: Expression
|
|
92
|
+
|
|
93
|
+
attr_reader right: Expression
|
|
94
|
+
|
|
95
|
+
def initialize: (t_token token, Expression left, Expression right) -> void
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# A logical `&&` expression.
|
|
99
|
+
class LogicalAndExpression < InfixExpression
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# A logical `||` expression.
|
|
103
|
+
class LogicalOrExpression < InfixExpression
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# An `==` expression.
|
|
107
|
+
class EqExpression < InfixExpression
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# A `!=` expression.
|
|
111
|
+
class NeExpression < InfixExpression
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# A `<=` expression.
|
|
115
|
+
class LeExpression < InfixExpression
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# A `>=` expression.
|
|
119
|
+
class GeExpression < InfixExpression
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# A `<` expression.
|
|
123
|
+
class LtExpression < InfixExpression
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# A `>` expression.
|
|
127
|
+
class GtExpression < InfixExpression
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Base class for all embedded filter queries
|
|
131
|
+
class QueryExpression < Expression
|
|
132
|
+
@query: Query
|
|
133
|
+
|
|
134
|
+
attr_reader query: Query
|
|
135
|
+
|
|
136
|
+
def initialize: (t_token token, Query query) -> void
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# An embedded query starting at the current node.
|
|
140
|
+
class RelativeQueryExpression < QueryExpression
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# An embedded query starting at the root node.
|
|
144
|
+
class AbsoluteQueryExpression < QueryExpression
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# A filter function call.
|
|
148
|
+
class FunctionExpression < Expression
|
|
149
|
+
@name: String
|
|
150
|
+
|
|
151
|
+
@func: FunctionExtension
|
|
152
|
+
|
|
153
|
+
@args: Array[Expression]
|
|
154
|
+
|
|
155
|
+
attr_reader name: String
|
|
156
|
+
|
|
157
|
+
attr_reader func: FunctionExtension
|
|
158
|
+
|
|
159
|
+
attr_reader args: Array[Expression]
|
|
160
|
+
|
|
161
|
+
# @param name [String]
|
|
162
|
+
# @param args [Array<Expression>]
|
|
163
|
+
def initialize: (t_token token, String name, JSONP3::Path::FunctionExtension func, Array[Expression] args) -> void
|
|
164
|
+
|
|
165
|
+
private
|
|
166
|
+
|
|
167
|
+
# @param func [Proc]
|
|
168
|
+
# @param args [Array<Object>]
|
|
169
|
+
# @return [Array<Object>]
|
|
170
|
+
def unpack_node_lists: (FunctionExtension func, Array[untyped] args) -> Array[untyped]
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def self.truthy?: (untyped obj) -> (true | false)
|
|
174
|
+
|
|
175
|
+
def self.eq?: (untyped left, untyped right) -> (false | true)
|
|
176
|
+
|
|
177
|
+
def self.lt?: (untyped left, untyped right) -> (true | false)
|
|
178
|
+
|
|
179
|
+
# Contextual information and data used for evaluating a filter expression.
|
|
180
|
+
class FilterContext
|
|
181
|
+
@env: Environment
|
|
182
|
+
|
|
183
|
+
@current: untyped
|
|
184
|
+
|
|
185
|
+
@root: untyped
|
|
186
|
+
|
|
187
|
+
attr_reader env: Environment
|
|
188
|
+
|
|
189
|
+
attr_reader current: untyped
|
|
190
|
+
|
|
191
|
+
attr_reader root: untyped
|
|
192
|
+
|
|
193
|
+
def initialize: (Environment env, untyped current, untyped root) -> void
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
module JSONP3
|
|
2
|
+
module Path
|
|
3
|
+
def self.map_iregexp: (String pattern) -> String
|
|
4
|
+
|
|
5
|
+
# Base class for all filter functions.
|
|
6
|
+
class FunctionExtension
|
|
7
|
+
ARG_TYPES: Array[Symbol]
|
|
8
|
+
RETURN_TYPE: Symbol
|
|
9
|
+
|
|
10
|
+
def call: (*untyped _args, **untyped _kwargs) -> untyped
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# The standard `count` function.
|
|
14
|
+
class Count < FunctionExtension
|
|
15
|
+
ARG_TYPES: Array[Symbol]
|
|
16
|
+
RETURN_TYPE: Symbol
|
|
17
|
+
def call: (NodeList node_list) -> untyped
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# The standard `count` function.
|
|
21
|
+
class Length < FunctionExtension
|
|
22
|
+
ARG_TYPES: Array[Symbol]
|
|
23
|
+
RETURN_TYPE: Symbol
|
|
24
|
+
def call: (untyped obj) -> untyped
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# The standard `match` function.
|
|
28
|
+
class Match < FunctionExtension
|
|
29
|
+
@cache_size: Integer
|
|
30
|
+
|
|
31
|
+
@raise_errors: (true | false)
|
|
32
|
+
|
|
33
|
+
@cache: LRUCache
|
|
34
|
+
|
|
35
|
+
ARG_TYPES: ::Array[Symbol]
|
|
36
|
+
|
|
37
|
+
RETURN_TYPE: Symbol
|
|
38
|
+
|
|
39
|
+
# @param cache_size [Integer] the maximum size of the regexp cache. Set it to
|
|
40
|
+
# zero or negative to disable the cache.
|
|
41
|
+
# @param raise_errors [Boolean] if _false_ (the default), return _false_ when this
|
|
42
|
+
# function causes a RegexpError instead of raising the exception.
|
|
43
|
+
def initialize: (?::Integer cache_size, ?raise_errors: bool) -> void
|
|
44
|
+
|
|
45
|
+
# @param value [String]
|
|
46
|
+
# @param pattern [String]
|
|
47
|
+
# @return Boolean
|
|
48
|
+
def call: (untyped value, untyped pattern) -> untyped
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def full_match: (String pattern) -> String
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# The standard `search` function.
|
|
56
|
+
class Search < FunctionExtension
|
|
57
|
+
@cache_size: Integer
|
|
58
|
+
|
|
59
|
+
@raise_errors: (true | false)
|
|
60
|
+
|
|
61
|
+
@cache: LRUCache
|
|
62
|
+
|
|
63
|
+
ARG_TYPES: ::Array[Symbol]
|
|
64
|
+
|
|
65
|
+
RETURN_TYPE: Symbol
|
|
66
|
+
|
|
67
|
+
# @param cache_size [Integer] the maximum size of the regexp cache. Set it to
|
|
68
|
+
# zero or negative to disable the cache.
|
|
69
|
+
# @param raise_errors [Boolean] if _false_ (the default), return _false_ when this
|
|
70
|
+
# function causes a RegexpError instead of raising the exception.
|
|
71
|
+
def initialize: (?::Integer cache_size, ?raise_errors: bool) -> void
|
|
72
|
+
|
|
73
|
+
# @param value [String]
|
|
74
|
+
# @param pattern [String]
|
|
75
|
+
# @return Boolean
|
|
76
|
+
def call: (untyped value, untyped pattern) -> untyped
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# The standard `value` function.
|
|
80
|
+
class Value < FunctionExtension
|
|
81
|
+
ARG_TYPES: ::Array[Symbol]
|
|
82
|
+
|
|
83
|
+
RETURN_TYPE: Symbol
|
|
84
|
+
|
|
85
|
+
def call: (NodeList node_list) -> untyped
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
type t_token = [t_token_kind, Integer, Integer]
|
|
2
|
+
|
|
3
|
+
type t_token_kind = (
|
|
4
|
+
:token_and |
|
|
5
|
+
:token_asterisk |
|
|
6
|
+
:token_at |
|
|
7
|
+
:token_colon |
|
|
8
|
+
:token_comma |
|
|
9
|
+
:token_dollar |
|
|
10
|
+
:token_dot |
|
|
11
|
+
:token_double_dot |
|
|
12
|
+
:token_double_quoted_esc_string |
|
|
13
|
+
:token_double_quoted_string |
|
|
14
|
+
:token_eoi |
|
|
15
|
+
:token_eq |
|
|
16
|
+
:token_error |
|
|
17
|
+
:token_false |
|
|
18
|
+
:token_float |
|
|
19
|
+
:token_function |
|
|
20
|
+
:token_ge |
|
|
21
|
+
:token_gt |
|
|
22
|
+
:token_index |
|
|
23
|
+
:token_int |
|
|
24
|
+
:token_lbracket |
|
|
25
|
+
:token_le |
|
|
26
|
+
:token_lparen |
|
|
27
|
+
:token_lt |
|
|
28
|
+
:token_name |
|
|
29
|
+
:token_ne |
|
|
30
|
+
:token_not |
|
|
31
|
+
:token_null |
|
|
32
|
+
:token_or |
|
|
33
|
+
:token_question |
|
|
34
|
+
:token_rbracket |
|
|
35
|
+
:token_rparen |
|
|
36
|
+
:token_single_quoted_esc_string |
|
|
37
|
+
:token_single_quoted_string |
|
|
38
|
+
:token_true |
|
|
39
|
+
:token_trivia
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
module JSONP3
|
|
43
|
+
module Path
|
|
44
|
+
RE_FLOAT: Regexp
|
|
45
|
+
RE_INDEX: Regexp
|
|
46
|
+
RE_INT: Regexp
|
|
47
|
+
|
|
48
|
+
def self.tokenize: (String query) -> Array[t_token]
|
|
49
|
+
|
|
50
|
+
def self.scan_string_literal: (String query, Integer byte, Integer pos) -> [t_token, Integer]
|
|
51
|
+
|
|
52
|
+
def self.name_first?: (Integer ch) -> bool
|
|
53
|
+
|
|
54
|
+
def self.name_ch?: (Integer ch) -> bool
|
|
55
|
+
|
|
56
|
+
def self.number_ch?: (Integer ch) -> bool
|
|
57
|
+
|
|
58
|
+
def self.trivia?: (Integer ch) -> bool
|
|
59
|
+
|
|
60
|
+
def self.get_token_value: (t_token token, String query) -> String
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
type location_item = String | Integer | Array[location_item]
|
|
2
|
+
|
|
3
|
+
module JSONP3
|
|
4
|
+
module Path
|
|
5
|
+
# A JSON-like value and its location.
|
|
6
|
+
class Node
|
|
7
|
+
@value: untyped
|
|
8
|
+
|
|
9
|
+
@location: Array[location_item]
|
|
10
|
+
|
|
11
|
+
@root: untyped
|
|
12
|
+
|
|
13
|
+
# @dynamic value, location, root
|
|
14
|
+
attr_reader value: untyped
|
|
15
|
+
|
|
16
|
+
# @dynamic value, location, root
|
|
17
|
+
attr_reader location: Array[location_item]
|
|
18
|
+
|
|
19
|
+
# @dynamic value, location, root
|
|
20
|
+
attr_reader root: untyped
|
|
21
|
+
|
|
22
|
+
# @param value [JSON-like] the value at this node.
|
|
23
|
+
# @param location [Array<String | Integer | Array<String | Integer>>] the sequence of
|
|
24
|
+
# names and/or indices leading to _value_ in _root_.
|
|
25
|
+
# @param root [JSON-like] the root value containing _value_ at _location_.
|
|
26
|
+
def initialize: (untyped value, Array[location_item] location, untyped root) -> void
|
|
27
|
+
|
|
28
|
+
# Return the normalized path to this node.
|
|
29
|
+
# @return [String] the normalized path.
|
|
30
|
+
def path: () -> ::String
|
|
31
|
+
|
|
32
|
+
# Return a new node that is a child of this node.
|
|
33
|
+
# @param value the JSON-like value at the new node.
|
|
34
|
+
# @param key [Integer, String] the array index or hash key associated with _value_.
|
|
35
|
+
def new_child: (untyped value, String | Integer key) -> Node
|
|
36
|
+
|
|
37
|
+
def to_s: () -> ::String
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# An array of JSONPathNode instances. We use this internally to differentiate
|
|
41
|
+
# arrays of Nodes and arrays of data values, which is required when calling
|
|
42
|
+
# filter functions expecting nodes as arguments. It is just an array though.
|
|
43
|
+
class NodeList < Array[Node]
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
module JSONP3
|
|
2
|
+
# JSONPath
|
|
3
|
+
module Path
|
|
4
|
+
# JSONPath query parser.
|
|
5
|
+
class Parser
|
|
6
|
+
@env: Environment
|
|
7
|
+
|
|
8
|
+
@query: String
|
|
9
|
+
|
|
10
|
+
@tokens: Array[t_token]
|
|
11
|
+
|
|
12
|
+
@pos: Integer
|
|
13
|
+
|
|
14
|
+
@eoi: t_token
|
|
15
|
+
|
|
16
|
+
class Precedence
|
|
17
|
+
LOWEST: 1
|
|
18
|
+
LOGICAL_OR: 3
|
|
19
|
+
LOGICAL_AND: 4
|
|
20
|
+
RELATIONAL: 5
|
|
21
|
+
PREFIX: 7
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
PRECEDENCES: Hash[Symbol, Integer]
|
|
25
|
+
|
|
26
|
+
BINARY_OPERATORS: Hash[Symbol, String]
|
|
27
|
+
|
|
28
|
+
COMPARISON_OPERATORS: Set[Symbol]
|
|
29
|
+
|
|
30
|
+
# @param env [Environment]
|
|
31
|
+
# @param query [String]
|
|
32
|
+
# @param tokens [Array[t_token]]
|
|
33
|
+
def initialize: (Environment env, String query, Array[t_token] tokens) -> void
|
|
34
|
+
|
|
35
|
+
def next: () -> t_token
|
|
36
|
+
|
|
37
|
+
def eat: (t_token_kind kind, ?String? message) -> t_token
|
|
38
|
+
|
|
39
|
+
def skip: (t_token_kind kind) -> void
|
|
40
|
+
|
|
41
|
+
def kind: () -> t_token_kind
|
|
42
|
+
|
|
43
|
+
def peek: () -> t_token
|
|
44
|
+
|
|
45
|
+
def parse: () -> Array[Segment]
|
|
46
|
+
|
|
47
|
+
def parse_segments: () -> Array[Segment]
|
|
48
|
+
|
|
49
|
+
def parse_descendant_selectors: () -> Array[Selector]
|
|
50
|
+
|
|
51
|
+
def parse_shorthand_selector: () -> Selector
|
|
52
|
+
|
|
53
|
+
def parse_bracketed_selectors: () -> Array[Selector]
|
|
54
|
+
|
|
55
|
+
def parse_index_or_slice: () -> Selector
|
|
56
|
+
|
|
57
|
+
def parse_slice_selector: () -> Selector
|
|
58
|
+
|
|
59
|
+
def parse_filter_selector: () -> Selector
|
|
60
|
+
|
|
61
|
+
def parse_filter_expression: (Integer precedence) -> Expression
|
|
62
|
+
|
|
63
|
+
def parse_function_expression: () -> Expression
|
|
64
|
+
|
|
65
|
+
def parse_primary: () -> Expression
|
|
66
|
+
|
|
67
|
+
def parse_grouped_expression: () -> Expression
|
|
68
|
+
|
|
69
|
+
def parse_prefix_expression: () -> Expression
|
|
70
|
+
|
|
71
|
+
def parse_infix_expression: (Expression left) -> Expression
|
|
72
|
+
|
|
73
|
+
def parse_integer_literal: () -> Expression
|
|
74
|
+
|
|
75
|
+
def parse_float_literal: () -> Expression
|
|
76
|
+
|
|
77
|
+
def parse_absolute_query: () -> Expression
|
|
78
|
+
|
|
79
|
+
def parse_relative_query: () -> Expression
|
|
80
|
+
|
|
81
|
+
def parse_i_json_int: (t_token token) -> Integer
|
|
82
|
+
|
|
83
|
+
def throw_for_not_compared: (Expression expression) -> void
|
|
84
|
+
|
|
85
|
+
def throw_for_non_comparable: (Expression expression) -> void
|
|
86
|
+
|
|
87
|
+
def validate_function_signature: (String name, FunctionExtension func, Array[Expression] args, t_token token) -> void
|
|
88
|
+
|
|
89
|
+
def function_return_type: (Expression expression) -> (nil | Symbol)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module JSONP3
|
|
2
|
+
module Path
|
|
3
|
+
# A compiled JSONPath expression ready to be applied to JSON-like values.
|
|
4
|
+
class Query
|
|
5
|
+
@env: JSONP3::Path::Environment
|
|
6
|
+
|
|
7
|
+
@segments: Array[JSONP3::Path::Segment]
|
|
8
|
+
|
|
9
|
+
def initialize: (JSONP3::Path::Environment env, Array[JSONP3::Path::Segment] segments) -> void
|
|
10
|
+
|
|
11
|
+
def to_s: () -> ::String
|
|
12
|
+
|
|
13
|
+
# Apply this JSONPath expression to JSON-like value _root_.
|
|
14
|
+
# @param root [Array, Hash, String, Integer, nil] the root JSON-like value to apply this query to.
|
|
15
|
+
# @return [Array<JSONPathNode>] the sequence of nodes found while applying this query to _root_.
|
|
16
|
+
def find: (untyped root) -> JSONP3::Path::NodeList
|
|
17
|
+
|
|
18
|
+
alias apply find
|
|
19
|
+
|
|
20
|
+
# Apply this JSONPath expression to JSON-like value _root_.
|
|
21
|
+
# @param root [Array, Hash, String, Integer, nil] the root JSON-like value to apply this query to.
|
|
22
|
+
# @return [Enumerable<JSONPathNode>] the sequence of nodes found while applying this query to _root_.
|
|
23
|
+
def find_enum: (untyped root) ->Enumerable[JSONP3::Path::Node]
|
|
24
|
+
|
|
25
|
+
# Return the first node from applying this JSONPath expression to JSON-like value _root_.
|
|
26
|
+
# @param root [Array, Hash, String, Integer, nil] the root JSON-like value to apply this query to.
|
|
27
|
+
# @return [JSONPathNode | nil] the first available node or nil if there were no matches.
|
|
28
|
+
def match: (untyped root) -> (JSONP3::Path::Node | nil)
|
|
29
|
+
|
|
30
|
+
# Return `true` if this query results in at least one node, or `false` otherwise.
|
|
31
|
+
# @param root [Array, Hash, String, Integer, nil] the root JSON-like value to apply this query to.
|
|
32
|
+
# @return [bool] `true` if this query results in at least one node, or `false` otherwise.
|
|
33
|
+
def match?: (untyped root) -> bool
|
|
34
|
+
|
|
35
|
+
# Return the first node from applying this JSONPath expression to JSON-like value _root_.
|
|
36
|
+
# @param root [Array, Hash, String, Integer, nil] the root JSON-like value to apply this query to.
|
|
37
|
+
# @return [JSONPathNode | nil] the first available node or nil if there were no matches.
|
|
38
|
+
def first: (untyped root) -> (JSONP3::Path::Node | nil)
|
|
39
|
+
|
|
40
|
+
# Return _true_ if this JSONPath expression is a singular query.
|
|
41
|
+
def singular?: () -> (false | true)
|
|
42
|
+
|
|
43
|
+
# Return _true_ if this JSONPath expression has no segments.
|
|
44
|
+
def empty?: () -> (false | true)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module JSONP3
|
|
2
|
+
module Path
|
|
3
|
+
# Base class for all JSONPath segments.
|
|
4
|
+
class Segment
|
|
5
|
+
@env: JSONP3::Path::Environment
|
|
6
|
+
|
|
7
|
+
@token: t_token
|
|
8
|
+
|
|
9
|
+
@selectors: Array[Selector]
|
|
10
|
+
|
|
11
|
+
# @dynamic token, selectors
|
|
12
|
+
attr_reader token: t_token
|
|
13
|
+
|
|
14
|
+
# @dynamic token, selectors
|
|
15
|
+
attr_reader selectors: Array[Selector]
|
|
16
|
+
|
|
17
|
+
def initialize: (JSONP3::Path::Environment env, t_token token, Array[Selector] selectors) -> void
|
|
18
|
+
|
|
19
|
+
# Select the children of each node in _nodes_.
|
|
20
|
+
# @return [Array<Node>]
|
|
21
|
+
def resolve: (Array[Node] _nodes) -> Array[Node]
|
|
22
|
+
|
|
23
|
+
# Select the children of each node in _nodes_.
|
|
24
|
+
# @return [Enumerable<Node>]
|
|
25
|
+
def resolve_enum: (Enumerable[Node] _nodes) -> Enumerable[Node]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# The child selection segment.
|
|
29
|
+
class ChildSegment < Segment
|
|
30
|
+
def to_s: () -> ::String
|
|
31
|
+
|
|
32
|
+
def ==: (untyped other) -> bool
|
|
33
|
+
|
|
34
|
+
alias eql? ==
|
|
35
|
+
|
|
36
|
+
def hash: () -> Integer
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# The descendent segment
|
|
40
|
+
class DescendantSegment < Segment
|
|
41
|
+
def to_s: () -> ::String
|
|
42
|
+
|
|
43
|
+
def ==: (untyped other) -> bool
|
|
44
|
+
|
|
45
|
+
alias eql? ==
|
|
46
|
+
|
|
47
|
+
def hash: () -> Integer
|
|
48
|
+
|
|
49
|
+
def visit: (Node node, ?::Integer depth) -> Array[Node]
|
|
50
|
+
|
|
51
|
+
def visit_enum: (Node node, ?::Integer depth) -> Enumerable[Node]
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
module JSONP3
|
|
2
|
+
module Path
|
|
3
|
+
# Base class for all JSONPath selectors
|
|
4
|
+
class Selector
|
|
5
|
+
@env: JSONP3::Path::Environment
|
|
6
|
+
|
|
7
|
+
@token: t_token
|
|
8
|
+
|
|
9
|
+
# @dynamic token
|
|
10
|
+
attr_reader token: t_token
|
|
11
|
+
|
|
12
|
+
def initialize: (Environment env, t_token token) -> void
|
|
13
|
+
|
|
14
|
+
# Apply this selector to _node_.
|
|
15
|
+
# @return [Array<JSONPathNode>]
|
|
16
|
+
def resolve: (Node _node) -> Array[Node]
|
|
17
|
+
|
|
18
|
+
# Apply this selector to _node_.
|
|
19
|
+
# @return [Enumerable<JSONPathNode>]
|
|
20
|
+
def resolve_enum: (Node node) -> Enumerable[Node]
|
|
21
|
+
|
|
22
|
+
# Return true if this selector is a singular selector.
|
|
23
|
+
def singular?: () -> (false | true)
|
|
24
|
+
|
|
25
|
+
def to_s: () -> String
|
|
26
|
+
|
|
27
|
+
def ==: (untyped other) -> bool
|
|
28
|
+
|
|
29
|
+
alias eql? ==
|
|
30
|
+
|
|
31
|
+
def hash: () -> Integer
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# The name selector select values from hashes given a key.
|
|
35
|
+
class NameSelector < Selector
|
|
36
|
+
@name: String
|
|
37
|
+
|
|
38
|
+
# @dynamic name
|
|
39
|
+
attr_reader name: untyped
|
|
40
|
+
|
|
41
|
+
def initialize: (Environment env, t_token token, String name) -> void
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# This non-standard name selector selects values from hashes given a string or
|
|
45
|
+
# symbol key.
|
|
46
|
+
class SymbolNameSelector < NameSelector
|
|
47
|
+
@sym: String
|
|
48
|
+
|
|
49
|
+
def initialize: (Environment env, t_token token, String name) -> void
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# The index selector selects values from arrays given an index.
|
|
53
|
+
class IndexSelector < Selector
|
|
54
|
+
@index: Integer
|
|
55
|
+
|
|
56
|
+
# @dynamic index
|
|
57
|
+
attr_reader index: Integer
|
|
58
|
+
|
|
59
|
+
def initialize: (Environment env, t_token token, Integer index) -> void
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def normalize: (Integer index, Integer length) -> Integer
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# The wildcard selector selects all elements from an array or values from a hash.
|
|
67
|
+
class WildcardSelector < Selector
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# The slice selector selects a range of elements from an array.
|
|
71
|
+
class SliceSelector < Selector
|
|
72
|
+
@start: (Integer | nil)
|
|
73
|
+
|
|
74
|
+
@stop: (Integer | nil)
|
|
75
|
+
|
|
76
|
+
@step: Integer
|
|
77
|
+
|
|
78
|
+
# @dynamic start, stop, step
|
|
79
|
+
attr_reader start: (Integer | nil)
|
|
80
|
+
|
|
81
|
+
# @dynamic start, stop, step
|
|
82
|
+
attr_reader stop: (Integer | nil)
|
|
83
|
+
|
|
84
|
+
# @dynamic start, stop, step
|
|
85
|
+
attr_reader step: Integer
|
|
86
|
+
|
|
87
|
+
def initialize: (Environment env, t_token token, (Integer | nil) start, (Integer | nil) stop, (Integer | nil) step) -> void
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Select array elements or hash values according to a filter expression.
|
|
91
|
+
class FilterSelector < Selector
|
|
92
|
+
@expression: Expression
|
|
93
|
+
|
|
94
|
+
# @dynamic expression
|
|
95
|
+
attr_reader expression: Expression
|
|
96
|
+
|
|
97
|
+
def initialize: (Environment env, t_token token, Expression expression) -> void
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|