jsi-dev 0.0.0.pre.kramdown
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 +7 -0
- data/.yardopts +8 -0
- data/CHANGELOG.md +101 -0
- data/LICENSE.md +613 -0
- data/README.md +303 -0
- data/docs/glossary.md +281 -0
- data/jsi.gemspec +30 -0
- data/lib/jsi/base/node.rb +373 -0
- data/lib/jsi/base.rb +738 -0
- data/lib/jsi/jsi_coder.rb +92 -0
- data/lib/jsi/metaschema.rb +6 -0
- data/lib/jsi/metaschema_node/bootstrap_schema.rb +126 -0
- data/lib/jsi/metaschema_node.rb +262 -0
- data/lib/jsi/ptr.rb +314 -0
- data/lib/jsi/schema/application/child_application/contains.rb +25 -0
- data/lib/jsi/schema/application/child_application/draft04.rb +21 -0
- data/lib/jsi/schema/application/child_application/draft06.rb +28 -0
- data/lib/jsi/schema/application/child_application/draft07.rb +28 -0
- data/lib/jsi/schema/application/child_application/items.rb +18 -0
- data/lib/jsi/schema/application/child_application/properties.rb +25 -0
- data/lib/jsi/schema/application/child_application.rb +13 -0
- data/lib/jsi/schema/application/draft04.rb +8 -0
- data/lib/jsi/schema/application/draft06.rb +8 -0
- data/lib/jsi/schema/application/draft07.rb +8 -0
- data/lib/jsi/schema/application/inplace_application/dependencies.rb +28 -0
- data/lib/jsi/schema/application/inplace_application/draft04.rb +25 -0
- data/lib/jsi/schema/application/inplace_application/draft06.rb +26 -0
- data/lib/jsi/schema/application/inplace_application/draft07.rb +32 -0
- data/lib/jsi/schema/application/inplace_application/ifthenelse.rb +20 -0
- data/lib/jsi/schema/application/inplace_application/ref.rb +18 -0
- data/lib/jsi/schema/application/inplace_application/someof.rb +44 -0
- data/lib/jsi/schema/application/inplace_application.rb +14 -0
- data/lib/jsi/schema/application.rb +12 -0
- data/lib/jsi/schema/draft04.rb +13 -0
- data/lib/jsi/schema/draft06.rb +13 -0
- data/lib/jsi/schema/draft07.rb +13 -0
- data/lib/jsi/schema/issue.rb +36 -0
- data/lib/jsi/schema/ref.rb +183 -0
- data/lib/jsi/schema/schema_ancestor_node.rb +122 -0
- data/lib/jsi/schema/validation/array.rb +69 -0
- data/lib/jsi/schema/validation/const.rb +20 -0
- data/lib/jsi/schema/validation/contains.rb +25 -0
- data/lib/jsi/schema/validation/dependencies.rb +49 -0
- data/lib/jsi/schema/validation/draft04/minmax.rb +91 -0
- data/lib/jsi/schema/validation/draft04.rb +110 -0
- data/lib/jsi/schema/validation/draft06.rb +120 -0
- data/lib/jsi/schema/validation/draft07.rb +157 -0
- data/lib/jsi/schema/validation/enum.rb +25 -0
- data/lib/jsi/schema/validation/ifthenelse.rb +46 -0
- data/lib/jsi/schema/validation/items.rb +54 -0
- data/lib/jsi/schema/validation/not.rb +20 -0
- data/lib/jsi/schema/validation/numeric.rb +121 -0
- data/lib/jsi/schema/validation/object.rb +45 -0
- data/lib/jsi/schema/validation/pattern.rb +34 -0
- data/lib/jsi/schema/validation/properties.rb +101 -0
- data/lib/jsi/schema/validation/property_names.rb +32 -0
- data/lib/jsi/schema/validation/ref.rb +40 -0
- data/lib/jsi/schema/validation/required.rb +27 -0
- data/lib/jsi/schema/validation/someof.rb +90 -0
- data/lib/jsi/schema/validation/string.rb +47 -0
- data/lib/jsi/schema/validation/type.rb +49 -0
- data/lib/jsi/schema/validation.rb +49 -0
- data/lib/jsi/schema.rb +792 -0
- data/lib/jsi/schema_classes.rb +357 -0
- data/lib/jsi/schema_registry.rb +190 -0
- data/lib/jsi/schema_set.rb +219 -0
- data/lib/jsi/simple_wrap.rb +26 -0
- data/lib/jsi/util/private/attr_struct.rb +130 -0
- data/lib/jsi/util/private/memo_map.rb +75 -0
- data/lib/jsi/util/private.rb +202 -0
- data/lib/jsi/util/typelike.rb +225 -0
- data/lib/jsi/util.rb +227 -0
- data/lib/jsi/validation/error.rb +34 -0
- data/lib/jsi/validation/result.rb +212 -0
- data/lib/jsi/validation.rb +15 -0
- data/lib/jsi/version.rb +5 -0
- data/lib/jsi.rb +105 -0
- data/lib/schemas/json-schema.org/draft-04/schema.rb +169 -0
- data/lib/schemas/json-schema.org/draft-06/schema.rb +171 -0
- data/lib/schemas/json-schema.org/draft-07/schema.rb +198 -0
- data/readme.rb +138 -0
- data/{resources}/schemas/json-schema.org/draft-04/schema.json +149 -0
- data/{resources}/schemas/json-schema.org/draft-06/schema.json +154 -0
- data/{resources}/schemas/json-schema.org/draft-07/schema.json +168 -0
- metadata +155 -0
@@ -0,0 +1,373 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JSI
|
4
|
+
module Base::Enumerable
|
5
|
+
include ::Enumerable
|
6
|
+
|
7
|
+
# an Array containing each item in this JSI.
|
8
|
+
#
|
9
|
+
# @param kw keyword arguments are passed to {Base#[]} - see its keyword params
|
10
|
+
# @return [Array]
|
11
|
+
def to_a(**kw)
|
12
|
+
# TODO remove eventually (keyword argument compatibility)
|
13
|
+
# discard when all supported ruby versions Enumerable#to_a delegate keywords to #each (3.0.1 breaks; 2.7.x warns)
|
14
|
+
# https://bugs.ruby-lang.org/issues/18289
|
15
|
+
ary = []
|
16
|
+
each(**kw) do |e|
|
17
|
+
ary << e
|
18
|
+
end
|
19
|
+
ary.freeze
|
20
|
+
end
|
21
|
+
|
22
|
+
alias_method :entries, :to_a
|
23
|
+
end
|
24
|
+
|
25
|
+
# module extending a {JSI::Base} object when its instance (its {Base#jsi_node_content})
|
26
|
+
# is a Hash (or responds to `#to_hash`)
|
27
|
+
module Base::HashNode
|
28
|
+
include Base::Enumerable
|
29
|
+
|
30
|
+
# instantiates and yields each property name (hash key) as a JSI described by any `propertyNames` schemas.
|
31
|
+
#
|
32
|
+
# @yield [JSI::Base]
|
33
|
+
# @return [nil, Enumerator] an Enumerator if invoked without a block; otherwise nil
|
34
|
+
def jsi_each_propertyName
|
35
|
+
return to_enum(__method__) { jsi_node_content_hash_pubsend(:size) } unless block_given?
|
36
|
+
|
37
|
+
property_schemas = SchemaSet.build do |schemas|
|
38
|
+
jsi_schemas.each do |s|
|
39
|
+
if s.keyword?('propertyNames') && s['propertyNames'].is_a?(Schema)
|
40
|
+
schemas << s['propertyNames']
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
jsi_node_content_hash_pubsend(:each_key) do |key|
|
45
|
+
yield property_schemas.new_jsi(key)
|
46
|
+
end
|
47
|
+
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
|
51
|
+
# See {Base#jsi_hash?}. Always true for HashNode.
|
52
|
+
def jsi_hash?
|
53
|
+
true
|
54
|
+
end
|
55
|
+
|
56
|
+
# Yields each key - see {Base#jsi_each_child_token}
|
57
|
+
def jsi_each_child_token(&block)
|
58
|
+
return to_enum(__method__) { jsi_node_content_hash_pubsend(:size) } unless block
|
59
|
+
jsi_node_content_hash_pubsend(:each_key, &block)
|
60
|
+
nil
|
61
|
+
end
|
62
|
+
|
63
|
+
# See {Base#jsi_child_token_in_range?}
|
64
|
+
def jsi_child_token_in_range?(token)
|
65
|
+
jsi_node_content_hash_pubsend(:key?, token)
|
66
|
+
end
|
67
|
+
|
68
|
+
# See {Base#jsi_node_content_child}
|
69
|
+
def jsi_node_content_child(token)
|
70
|
+
# I could check token_in_range? and return nil here (as ArrayNode does).
|
71
|
+
# without that check, if the instance defines Hash#default or #default_proc, that result is returned.
|
72
|
+
# the preferred mechanism for a JSI's default value should be its schema.
|
73
|
+
# but there's no compelling reason not to support both, so I'll return what #[] returns.
|
74
|
+
jsi_node_content_hash_pubsend(:[], token)
|
75
|
+
end
|
76
|
+
|
77
|
+
# See {Base#[]}
|
78
|
+
def [](token, as_jsi: jsi_child_as_jsi_default, use_default: jsi_child_use_default_default)
|
79
|
+
if jsi_node_content_hash_pubsend(:key?, token)
|
80
|
+
jsi_child(token, as_jsi: as_jsi)
|
81
|
+
else
|
82
|
+
if use_default
|
83
|
+
jsi_default_child(token, as_jsi: as_jsi)
|
84
|
+
else
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# yields each hash key and value of this node.
|
91
|
+
#
|
92
|
+
# each yielded key is a key of the instance hash, and each yielded value is the result of {Base#[]}.
|
93
|
+
#
|
94
|
+
# @param kw keyword arguments are passed to {Base#[]}
|
95
|
+
# @yield [Object, Object] each key and value of this hash node
|
96
|
+
# @return [self, Enumerator] an Enumerator if invoked without a block; otherwise self
|
97
|
+
def each(**kw, &block)
|
98
|
+
return to_enum(__method__, **kw) { jsi_node_content_hash_pubsend(:size) } unless block
|
99
|
+
if block.arity > 1
|
100
|
+
jsi_node_content_hash_pubsend(:each_key) { |k| yield k, self[k, **kw] }
|
101
|
+
else
|
102
|
+
jsi_node_content_hash_pubsend(:each_key) { |k| yield [k, self[k, **kw]] }
|
103
|
+
end
|
104
|
+
self
|
105
|
+
end
|
106
|
+
|
107
|
+
# a hash in which each key is a key of the instance hash and each value is the result of {Base#[]}
|
108
|
+
# @param kw keyword arguments are passed to {Base#[]}
|
109
|
+
# @return [Hash]
|
110
|
+
def to_hash(**kw)
|
111
|
+
hash = {}
|
112
|
+
jsi_node_content_hash_pubsend(:each_key) { |k| hash[k] = self[k, **kw] }
|
113
|
+
hash.freeze
|
114
|
+
end
|
115
|
+
|
116
|
+
# See {Base#as_json}
|
117
|
+
def as_json(options = {})
|
118
|
+
hash = {}
|
119
|
+
each_key do |k|
|
120
|
+
ks = k.is_a?(String) ? k :
|
121
|
+
k.is_a?(Symbol) ? k.to_s :
|
122
|
+
k.respond_to?(:to_str) && (kstr = k.to_str).is_a?(String) ? kstr :
|
123
|
+
raise(TypeError, "JSON object (Hash) cannot be keyed with: #{k.pretty_inspect.chomp}")
|
124
|
+
hash[ks] = jsi_child(k, as_jsi: true).as_json(**options)
|
125
|
+
end
|
126
|
+
hash
|
127
|
+
end
|
128
|
+
|
129
|
+
include Util::Hashlike
|
130
|
+
|
131
|
+
if Util::LAST_ARGUMENT_AS_KEYWORD_PARAMETERS
|
132
|
+
# invokes the method with the given name on the jsi_node_content (if defined) or its #to_hash
|
133
|
+
# @param method_name [String, Symbol]
|
134
|
+
# @param a positional arguments are passed to the invocation of method_name
|
135
|
+
# @param b block is passed to the invocation of method_name
|
136
|
+
# @return [Object] the result of calling method method_name on the jsi_node_content or its #to_hash
|
137
|
+
def jsi_node_content_hash_pubsend(method_name, *a, &b)
|
138
|
+
if jsi_node_content.respond_to?(method_name)
|
139
|
+
jsi_node_content.public_send(method_name, *a, &b)
|
140
|
+
else
|
141
|
+
jsi_node_content.to_hash.public_send(method_name, *a, &b)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
else
|
145
|
+
# invokes the method with the given name on the jsi_node_content (if defined) or its #to_hash
|
146
|
+
# @param method_name [String, Symbol]
|
147
|
+
# @param a positional arguments are passed to the invocation of method_name
|
148
|
+
# @param kw keyword arguments are passed to the invocation of method_name
|
149
|
+
# @param b block is passed to the invocation of method_name
|
150
|
+
# @return [Object] the result of calling method method_name on the jsi_node_content or its #to_hash
|
151
|
+
def jsi_node_content_hash_pubsend(method_name, *a, **kw, &b)
|
152
|
+
if jsi_node_content.respond_to?(method_name)
|
153
|
+
jsi_node_content.public_send(method_name, *a, **kw, &b)
|
154
|
+
else
|
155
|
+
jsi_node_content.to_hash.public_send(method_name, *a, **kw, &b)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# methods that don't look at the value; can skip the overhead of #[] (invoked by #to_hash)
|
161
|
+
SAFE_KEY_ONLY_METHODS.each do |method_name|
|
162
|
+
if Util::LAST_ARGUMENT_AS_KEYWORD_PARAMETERS
|
163
|
+
define_method(method_name) do |*a, &b|
|
164
|
+
jsi_node_content_hash_pubsend(method_name, *a, &b)
|
165
|
+
end
|
166
|
+
else
|
167
|
+
define_method(method_name) do |*a, **kw, &b|
|
168
|
+
jsi_node_content_hash_pubsend(method_name, *a, **kw, &b)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# module extending a {JSI::Base} object when its instance (its {Base#jsi_node_content})
|
175
|
+
# is an Array (or responds to `#to_ary`)
|
176
|
+
module Base::ArrayNode
|
177
|
+
include Base::Enumerable
|
178
|
+
|
179
|
+
# See {Base#jsi_array?}. Always true for ArrayNode.
|
180
|
+
def jsi_array?
|
181
|
+
true
|
182
|
+
end
|
183
|
+
|
184
|
+
# Yields each index - see {Base#jsi_each_child_token}
|
185
|
+
def jsi_each_child_token(&block)
|
186
|
+
return to_enum(__method__) { jsi_node_content_ary_pubsend(:size) } unless block
|
187
|
+
jsi_node_content_ary_pubsend(:each_index, &block)
|
188
|
+
nil
|
189
|
+
end
|
190
|
+
|
191
|
+
# See {Base#jsi_child_token_in_range?}
|
192
|
+
def jsi_child_token_in_range?(token)
|
193
|
+
token.is_a?(Integer) && token >= 0 && token < jsi_node_content_ary_pubsend(:size)
|
194
|
+
end
|
195
|
+
|
196
|
+
# See {Base#jsi_node_content_child}
|
197
|
+
def jsi_node_content_child(token)
|
198
|
+
# we check token_in_range? here (unlike HashNode) because we do not want to pass
|
199
|
+
# negative indices, Ranges, or non-Integers to Array#[]
|
200
|
+
if jsi_child_token_in_range?(token)
|
201
|
+
jsi_node_content_ary_pubsend(:[], token)
|
202
|
+
else
|
203
|
+
nil
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
# See {Base#[]}
|
208
|
+
def [](token, as_jsi: jsi_child_as_jsi_default, use_default: jsi_child_use_default_default)
|
209
|
+
size = jsi_node_content_ary_pubsend(:size)
|
210
|
+
if token.is_a?(Integer)
|
211
|
+
if token < 0
|
212
|
+
if token < -size
|
213
|
+
nil
|
214
|
+
else
|
215
|
+
jsi_child(token + size, as_jsi: as_jsi)
|
216
|
+
end
|
217
|
+
else
|
218
|
+
if token < size
|
219
|
+
jsi_child(token, as_jsi: as_jsi)
|
220
|
+
else
|
221
|
+
if use_default
|
222
|
+
jsi_default_child(token, as_jsi: as_jsi)
|
223
|
+
else
|
224
|
+
nil
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
elsif token.is_a?(Range)
|
229
|
+
type_err = proc do
|
230
|
+
raise(TypeError, [
|
231
|
+
"given range does not contain Integers",
|
232
|
+
"range: #{token.inspect}",
|
233
|
+
].join("\n"))
|
234
|
+
end
|
235
|
+
|
236
|
+
start_idx = token.begin
|
237
|
+
if start_idx.is_a?(Integer)
|
238
|
+
start_idx += size if start_idx < 0
|
239
|
+
return Util::EMPTY_ARY if start_idx == size
|
240
|
+
return nil if start_idx < 0 || start_idx > size
|
241
|
+
elsif start_idx.nil?
|
242
|
+
start_idx = 0
|
243
|
+
else
|
244
|
+
type_err.call
|
245
|
+
end
|
246
|
+
|
247
|
+
end_idx = token.end
|
248
|
+
if end_idx.is_a?(Integer)
|
249
|
+
end_idx += size if end_idx < 0
|
250
|
+
end_idx += 1 unless token.exclude_end?
|
251
|
+
end_idx = size if end_idx > size
|
252
|
+
return Util::EMPTY_ARY if start_idx >= end_idx
|
253
|
+
elsif end_idx.nil?
|
254
|
+
end_idx = size
|
255
|
+
else
|
256
|
+
type_err.call
|
257
|
+
end
|
258
|
+
|
259
|
+
(start_idx...end_idx).map { |i| jsi_child(i, as_jsi: as_jsi) }.freeze
|
260
|
+
else
|
261
|
+
raise(TypeError, [
|
262
|
+
"expected `token` param to be an Integer or Range",
|
263
|
+
"token: #{token.inspect}",
|
264
|
+
].join("\n"))
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
# yields each array element of this node.
|
269
|
+
#
|
270
|
+
# each yielded element is the result of {Base#[]} for each index of the instance array.
|
271
|
+
#
|
272
|
+
# @param kw keyword arguments are passed to {Base#[]}
|
273
|
+
# @yield [Object] each element of this array node
|
274
|
+
# @return [self, Enumerator] an Enumerator if invoked without a block; otherwise self
|
275
|
+
def each(**kw, &block)
|
276
|
+
return to_enum(__method__, **kw) { jsi_node_content_ary_pubsend(:size) } unless block
|
277
|
+
jsi_node_content_ary_pubsend(:each_index) { |i| yield(self[i, **kw]) }
|
278
|
+
self
|
279
|
+
end
|
280
|
+
|
281
|
+
# an array, the same size as the instance array, in which the element at each index is the
|
282
|
+
# result of {Base#[]}.
|
283
|
+
# @param kw keyword arguments are passed to {Base#[]}
|
284
|
+
# @return [Array]
|
285
|
+
def to_ary(**kw)
|
286
|
+
to_a(**kw)
|
287
|
+
end
|
288
|
+
|
289
|
+
# See {Base#as_json}
|
290
|
+
def as_json(options = {})
|
291
|
+
each_index.map { |i| jsi_child(i, as_jsi: true).as_json(**options) }
|
292
|
+
end
|
293
|
+
|
294
|
+
include Util::Arraylike
|
295
|
+
|
296
|
+
if Util::LAST_ARGUMENT_AS_KEYWORD_PARAMETERS
|
297
|
+
# invokes the method with the given name on the jsi_node_content (if defined) or its #to_ary
|
298
|
+
# @param method_name [String, Symbol]
|
299
|
+
# @param a positional arguments are passed to the invocation of method_name
|
300
|
+
# @param b block is passed to the invocation of method_name
|
301
|
+
# @return [Object] the result of calling method method_name on the jsi_node_content or its #to_ary
|
302
|
+
def jsi_node_content_ary_pubsend(method_name, *a, &b)
|
303
|
+
if jsi_node_content.respond_to?(method_name)
|
304
|
+
jsi_node_content.public_send(method_name, *a, &b)
|
305
|
+
else
|
306
|
+
jsi_node_content.to_ary.public_send(method_name, *a, &b)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
else
|
310
|
+
# invokes the method with the given name on the jsi_node_content (if defined) or its #to_ary
|
311
|
+
# @param method_name [String, Symbol]
|
312
|
+
# @param a positional arguments are passed to the invocation of method_name
|
313
|
+
# @param kw keyword arguments are passed to the invocation of method_name
|
314
|
+
# @param b block is passed to the invocation of method_name
|
315
|
+
# @return [Object] the result of calling method method_name on the jsi_node_content or its #to_ary
|
316
|
+
def jsi_node_content_ary_pubsend(method_name, *a, **kw, &b)
|
317
|
+
if jsi_node_content.respond_to?(method_name)
|
318
|
+
jsi_node_content.public_send(method_name, *a, **kw, &b)
|
319
|
+
else
|
320
|
+
jsi_node_content.to_ary.public_send(method_name, *a, **kw, &b)
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
# methods that don't look at the value; can skip the overhead of #[] (invoked by #to_a).
|
326
|
+
# we override these methods from Arraylike
|
327
|
+
SAFE_INDEX_ONLY_METHODS.each do |method_name|
|
328
|
+
if Util::LAST_ARGUMENT_AS_KEYWORD_PARAMETERS
|
329
|
+
define_method(method_name) do |*a, &b|
|
330
|
+
jsi_node_content_ary_pubsend(method_name, *a, &b)
|
331
|
+
end
|
332
|
+
else
|
333
|
+
define_method(method_name) do |*a, **kw, &b|
|
334
|
+
jsi_node_content_ary_pubsend(method_name, *a, **kw, &b)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
module Base::StringNode
|
341
|
+
delegate_methods = %w(% * + << =~ [] []=
|
342
|
+
ascii_only? b byteindex byterindex bytes bytesize byteslice bytesplice capitalize capitalize!
|
343
|
+
casecmp casecmp? center chars chomp chomp! chop chop! chr clear codepoints concat count delete delete!
|
344
|
+
delete_prefix delete_prefix! delete_suffix delete_suffix! downcase downcase!
|
345
|
+
each_byte each_char each_codepoint each_grapheme_cluster each_line
|
346
|
+
empty? encode encode! encoding end_with? force_encoding getbyte grapheme_clusters gsub gsub! hex
|
347
|
+
include? index insert intern length lines ljust lstrip lstrip! match match? next next! oct ord
|
348
|
+
partition prepend replace reverse reverse! rindex rjust rpartition rstrip rstrip! scan scrub scrub!
|
349
|
+
setbyte size slice slice! split squeeze squeeze! start_with? strip strip! sub sub! succ succ! sum
|
350
|
+
swapcase swapcase! to_c to_f to_i to_r to_s to_str to_sym tr tr! tr_s tr_s!
|
351
|
+
unicode_normalize unicode_normalize! unicode_normalized? unpack unpack1 upcase upcase! upto valid_encoding?
|
352
|
+
)
|
353
|
+
delegate_methods.each do |method_name|
|
354
|
+
if Util::LAST_ARGUMENT_AS_KEYWORD_PARAMETERS
|
355
|
+
define_method(method_name) do |*a, &b|
|
356
|
+
if jsi_node_content.respond_to?(method_name)
|
357
|
+
jsi_node_content.public_send(method_name, *a, &b)
|
358
|
+
else
|
359
|
+
jsi_node_content.to_str.public_send(method_name, *a, &b)
|
360
|
+
end
|
361
|
+
end
|
362
|
+
else
|
363
|
+
define_method(method_name) do |*a, **kw, &b|
|
364
|
+
if jsi_node_content.respond_to?(method_name)
|
365
|
+
jsi_node_content.public_send(method_name, *a, **kw, &b)
|
366
|
+
else
|
367
|
+
jsi_node_content.to_str.public_send(method_name, *a, **kw, &b)
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|