sinclair 1.14.2 → 1.16.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6bd1d9896437c341e52648bac78c70d453a773c92a2fba06111d88d12be06a3
4
- data.tar.gz: 5cb2ba761532e3db60ffc8a09b821509c1355949071c5346cef962b0d43dfe9d
3
+ metadata.gz: 54cfb901ecd8185d00862d7c0b5a99e9cb626d2bbadf45db59553ae980ef9dc1
4
+ data.tar.gz: 7f0f0a291a659fbc5eaa0d6b56a8bc0f2dfe08b3c0a0d290dad2a6136c7ccc53
5
5
  SHA512:
6
- metadata.gz: bf2fd682ae8e6c57a8a173a5f78492bf6c7011dfef7734fd9c0c2d3d4d73fa599bac72a9317920dd0ebf5bb6c98f0f2f511c0fcc9fe5b683f766b5624359ccf3
7
- data.tar.gz: db83a68fd9b11d0a227afca422f5a6e8e33bc64e3624a55c0d8f3b87d49235d8e17b1393c44b6ac2a67c8b9869e58d5780a3a06aad4f76429a4c4b0c48247f43
6
+ metadata.gz: d788efed427695e2b001e7b38cc7fa4ef41fb8f6e6b855d321e88f24cb7c97b71b7f4d2622041a5f36ed9921b88513bb26beb4d3b0f11c37a19425a2d1698d9b
7
+ data.tar.gz: 66f7170ee3a639fa43219f10f3c984369d72ac3e58f182ac00bf0fecf947efa0e5f25107cffa45db30048366085c7c329cd214b5ed5659d854af93f0588b264b
data/.rubocop.yml CHANGED
@@ -31,6 +31,7 @@ RSpec/PredicateMatcher:
31
31
  RSpec/DescribedClass:
32
32
  Exclude:
33
33
  - 'spec/integration/yard/**/*_spec.rb'
34
+ - 'spec/integration/readme/**/*_spec.rb'
34
35
 
35
36
  RSpec/ExampleLength:
36
37
  Exclude:
data/README.md CHANGED
@@ -15,13 +15,13 @@ create custom comparators, configure your application, create powerfull options,
15
15
 
16
16
  Employing Sinclair in your applications helps you streamline your development workflow and enhance your development process through more efficient, cleaner code
17
17
 
18
- Current Release: [1.14.2](https://github.com/darthjee/sinclair/tree/1.14.2)
18
+ Current Release: [1.16.0](https://github.com/darthjee/sinclair/tree/1.16.0)
19
19
 
20
- [Next release](https://github.com/darthjee/sinclair/compare/1.14.2...master)
20
+ [Next release](https://github.com/darthjee/sinclair/compare/1.16.0...master)
21
21
 
22
22
  Yard Documentation
23
23
  -------------------
24
- [https://www.rubydoc.info/gems/sinclair/1.14.2](https://www.rubydoc.info/gems/sinclair/1.14.2)
24
+ [https://www.rubydoc.info/gems/sinclair/1.16.0](https://www.rubydoc.info/gems/sinclair/1.16.0)
25
25
 
26
26
  Installation
27
27
  ---------------
@@ -290,9 +290,9 @@ Block methods accepts, as option
290
290
  klass = Class.new
291
291
  instance = klass.new
292
292
 
293
- builder = Sinclair.new(klass)
294
- builder.add_method(:random_number) { Random.rand(10..20) }
295
- builder.build
293
+ Sinclair.build(klass) do
294
+ add_method(:random_number) { Random.rand(10..20) }
295
+ end
296
296
 
297
297
  instance.random_number # returns a number between 10 and 20
298
298
  ```
@@ -326,11 +326,11 @@ instance.random_number # returns a number between 10 and 20
326
326
  class MyClass
327
327
  end
328
328
 
329
- builder = described_class.new(MyClass)
330
- builder.add_class_method(
331
- :function, 'a ** b + c', parameters: [:a], named_parameters: [:b, { c: 15 }]
332
- )
333
- builder.build
329
+ Sinclair.build(MyClass) do
330
+ add_class_method(
331
+ :function, 'a ** b + c', parameters: [:a], named_parameters: [:b, { c: 15 }]
332
+ )
333
+ end
334
334
 
335
335
  MyClass.function(10, b: 2) # returns 115
336
336
  ```
data/config/yardstick.yml CHANGED
@@ -1,4 +1,4 @@
1
- threshold: 99.8
1
+ threshold: 100
2
2
  require_exact_threshold: false
3
3
  rules:
4
4
  ApiTag::Presence:
@@ -18,6 +18,14 @@ rules:
18
18
  exclude:
19
19
  - Sinclair#add_method
20
20
  - Sinclair#add_class_method
21
+ - Sinclair.build
22
+ - Sinclair::Caster.cast
23
+ - Sinclair::Caster.cast_with
24
+ - Sinclair::Caster.caster_for
25
+ - Sinclair::Caster#initialize
26
+ - Sinclair::Caster::ClassMethods#cast
27
+ - Sinclair::Caster::ClassMethods#cast_with
28
+ - Sinclair::Caster::ClassMethods#caster_for
21
29
  - Sinclair::Configurable#config
22
30
  - Sinclair::Configurable#reset_config
23
31
  - Sinclair::Configurable#configure
@@ -34,6 +42,7 @@ rules:
34
42
  ReturnTag:
35
43
  enabled: true
36
44
  exclude:
45
+ - Sinclair.build
37
46
  - Sinclair::Matchers::AddClassMethodTo#raise_block_syntax_error
38
47
  - Sinclair::Matchers::AddInstanceMethodTo#raise_block_syntax_error
39
48
  - Sinclair::MethodBuilder#build_from_definition
@@ -42,6 +51,7 @@ rules:
42
51
  Summary::Presence:
43
52
  enabled: true
44
53
  exclude:
54
+ - Sinclair::Caster#initialize
45
55
  - Sinclair::Config::MethodsBuilder#initialize
46
56
  - Sinclair::ConfigFactory#initialize
47
57
  - Sinclair::EnvSettable::Builder#initialize
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sinclair
4
+ class Caster
5
+ # @api public
6
+ # @author darhtjee
7
+ #
8
+ # Class methods for {Caster}
9
+ module ClassMethods
10
+ # (see Caster.master_caster!)
11
+ def master_caster!
12
+ @master_caster = true
13
+ end
14
+
15
+ # (see Caster.cast_with)
16
+ def cast_with(key, method_name = nil, &block)
17
+ caster = instance_for(method_name, &block)
18
+
19
+ return class_casters[key] = caster if key.is_a?(Class)
20
+
21
+ casters[key] = caster
22
+ end
23
+
24
+ # (see Caster.cast)
25
+ def cast(value, key, **opts)
26
+ caster_for(key).cast(value, **opts)
27
+ end
28
+
29
+ # (see Caster.caster_for)
30
+ def caster_for(key)
31
+ return casters[key] if casters.key?(key)
32
+
33
+ caster_for_class(key) || superclas_caster_for(key) || new { |value| value }
34
+ end
35
+
36
+ protected
37
+
38
+ # @api private
39
+ #
40
+ # Returns a caster from the superclass
41
+ #
42
+ # @param key [Symbol,Class] key to be checked
43
+ #
44
+ # @see caster_for
45
+ # @return [Caster]
46
+ def superclas_caster_for(key)
47
+ return if master_caster?
48
+
49
+ superclass.caster_for(key)
50
+ end
51
+
52
+ # @api private
53
+ #
54
+ # Returns a caster searching for using class as key
55
+ #
56
+ # This is called by {#caster_for} any time key is a class
57
+ #
58
+ # @param klass [Class] class to be used in the search
59
+ #
60
+ # When the given class is not registered, a caster for a parent
61
+ # class is returned
62
+ #
63
+ # @return [Caster]
64
+ def caster_for_class(klass)
65
+ return unless klass.is_a?(Class) || klass.is_a?(Module)
66
+
67
+ class_casters.find do |klazz, _|
68
+ klass <= klazz
69
+ end&.second
70
+ end
71
+
72
+ # @api private
73
+ #
74
+ # Returns a new instance {Caster}
75
+ #
76
+ # @overload instance_for(method_name, &block)
77
+ # @param method_name [Symbol] method to be called in the model
78
+ # @param block [Proc] block to perform the casting
79
+ #
80
+ # When +method_name+ is not given, the block is used
81
+ #
82
+ # @overload instance_for(caster)
83
+ # @param caster [Caster] instance of caster to be returned
84
+ #
85
+ # @return [Caster]
86
+ def instance_for(method_name, &block)
87
+ return new(&block) unless method_name
88
+ return method_name if method_name.is_a?(Caster)
89
+
90
+ new(&method_name)
91
+ end
92
+
93
+ private
94
+
95
+ # @api private
96
+ # @private
97
+ #
98
+ # Caster map stored by +Symbols+
99
+ #
100
+ # @return [Hash<Symbol,Caster>]
101
+ def casters
102
+ @casters ||= {}
103
+ end
104
+
105
+ # @api private
106
+ # @private
107
+ #
108
+ # Caster map stored by +Classs+
109
+ #
110
+ # @return [Hash<Class,Caster>]
111
+ def class_casters
112
+ @class_casters ||= {}
113
+ end
114
+
115
+ # @api private
116
+ # @private
117
+ #
118
+ # Chack if the caster class is a master
119
+ #
120
+ # A master caster never checks if a superclass has a caster
121
+ #
122
+ # @see master_caster!
123
+ # @return [TrueClass,FalseClass]
124
+ def master_caster?
125
+ @master_caster
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,381 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sinclair
4
+ # @api public
5
+ # @author darhtjee
6
+ #
7
+ # Class responsible for defining how to and casting values
8
+ #
9
+ # First the class needs to be configured using {.cast_with} and later
10
+ # a value can be cast by using {.cast} or {.caster_for}
11
+ #
12
+ # Inheritance grants the hability to have different casting for different
13
+ # purposes / applications / gems
14
+ class Caster
15
+ autoload :ClassMethods, 'sinclair/caster/class_methods'
16
+ extend Caster::ClassMethods
17
+ master_caster!
18
+
19
+ # @method self.master_caster!
20
+ # @api public
21
+ #
22
+ # Changes the class to be the master caster
23
+ #
24
+ # The master caster never checks with its an
25
+ #
26
+ # @example
27
+ # class BaseCaster < Sinclair::Caster
28
+ # cast_with(:string, :to_s)
29
+ # end
30
+ #
31
+ # class MyCaster < BaseCaster
32
+ # end
33
+ #
34
+ # MyCaster.cast(10, :string) # returns '10'
35
+ #
36
+ # MyCaster.master_caster!
37
+ #
38
+ # MyCaster.cast(10, :string) # returns 10
39
+ #
40
+ # @see Caster::ClassMethods#master_caster!
41
+ #
42
+ # @return [TrueClass]
43
+
44
+ # @method self.cast_with
45
+ # @api public
46
+ #
47
+ # Register a caster under a key
48
+ #
49
+ # @overload cast_with(key, method_name)
50
+ # @param key [Symbol] key where the caster will be store.
51
+ # @param method_name [Symbol] method to be called on the
52
+ # value that is being converted
53
+ #
54
+ # @example Casting from pre registered symbol caster
55
+ # class MyCaster < Sinclair::Caster
56
+ # cast_with(:json, :to_json)
57
+ # end
58
+ #
59
+ # MyCaster.cast({ key: :value }, :json) # returns '{"key":"value"}'
60
+ #
61
+ # @overload cast_with(key, &block)
62
+ # @param key [Symbol] key where the caster will be store.
63
+ # @param block [Proc] block to be used when casting the value.
64
+ #
65
+ # @example Casting from pre registered block caster
66
+ # MyCaster.cast_with(:complex) do |hash|
67
+ # real = hash[:real]
68
+ # imaginary = hash[:imaginary]
69
+ #
70
+ # "#{real.to_f} + #{imaginary.to_f} i"
71
+ # end
72
+ #
73
+ # value = { real: 10, imaginary: 5 }
74
+ #
75
+ # MyCaster.cast(value, :complex) # returns '10.0 + 5.0 i'
76
+ #
77
+ # @overload cast_with(class_key, method_name)
78
+ # @param class_key [Class] class to be used as key.
79
+ # This will be used as parent class when the calling {Caster.cast}.
80
+ # @param method_name [Symbol] method to be called on the
81
+ # value that is being converted.
82
+ #
83
+ # @example Casting from pre registered class
84
+ # class MyCaster < Sinclair::Caster
85
+ # cast_with(Numeric, :to_i)
86
+ # end
87
+ #
88
+ # MyCaster.cast('10', Integer) # returns 10
89
+ #
90
+ # @overload cast_with(class_key, &block)
91
+ # @param class_key [Class] class to be used as key.
92
+ # This will be used as parent class when the calling {Caster.cast}.
93
+ # @param block [Proc] block to be used when casting the value.
94
+ #
95
+ # @example Casting from pre registered block caster from a class
96
+ # # hash_model.rb
97
+ #
98
+ # class HashModel
99
+ # def initialize(hash)
100
+ # hash.each do |attribute, value|
101
+ # method_name = "#{attribute}="
102
+ #
103
+ # send(method_name, value) if respond_to?(method_name)
104
+ # end
105
+ # end
106
+ # end
107
+ #
108
+ # # hash_person.rb
109
+ # class HashPerson < HashModel
110
+ # attr_accessor :name, :age
111
+ # end
112
+ #
113
+ # # caster_config.rb
114
+ # Caster.cast_with(HashModel) do |value, klass:|
115
+ # klass.new(value)
116
+ # end
117
+ #
118
+ # Caster.cast_with(String, &:to_json)
119
+ #
120
+ # # main.rb
121
+ # values = [
122
+ # { klass: String, value: { name: 'john', age: 20, country: 'BR' } },
123
+ # { klass: HashPerson, value: { name: 'Mary', age: 22, country: 'IT' } }
124
+ # ]
125
+ #
126
+ # values.map! do |config|
127
+ # value = config[:value]
128
+ # klass = config[:klass]
129
+ #
130
+ # Caster.cast(value, klass, klass: klass)
131
+ # end
132
+ #
133
+ # values[0] # returns '{"name":"john","age":20,"country":"BR"}'
134
+ # values[1] # returns HashPerson.new(name: 'Mary', age: 22)
135
+ #
136
+ # @see Caster::ClassMethods#cast_with
137
+ # @see Caster.caster_for
138
+ # @see Caster.cast
139
+ #
140
+ # @return [Caster] the registered caster
141
+
142
+ # @method self.cast
143
+ # @api public
144
+ #
145
+ # Cast a value using the registered caster
146
+ #
147
+ # @overload cast(value, key, **opts)
148
+ # @param value [Object] value to be cast
149
+ # @param key [Symbol] key where the caster is registered under
150
+ # @param opts [Hash] Options to be sent to the caster
151
+ #
152
+ # @example Casts with a symbol key
153
+ # # math_caster.rb
154
+ # class MathCaster < Sinclair::Caster
155
+ # cast_with(:float, :to_f)
156
+ #
157
+ # cast_with(:log) do |value, base: 10|
158
+ # value = MathCaster.cast(value, :float)
159
+ #
160
+ # Math.log(value, base)
161
+ # end
162
+ #
163
+ # cast_with(:exp) do |value, base: 10|
164
+ # value = MathCaster.cast(value, :float)
165
+ #
166
+ # base**value
167
+ # end
168
+ # end
169
+ #
170
+ # # main.rb
171
+ # initial = Random.rand(10..20)
172
+ # log = MathCaster.cast(initial, :log)
173
+ # exp = MathCaster.cast(log, :exp)
174
+ #
175
+ # # exp will be betwween initial - 0.0001 and initial + 0.0001
176
+ #
177
+ # @example Casts passing parameter
178
+ # base = Random.rand(3..6)
179
+ # initial = Random.rand(10..20)
180
+ # log = MathCaster.cast(initial, :log, base: base)
181
+ # exp = MathCaster.cast(log, :exp, base: base)
182
+ #
183
+ # # exp will be betwween initial - 0.0001 and initial + 0.0001
184
+ #
185
+ # @overload cast(value, class_key, **opts)
186
+ # @param value [Object] value to be cast
187
+ # @param class_key [Class] Class to used as key in the casters storage
188
+ # @param opts [Hash] Options to be sent to the caster
189
+ #
190
+ # When the +class_key+ does not match the stored key, but matches a superclass,
191
+ # the registerd caster is returned.
192
+ #
193
+ # @example Casts with class key
194
+ # # ruby_string_caster.rb
195
+ # class RubyStringCaster < Sinclair::Caster
196
+ # master_caster!
197
+ #
198
+ # cast_with(NilClass) { 'nil' }
199
+ # cast_with(Symbol) { |value| ":#{value}" }
200
+ # cast_with(String, :to_json)
201
+ # cast_with(Object, :to_s)
202
+ #
203
+ # def self.to_ruby_string(value)
204
+ # cast(value, value.class)
205
+ # end
206
+ # end
207
+ #
208
+ # # main.rb
209
+ # hash = { a: 1, b: 2, 'c' => nil }
210
+ # string = 'my string'
211
+ # symbol = :the_symbol
212
+ # number = 10
213
+ # null = nil
214
+ #
215
+ # <<-RUBY
216
+ # hash_value = #{RubyStringCaster.to_ruby_string(hash)}
217
+ # string_value = #{RubyStringCaster.to_ruby_string(string)}
218
+ # symbol_value = #{RubyStringCaster.to_ruby_string(symbol)}
219
+ # number = #{RubyStringCaster.to_ruby_string(number)}
220
+ # null_value = #{RubyStringCaster.to_ruby_string(null)}
221
+ # RUBY
222
+ #
223
+ # # Generates the String
224
+ # #
225
+ # # <<-RUBY
226
+ # # hash_value = {:a=>1, :b=>2, "c"=>nil}
227
+ # # string_value = "my string"
228
+ # # symbol_value = :the_symbol
229
+ # # number = 10
230
+ # # null_value = nil
231
+ # # RUBY
232
+ #
233
+ # @see Caster::ClassMethods#cast
234
+ # @see Caster.cast_with
235
+ # @see Caster.caster_for
236
+ # @see Caster#cast
237
+ #
238
+ # @return [Object] the value cast
239
+
240
+ # @method self.caster_for
241
+ # @api public
242
+ #
243
+ # Returns an instance of caster for the provided key
244
+ #
245
+ # When no registered caster is found one is requested for the parent class.
246
+ # If no caster is found, then a default caster is returned
247
+ #
248
+ # The default caster performs no casting returning the value itself
249
+ #
250
+ # @overload caster_for(key)
251
+ # @param key [Symbol] key where the caster is registered under
252
+ #
253
+ # @example Getting the caster with symbol key
254
+ # # enum_caster.rb
255
+ # class EnumCaster < Sinclair::Caster
256
+ # cast_with(:hash, :to_h)
257
+ # cast_with(:array, :to_a)
258
+ # end
259
+ #
260
+ # # enum_converter.rb
261
+ # module EnumConverter
262
+ # class << self
263
+ # def to_hash(value)
264
+ # return value if value.is_a?(Hash)
265
+ #
266
+ # hash_caster.cast(value)
267
+ # end
268
+ #
269
+ # def to_array(value)
270
+ # return value if value.is_a?(Array)
271
+ #
272
+ # array_caster.cast(value)
273
+ # end
274
+ #
275
+ # private
276
+ #
277
+ # def hash_caster
278
+ # @hash_caster ||= EnumCaster.caster_for(:hash)
279
+ # end
280
+ #
281
+ # def array_caster
282
+ # @array_caster ||= EnumCaster.caster_for(:array)
283
+ # end
284
+ # end
285
+ # end
286
+ #
287
+ # # main.rb
288
+ # EnumConverter.to_array({ key: :value }) # returns [%i[key value]]
289
+ # EnumConverter.to_hash([%i[key value]]) # returns { key: :value }
290
+ #
291
+ # @overload caster_for(class_key)
292
+ # @param class_key [Class] Class to used as key in the casters storage
293
+ #
294
+ # When the +class_key+ does not match the stored key, but matches a superclass,
295
+ # the registerd caster is returned.
296
+ #
297
+ # @example Getting the caster with class key'
298
+ # # stringer_parser.rb
299
+ # class StringParser < Sinclair::Caster
300
+ # master_caster!
301
+ #
302
+ # cast_with(JSON) { |value| JSON.parse(value) }
303
+ # cast_with(Integer, :to_i)
304
+ # cast_with(Float, :to_f)
305
+ # end
306
+ #
307
+ # # main.rb
308
+ # StringParser.cast('{"key":"value"}', JSON) # returns { "key" => "value" }
309
+ # StringParser.cast('10.2', Integer) # returns 10
310
+ # StringParser.cast('10.2', Float) # returns 10.2
311
+ #
312
+ # @see Caster::ClassMethods#caster_for
313
+ # @see Caster.cast_with
314
+ # @see Caster.cast
315
+ #
316
+ # @return [Caster]
317
+
318
+ # @param block [Proc] Proc to be used when converting the value object
319
+ def initialize(&block)
320
+ @block = block.to_proc
321
+ end
322
+
323
+ # Cast a value using the given the set +block+
324
+ #
325
+ # @param value [Object] value to be converted
326
+ # @param opts [Hash] options to be sent to the block
327
+ #
328
+ # When the block does not accept options, those
329
+ # are not passed
330
+ #
331
+ # @example Casts from a selected caster
332
+ # # math_caster.rb
333
+ # class MathCaster < Sinclair::Caster
334
+ # cast_with(:float, :to_f)
335
+ #
336
+ # cast_with(:log) do |value, base: 10|
337
+ # value = MathCaster.cast(value, :float)
338
+ #
339
+ # Math.log(value, base)
340
+ # end
341
+ # end
342
+ #
343
+ # # main.rb
344
+ # caster = MathCaster.caster_for(:log)
345
+ #
346
+ # caster.cast(100) # returns 2
347
+ # caster.cast(8, base: 2) # returns 3
348
+ #
349
+ # @return [Object] the result of the converting block
350
+ def cast(value, **opts)
351
+ options = opts.select do |key, _|
352
+ options_keys.include?(key)
353
+ end
354
+
355
+ block.call(value, **options)
356
+ end
357
+
358
+ private
359
+
360
+ # @api private
361
+ # @private
362
+ #
363
+ # Keys of options accepted by the block
364
+ #
365
+ # @return [Array<Symbol>]
366
+ def options_keys
367
+ @options_keys ||= block.parameters.select do |(type, _)|
368
+ %i[key keyreq].include? type
369
+ end.map(&:second)
370
+ end
371
+
372
+ # @method block
373
+ # @api private
374
+ # @private
375
+ #
376
+ # Proc to be used when converting the value object
377
+ #
378
+ # @return [Proc]
379
+ attr_reader :block
380
+ end
381
+ end
@@ -69,22 +69,16 @@ class Sinclair
69
69
  #
70
70
  # config = AppConfig.new
71
71
  #
72
- # config.secret
73
- # # return nil
74
- #
75
- # config.app_name
76
- # # return 'MyApp'
72
+ # config.secret # return nil
73
+ # config.app_name # return 'MyApp'
77
74
  #
78
75
  # config_builder = Sinclair::ConfigBuilder.new(config)
79
76
  #
80
77
  # config_builder.secret '123abc'
81
78
  # config_builder.app_name 'MySuperApp'
82
79
  #
83
- # config.secret
84
- # # return '123abc'
85
- #
86
- # config.app_name
87
- # # return 'MySuperApp'
80
+ # config.secret # return '123abc'
81
+ # config.app_name # return 'MySuperApp'
88
82
  def add_configs(*args)
89
83
  Config::MethodsBuilder.new(self, *args).tap do |builder|
90
84
  builder.build
@@ -8,7 +8,14 @@ class Sinclair
8
8
  # @author darthjee
9
9
  #
10
10
  # Stringgify a value for {StringDefinition}
11
- class Stringifier
11
+ class Stringifier < Caster
12
+ master_caster!
13
+
14
+ cast_with(NilClass) { 'nil' }
15
+ cast_with(Symbol) { |value| ":#{value}" }
16
+ cast_with(String, :to_json)
17
+ cast_with(Object, :to_s)
18
+
12
19
  # Convert a value to a string format
13
20
  #
14
21
  # The returned string can be evaluated as code, returning the
@@ -18,12 +25,7 @@ class Sinclair
18
25
  #
19
26
  # @return [String]
20
27
  def self.value_string(value)
21
- return 'nil' if value.nil?
22
- return ":#{value}" if value.is_a?(Symbol)
23
-
24
- return value.to_s if value.is_any?(Class, Hash, Array)
25
-
26
- value.to_json
28
+ cast(value, value.class)
27
29
  end
28
30
  end
29
31
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Sinclair
4
- VERSION = '1.14.2'
4
+ VERSION = '1.16.0'
5
5
  end