serega 0.16.0 → 0.18.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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +145 -86
  3. data/VERSION +1 -1
  4. data/lib/serega/attribute.rb +3 -3
  5. data/lib/serega/attribute_normalizer.rb +21 -2
  6. data/lib/serega/object_serializer.rb +1 -1
  7. data/lib/serega/plugins/batch/batch.rb +11 -56
  8. data/lib/serega/plugins/batch/lib/batch_config.rb +22 -27
  9. data/lib/serega/plugins/batch/lib/modules/attribute_normalizer.rb +27 -12
  10. data/lib/serega/plugins/batch/lib/modules/object_serializer.rb +2 -2
  11. data/lib/serega/plugins/batch/lib/modules/plan_point.rb +2 -19
  12. data/lib/serega/plugins/batch/lib/validations/check_batch_opt_id_method.rb +43 -0
  13. data/lib/serega/plugins/batch/lib/validations/check_batch_opt_loader.rb +17 -31
  14. data/lib/serega/plugins/batch/lib/validations/check_opt_batch.rb +10 -11
  15. data/lib/serega/plugins/formatters/formatters.rb +88 -14
  16. data/lib/serega/plugins/if/if.rb +43 -19
  17. data/lib/serega/plugins/if/validations/check_opt_if.rb +4 -36
  18. data/lib/serega/plugins/if/validations/check_opt_if_value.rb +7 -39
  19. data/lib/serega/plugins/if/validations/check_opt_unless.rb +4 -45
  20. data/lib/serega/plugins/if/validations/check_opt_unless_value.rb +7 -39
  21. data/lib/serega/plugins/metadata/meta_attribute.rb +21 -5
  22. data/lib/serega/plugins/metadata/metadata.rb +16 -7
  23. data/lib/serega/plugins/metadata/validations/check_block.rb +10 -10
  24. data/lib/serega/plugins/metadata/validations/check_opt_const.rb +38 -0
  25. data/lib/serega/plugins/metadata/validations/check_opt_value.rb +61 -0
  26. data/lib/serega/plugins/metadata/validations/check_opts.rb +24 -10
  27. data/lib/serega/utils/params_count.rb +50 -0
  28. data/lib/serega/utils/to_hash.rb +1 -1
  29. data/lib/serega/validations/attribute/check_block.rb +4 -5
  30. data/lib/serega/validations/attribute/check_opt_value.rb +16 -12
  31. data/lib/serega/validations/check_attribute_params.rb +1 -0
  32. data/lib/serega/validations/utils/check_extra_keyword_arg.rb +33 -0
  33. data/lib/serega.rb +2 -0
  34. metadata +8 -4
  35. data/lib/serega/plugins/batch/lib/validations/check_batch_opt_key.rb +0 -73
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module SeregaPlugins
5
+ module Batch
6
+ #
7
+ # Validator for option :id_method in attribute :batch option
8
+ #
9
+ class CheckBatchOptIdMethod
10
+ class << self
11
+ #
12
+ # Checks option :id_method of attribute :batch option
13
+ #
14
+ # @param id [nil, #call] Attribute :batch option :id_method
15
+ #
16
+ # @raise [SeregaError] validation error
17
+ #
18
+ # @return [void]
19
+ #
20
+ def call(id)
21
+ return if id.is_a?(Symbol)
22
+
23
+ raise SeregaError, must_be_callable unless id.respond_to?(:call)
24
+
25
+ SeregaValidations::Utils::CheckExtraKeywordArg.call(id, "batch option :id_method")
26
+ params_count = SeregaUtils::ParamsCount.call(id, max_count: 2)
27
+ raise SeregaError, params_count_error if params_count > 2
28
+ end
29
+
30
+ private
31
+
32
+ def params_count_error
33
+ "Invalid :batch option :id_method. It can accept maximum 2 parameters (object, context)"
34
+ end
35
+
36
+ def must_be_callable
37
+ "Invalid :batch option :id_method. It must be a Symbol, a Proc or respond to #call"
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -17,13 +17,9 @@ class Serega
17
17
  #
18
18
  # @return [void]
19
19
  #
20
- def call(loader)
21
- return if loader.is_a?(Symbol)
22
-
23
- raise SeregaError, must_be_callable unless loader.respond_to?(:call)
24
-
25
- if loader.is_a?(Proc)
26
- check_block(loader)
20
+ def call(loader, serializer_class)
21
+ if loader.is_a?(Symbol)
22
+ check_symbol(loader, serializer_class)
27
23
  else
28
24
  check_callable(loader)
29
25
  end
@@ -31,36 +27,26 @@ class Serega
31
27
 
32
28
  private
33
29
 
34
- def check_block(block)
35
- return if valid_parameters?(block, accepted_count: 0..3)
36
-
37
- raise SeregaError, block_parameters_error
38
- end
39
-
40
- def check_callable(callable)
41
- return if valid_parameters?(callable.method(:call), accepted_count: 3..3)
30
+ def check_symbol(loader_name, serializer_class)
31
+ defined_loaders = serializer_class.config.batch.loaders
32
+ return if defined_loaders[loader_name]
42
33
 
43
- raise SeregaError, callable_parameters_error
34
+ raise SeregaError, <<~ERR.strip
35
+ Please define loader before adding it to attribute.
36
+ Example: `config.batch.define(:#{loader_name}) { |ids| ... }`
37
+ ERR
44
38
  end
45
39
 
46
- def valid_parameters?(data, accepted_count:)
47
- params = data.parameters
48
- accepted_count.include?(params.count) && valid_parameters_types?(params)
49
- end
50
-
51
- def valid_parameters_types?(params)
52
- params.all? do |param|
53
- type = param[0]
54
- (type == :req) || (type == :opt)
55
- end
56
- end
40
+ def check_callable(loader)
41
+ raise SeregaError, must_be_callable unless loader.respond_to?(:call)
57
42
 
58
- def block_parameters_error
59
- "Invalid :batch option :loader. When it is a Proc it can have maximum three regular parameters (keys, context, point)"
43
+ SeregaValidations::Utils::CheckExtraKeywordArg.call(loader, ":batch option :loader")
44
+ params_count = SeregaUtils::ParamsCount.call(loader, max_count: 3)
45
+ raise SeregaError, params_count_error if params_count > 3
60
46
  end
61
47
 
62
- def callable_parameters_error
63
- "Invalid :batch option :loader. When it is a callable object it must have three regular parameters (keys, context, point)"
48
+ def params_count_error
49
+ "Invalid :batch option :loader. It can accept maximum 3 parameters (ids, context, plan)"
64
50
  end
65
51
 
66
52
  def must_be_callable
@@ -23,30 +23,29 @@ class Serega
23
23
  SeregaValidations::Utils::CheckOptIsHash.call(opts, :batch)
24
24
 
25
25
  batch = opts[:batch]
26
- SeregaValidations::Utils::CheckAllowedKeys.call(batch, %i[key loader default], :batch)
27
-
28
- check_batch_opt_key(batch, serializer_class)
29
- check_batch_opt_loader(batch)
26
+ SeregaValidations::Utils::CheckAllowedKeys.call(batch, %i[id_method loader default], :batch)
30
27
 
28
+ check_batch_opt_id_method(batch, serializer_class)
29
+ check_batch_opt_loader(batch, serializer_class)
31
30
  check_usage_with_other_params(opts, block)
32
31
  end
33
32
 
34
33
  private
35
34
 
36
- def check_batch_opt_key(batch, serializer_class)
37
- return if !batch.key?(:key) && serializer_class.config.batch.default_key
35
+ def check_batch_opt_id_method(batch, serializer_class)
36
+ return if !batch.key?(:id_method) && serializer_class.config.batch.id_method
38
37
 
39
- key = batch[:key]
40
- raise SeregaError, "Option :key must present inside :batch option" unless key
38
+ id_method = batch[:id_method]
39
+ raise SeregaError, "Option :id_method must present inside :batch option" unless id_method
41
40
 
42
- CheckBatchOptKey.call(key)
41
+ CheckBatchOptIdMethod.call(id_method)
43
42
  end
44
43
 
45
- def check_batch_opt_loader(batch)
44
+ def check_batch_opt_loader(batch, serializer_class)
46
45
  loader = batch[:loader]
47
46
  raise SeregaError, "Option :loader must present inside :batch option" unless loader
48
47
 
49
- CheckBatchOptLoader.call(loader)
48
+ CheckBatchOptLoader.call(loader, serializer_class)
50
49
  end
51
50
 
52
51
  def check_usage_with_other_params(opts, block)
@@ -11,12 +11,15 @@ class Serega
11
11
  #
12
12
  # Attribute option `:format` now can be used with name of formatter or with callable instance.
13
13
  #
14
+ # Formatters can accept up to 2 parameters (formatted object, context)
15
+ #
14
16
  # @example
15
17
  # class AppSerializer < Serega
16
18
  # plugin :formatters, formatters: {
17
19
  # iso8601: ->(value) { time.iso8601.round(6) },
18
20
  # on_off: ->(value) { value ? 'ON' : 'OFF' },
19
21
  # money: ->(value) { value.round(2) }
22
+ # date: DateTypeFormatter # callable
20
23
  # }
21
24
  # end
22
25
  #
@@ -35,6 +38,7 @@ class Serega
35
38
  # attribute :updated_at, format: :iso8601
36
39
  #
37
40
  # # Using `callable` formatter
41
+ # attribute :score_percent, format: PercentFormmatter # callable class
38
42
  # attribute :score_percent, format: proc { |percent| "#{percent.round(2)}%" }
39
43
  # end
40
44
  #
@@ -68,6 +72,7 @@ class Serega
68
72
  def self.load_plugin(serializer_class, **_opts)
69
73
  serializer_class::SeregaConfig.include(ConfigInstanceMethods)
70
74
  serializer_class::SeregaAttributeNormalizer.include(AttributeNormalizerInstanceMethods)
75
+ serializer_class::CheckAttributeParams.include(CheckAttributeParamsInstanceMethods)
71
76
  end
72
77
 
73
78
  #
@@ -107,6 +112,7 @@ class Serega
107
112
  # @return [void]
108
113
  def add(formatters)
109
114
  formatters.each_pair do |key, value|
115
+ CheckFormatter.call(key, value)
110
116
  opts[key] = value
111
117
  end
112
118
  end
@@ -124,6 +130,21 @@ class Serega
124
130
  end
125
131
  end
126
132
 
133
+ #
134
+ # Serega::SeregaValidations::CheckAttributeParams additional/patched class methods
135
+ #
136
+ # @see Serega::SeregaValidations::CheckAttributeParams
137
+ #
138
+ module CheckAttributeParamsInstanceMethods
139
+ private
140
+
141
+ def check_opts
142
+ super
143
+
144
+ CheckOptFormat.call(opts, self.class.serializer_class)
145
+ end
146
+ end
147
+
127
148
  #
128
149
  # Attribute class additional/patched instance methods
129
150
  #
@@ -143,16 +164,10 @@ class Serega
143
164
  def prepare_value_block
144
165
  return super unless formatter
145
166
 
146
- if init_opts.key?(:const)
147
- # Format const value in advance
148
- const_value = formatter.call(init_opts[:const])
149
- proc { const_value }
150
- else
151
- # Wrap original block into formatter block
152
- proc do |object, context|
153
- value = super.call(object, context)
154
- formatter.call(value)
155
- end
167
+ # Wrap original block into formatter block
168
+ proc do |object, context|
169
+ value = super.call(object, context)
170
+ formatter.call(value, context)
156
171
  end
157
172
  end
158
173
 
@@ -160,10 +175,69 @@ class Serega
160
175
  formatter = init_opts[:format]
161
176
  return unless formatter
162
177
 
163
- if formatter.is_a?(Symbol)
164
- self.class.serializer_class.config.formatters.opts.fetch(formatter)
165
- else
166
- formatter # already callable
178
+ formatter = self.class.serializer_class.config.formatters.opts.fetch(formatter) if formatter.is_a?(Symbol)
179
+ prepare_callable_proc(formatter)
180
+ end
181
+ end
182
+
183
+ #
184
+ # Validator for attribute :format option
185
+ #
186
+ class CheckOptFormat
187
+ class << self
188
+ #
189
+ # Checks attribute :format option must be registered or valid callable with maximum 2 args
190
+ #
191
+ # @param opts [value] Attribute options
192
+ #
193
+ # @raise [SeregaError] Attribute validation error
194
+ #
195
+ # @return [void]
196
+ #
197
+ def call(opts, serializer_class)
198
+ return unless opts.key?(:format)
199
+
200
+ formatter = opts[:format]
201
+
202
+ if formatter.is_a?(Symbol)
203
+ check_formatter_defined(serializer_class, formatter)
204
+ else
205
+ CheckFormatter.call(:format, formatter)
206
+ end
207
+ end
208
+
209
+ private
210
+
211
+ def check_formatter_defined(serializer_class, formatter)
212
+ return if serializer_class.config.formatters.opts.key?(formatter)
213
+
214
+ raise Serega::SeregaError, "Formatter `#{formatter.inspect}` was not defined"
215
+ end
216
+ end
217
+ end
218
+
219
+ #
220
+ # Validator for formatters defined as config options or directly as attribute :format option
221
+ #
222
+ class CheckFormatter
223
+ class << self
224
+ #
225
+ # Check formatter type and parameters
226
+ #
227
+ # @param formatter_name [Symbol] Name of formatter
228
+ # @param formatter [#call] Formatter callable object
229
+ #
230
+ # @return [void]
231
+ #
232
+ def call(formatter_name, formatter)
233
+ raise Serega::SeregaError, "Option #{formatter_name.inspect} must have callable value" unless formatter.respond_to?(:call)
234
+
235
+ SeregaValidations::Utils::CheckExtraKeywordArg.call(formatter, "#{formatter_name.inspect} value")
236
+ params_count = SeregaUtils::ParamsCount.call(formatter, max_count: 2)
237
+
238
+ if params_count > 2
239
+ raise SeregaError, "Formatter can have maximum 2 parameters (value to format, context)"
240
+ end
167
241
  end
168
242
  end
169
243
  end
@@ -61,10 +61,11 @@ class Serega
61
61
  require_relative "validations/check_opt_unless"
62
62
  require_relative "validations/check_opt_unless_value"
63
63
 
64
- serializer_class::SeregaAttribute.include(SeregaAttributeInstanceMethods)
64
+ serializer_class::SeregaAttribute.include(AttributeInstanceMethods)
65
+ serializer_class::SeregaAttributeNormalizer.include(AttributeNormalizerInstanceMethods)
65
66
  serializer_class::SeregaPlanPoint.include(PlanPointInstanceMethods)
66
67
  serializer_class::CheckAttributeParams.include(CheckAttributeParamsInstanceMethods)
67
- serializer_class::SeregaObjectSerializer.include(SeregaObjectSerializerInstanceMethods)
68
+ serializer_class::SeregaObjectSerializer.include(ObjectSerializerInstanceMethods)
68
69
  end
69
70
 
70
71
  #
@@ -79,12 +80,47 @@ class Serega
79
80
  serializer_class.config.attribute_keys << :if << :if_value << :unless << :unless_value
80
81
  end
81
82
 
83
+ #
84
+ # SeregaAttributeNormalizer additional/patched instance methods
85
+ #
86
+ # @see SeregaAttributeNormalizer::AttributeInstanceMethods
87
+ #
88
+ module AttributeNormalizerInstanceMethods
89
+ #
90
+ # Returns prepared attribute :if_options.
91
+ #
92
+ # @return [Hash] prepared options for :if plugin
93
+ #
94
+ def if_options
95
+ @if_options ||= {
96
+ if: prepare_if_option(init_opts[:if]),
97
+ unless: prepare_if_option(init_opts[:unless]),
98
+ if_value: prepare_if_option(init_opts[:if_value]),
99
+ unless_value: prepare_if_option(init_opts[:unless_value])
100
+ }.freeze
101
+ end
102
+
103
+ private
104
+
105
+ def prepare_if_option(if_option)
106
+ return unless if_option
107
+ return proc { |val| val.public_send(if_option) } if if_option.is_a?(Symbol)
108
+
109
+ params_count = SeregaUtils::ParamsCount.call(if_option, max_count: 2)
110
+ case params_count
111
+ when 0 then proc { if_option.call }
112
+ when 1 then proc { |obj| if_option.call(obj) }
113
+ else if_option
114
+ end
115
+ end
116
+ end
117
+
82
118
  #
83
119
  # SeregaAttribute additional/patched instance methods
84
120
  #
85
121
  # @see Serega::SeregaAttribute
86
122
  #
87
- module SeregaAttributeInstanceMethods
123
+ module AttributeInstanceMethods
88
124
  # @return provided :if options
89
125
  attr_reader :opt_if
90
126
 
@@ -92,7 +128,7 @@ class Serega
92
128
 
93
129
  def set_normalized_vars(normalizer)
94
130
  super
95
- @opt_if = initials[:opts].slice(:if, :if_value, :unless, :unless_value).freeze
131
+ @opt_if = normalizer.if_options
96
132
  end
97
133
  end
98
134
 
@@ -125,20 +161,8 @@ class Serega
125
161
  opt_unless = attribute.opt_if[opt_unless_name]
126
162
  return true if opt_if.nil? && opt_unless.nil?
127
163
 
128
- res_if =
129
- case opt_if
130
- when NilClass then true
131
- when Symbol then obj.public_send(opt_if)
132
- else opt_if.call(obj, ctx)
133
- end
134
-
135
- res_unless =
136
- case opt_unless
137
- when NilClass then true
138
- when Symbol then !obj.public_send(opt_unless)
139
- else !opt_unless.call(obj, ctx)
140
- end
141
-
164
+ res_if = opt_if ? opt_if.call(obj, ctx) : true
165
+ res_unless = opt_unless ? !opt_unless.call(obj, ctx) : true
142
166
  res_if && res_unless
143
167
  end
144
168
  end
@@ -166,7 +190,7 @@ class Serega
166
190
  #
167
191
  # @see Serega::SeregaObjectSerializer
168
192
  #
169
- module SeregaObjectSerializerInstanceMethods
193
+ module ObjectSerializerInstanceMethods
170
194
  private
171
195
 
172
196
  def serialize_point(object, point, _container)
@@ -27,48 +27,16 @@ class Serega
27
27
 
28
28
  def check_type(value)
29
29
  return if value.is_a?(Symbol)
30
-
31
30
  raise SeregaError, must_be_callable unless value.respond_to?(:call)
32
31
 
33
- if value.is_a?(Proc)
34
- check_block(value)
35
- else
36
- check_callable(value)
37
- end
38
- end
39
-
40
- def check_block(block)
41
- return if valid_parameters?(block, accepted_count: 0..2)
32
+ SeregaValidations::Utils::CheckExtraKeywordArg.call(value, ":if option")
33
+ params_count = SeregaUtils::ParamsCount.call(value, max_count: 2)
42
34
 
43
- raise SeregaError, block_parameters_error
44
- end
45
-
46
- def check_callable(callable)
47
- return if valid_parameters?(callable.method(:call), accepted_count: 2..2)
48
-
49
- raise SeregaError, callable_parameters_error
50
- end
51
-
52
- def valid_parameters?(data, accepted_count:)
53
- params = data.parameters
54
- accepted_count.include?(params.count) && valid_parameters_types?(params)
55
- end
56
-
57
- def valid_parameters_types?(params)
58
- params.all? do |param|
59
- type = param[0]
60
- (type == :req) || (type == :opt)
35
+ if params_count > 2
36
+ raise SeregaError, "Option :if value should have up to 2 parameters (object, context)"
61
37
  end
62
38
  end
63
39
 
64
- def block_parameters_error
65
- "Invalid attribute option :if. When it is a Proc it can have maximum two regular parameters (object, context)"
66
- end
67
-
68
- def callable_parameters_error
69
- "Invalid attribute option :if. When it is a callable object it must have two regular parameters (object, context)"
70
- end
71
-
72
40
  def must_be_callable
73
41
  "Invalid attribute option :if. It must be a Symbol, a Proc or respond to :call"
74
42
  end
@@ -26,54 +26,22 @@ class Serega
26
26
 
27
27
  private
28
28
 
29
- def check_type(value)
30
- return if value.is_a?(Symbol)
31
-
32
- raise SeregaError, must_be_callable unless value.respond_to?(:call)
33
-
34
- if value.is_a?(Proc)
35
- check_block(value)
36
- else
37
- check_callable(value)
38
- end
39
- end
40
-
41
29
  def check_usage_with_other_params(opts)
42
30
  raise SeregaError, "Option :if_value can not be used together with option :serializer" if opts.key?(:serializer)
43
31
  end
44
32
 
45
- def check_block(block)
46
- return if valid_parameters?(block, accepted_count: 0..2)
47
-
48
- raise SeregaError, block_parameters_error
49
- end
50
-
51
- def check_callable(callable)
52
- return if valid_parameters?(callable.method(:call), accepted_count: 2..2)
53
-
54
- raise SeregaError, callable_parameters_error
55
- end
33
+ def check_type(value)
34
+ return if value.is_a?(Symbol)
35
+ raise SeregaError, must_be_callable unless value.respond_to?(:call)
56
36
 
57
- def valid_parameters?(data, accepted_count:)
58
- params = data.parameters
59
- accepted_count.include?(params.count) && valid_parameters_types?(params)
60
- end
37
+ SeregaValidations::Utils::CheckExtraKeywordArg.call(value, ":if_value option")
38
+ params_count = SeregaUtils::ParamsCount.call(value, max_count: 2)
61
39
 
62
- def valid_parameters_types?(params)
63
- params.all? do |param|
64
- type = param[0]
65
- (type == :req) || (type == :opt)
40
+ if params_count > 2
41
+ raise SeregaError, "Option :if_value value should have up to 2 parameters (value, context)"
66
42
  end
67
43
  end
68
44
 
69
- def block_parameters_error
70
- "Invalid attribute option :if_value. When it is a Proc it can have maximum two regular parameters (object, context)"
71
- end
72
-
73
- def callable_parameters_error
74
- "Invalid attribute option :if_value. When it is a callable object it must have two regular parameters (object, context)"
75
- end
76
-
77
45
  def must_be_callable
78
46
  "Invalid attribute option :if_value. It must be a Symbol, a Proc or respond to :call"
79
47
  end
@@ -25,59 +25,18 @@ class Serega
25
25
 
26
26
  private
27
27
 
28
- #
29
- # Checks attribute :unless option
30
- #
31
- # @param value [nil, Symbol, Proc, #call] Attribute :unless option
32
- #
33
- # @raise [SeregaError] validation error
34
- #
35
- # @return [void]
36
- #
37
28
  def check_type(value)
38
29
  return if value.is_a?(Symbol)
39
-
40
30
  raise SeregaError, must_be_callable unless value.respond_to?(:call)
41
31
 
42
- if value.is_a?(Proc)
43
- check_block(value)
44
- else
45
- check_callable(value)
46
- end
47
- end
32
+ SeregaValidations::Utils::CheckExtraKeywordArg.call(value, ":unless option")
33
+ params_count = SeregaUtils::ParamsCount.call(value, max_count: 2)
48
34
 
49
- def check_block(block)
50
- return if valid_parameters?(block, accepted_count: 0..2)
51
-
52
- raise SeregaError, block_parameters_error
53
- end
54
-
55
- def check_callable(callable)
56
- return if valid_parameters?(callable.method(:call), accepted_count: 2..2)
57
-
58
- raise SeregaError, callable_parameters_error
59
- end
60
-
61
- def valid_parameters?(data, accepted_count:)
62
- params = data.parameters
63
- accepted_count.include?(params.count) && valid_parameters_types?(params)
64
- end
65
-
66
- def valid_parameters_types?(params)
67
- params.all? do |param|
68
- type = param[0]
69
- (type == :req) || (type == :opt)
35
+ if params_count > 2
36
+ raise SeregaError, "Option :unless value should have up to 2 parameters (object, context)"
70
37
  end
71
38
  end
72
39
 
73
- def block_parameters_error
74
- "Invalid attribute option :unless. When it is a Proc it can have maximum two regular parameters (object, context)"
75
- end
76
-
77
- def callable_parameters_error
78
- "Invalid attribute option :unless. When it is a callable object it must have two regular parameters (object, context)"
79
- end
80
-
81
40
  def must_be_callable
82
41
  "Invalid attribute option :unless. It must be a Symbol, a Proc or respond to :call"
83
42
  end
@@ -26,54 +26,22 @@ class Serega
26
26
 
27
27
  private
28
28
 
29
- def check_type(value)
30
- return if value.is_a?(Symbol)
31
-
32
- raise SeregaError, must_be_callable unless value.respond_to?(:call)
33
-
34
- if value.is_a?(Proc)
35
- check_block(value)
36
- else
37
- check_callable(value)
38
- end
39
- end
40
-
41
29
  def check_usage_with_other_params(opts)
42
30
  raise SeregaError, "Option :unless_value can not be used together with option :serializer" if opts.key?(:serializer)
43
31
  end
44
32
 
45
- def check_block(block)
46
- return if valid_parameters?(block, accepted_count: 0..2)
47
-
48
- raise SeregaError, block_parameters_error
49
- end
50
-
51
- def check_callable(callable)
52
- return if valid_parameters?(callable.method(:call), accepted_count: 2..2)
53
-
54
- raise SeregaError, callable_parameters_error
55
- end
33
+ def check_type(value)
34
+ return if value.is_a?(Symbol)
35
+ raise SeregaError, must_be_callable unless value.respond_to?(:call)
56
36
 
57
- def valid_parameters?(data, accepted_count:)
58
- params = data.parameters
59
- accepted_count.include?(params.count) && valid_parameters_types?(params)
60
- end
37
+ SeregaValidations::Utils::CheckExtraKeywordArg.call(value, ":unless_value option")
38
+ params_count = SeregaUtils::ParamsCount.call(value, max_count: 2)
61
39
 
62
- def valid_parameters_types?(params)
63
- params.all? do |param|
64
- type = param[0]
65
- (type == :req) || (type == :opt)
40
+ if params_count > 2
41
+ raise SeregaError, "Option :unless_value value should have up to 2 parameters (value, context)"
66
42
  end
67
43
  end
68
44
 
69
- def block_parameters_error
70
- "Invalid attribute option :unless_value. When it is a Proc it can have maximum two regular parameters (object, context)"
71
- end
72
-
73
- def callable_parameters_error
74
- "Invalid attribute option :unless_value. When it is a callable object it must have two regular parameters (object, context)"
75
- end
76
-
77
45
  def must_be_callable
78
46
  "Invalid attribute option :unless_value. It must be a Symbol, a Proc or respond to :call"
79
47
  end