serega 0.16.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +22 -10
  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/plugins/batch/lib/batch_config.rb +11 -8
  7. data/lib/serega/plugins/batch/lib/modules/attribute_normalizer.rb +26 -11
  8. data/lib/serega/plugins/batch/lib/validations/check_batch_opt_key.rb +5 -35
  9. data/lib/serega/plugins/batch/lib/validations/check_batch_opt_loader.rb +5 -35
  10. data/lib/serega/plugins/formatters/formatters.rb +88 -14
  11. data/lib/serega/plugins/if/if.rb +43 -19
  12. data/lib/serega/plugins/if/validations/check_opt_if.rb +4 -36
  13. data/lib/serega/plugins/if/validations/check_opt_if_value.rb +7 -39
  14. data/lib/serega/plugins/if/validations/check_opt_unless.rb +4 -45
  15. data/lib/serega/plugins/if/validations/check_opt_unless_value.rb +7 -39
  16. data/lib/serega/plugins/metadata/meta_attribute.rb +21 -5
  17. data/lib/serega/plugins/metadata/metadata.rb +16 -7
  18. data/lib/serega/plugins/metadata/validations/check_block.rb +10 -10
  19. data/lib/serega/plugins/metadata/validations/check_opt_const.rb +38 -0
  20. data/lib/serega/plugins/metadata/validations/check_opt_value.rb +61 -0
  21. data/lib/serega/plugins/metadata/validations/check_opts.rb +24 -10
  22. data/lib/serega/utils/params_count.rb +50 -0
  23. data/lib/serega/utils/to_hash.rb +1 -1
  24. data/lib/serega/validations/attribute/check_block.rb +4 -5
  25. data/lib/serega/validations/attribute/check_opt_value.rb +16 -12
  26. data/lib/serega/validations/check_attribute_params.rb +1 -0
  27. data/lib/serega/validations/utils/check_extra_keyword_arg.rb +33 -0
  28. data/lib/serega.rb +2 -0
  29. metadata +7 -3
@@ -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
@@ -20,7 +20,7 @@ class Serega
20
20
  # @return [Proc] Meta attribute options
21
21
  attr_reader :opts
22
22
 
23
- # @return [Proc] Meta attribute originally added block
23
+ # @return [Proc,nil] Meta attribute originally added block
24
24
  attr_reader :block
25
25
 
26
26
  #
@@ -39,6 +39,7 @@ class Serega
39
39
  @path = SeregaUtils::EnumDeepDup.call(path)
40
40
  @opts = SeregaUtils::EnumDeepDup.call(opts)
41
41
  @block = block
42
+ @normalized_block = normalize_block(opts[:value], opts[:const], block)
42
43
  end
43
44
 
44
45
  #
@@ -50,19 +51,34 @@ class Serega
50
51
  # @return [Object] Serialized meta attribute value
51
52
  #
52
53
  def value(object, context)
53
- block.call(object, context)
54
+ normalized_block.call(object, context)
54
55
  end
55
56
 
56
57
  def hide?(value)
57
- (opts[:hide_nil] && value.nil?) || (opts[:hide_empty] && value.empty?)
58
+ (!!opts[:hide_nil] && value.nil?) || (!!opts[:hide_empty] && (value.nil? || (value.respond_to?(:empty?) && value.empty?)))
58
59
  end
59
60
 
60
61
  private
61
62
 
63
+ attr_reader :normalized_block
64
+
65
+ def normalize_block(value, const, block)
66
+ return proc { const } if const
67
+
68
+ callable = (value || block)
69
+ params_count = SeregaUtils::ParamsCount.call(callable, max_count: 2)
70
+
71
+ case params_count
72
+ when 0 then proc { callable.call }
73
+ when 1 then proc { |obj| callable.call(obj) }
74
+ else callable
75
+ end
76
+ end
77
+
62
78
  def check(path, opts, block)
63
79
  CheckPath.call(path) if check_attribute_name
64
- CheckOpts.call(opts, attribute_keys)
65
- CheckBlock.call(block)
80
+ CheckOpts.call(opts, block, attribute_keys)
81
+ CheckBlock.call(block) if block
66
82
  end
67
83
 
68
84
  def attribute_keys
@@ -10,17 +10,24 @@ class Serega
10
10
  # Adds ability to describe metadata that must be added to serialized response
11
11
  #
12
12
  # Added class-level method `:meta_attribute`, to define metadata, it accepts:
13
- # - *path [Array<Symbol>] - nested hash keys beginning from the root object.
14
- # - **options [Hash] - defaults are `hide_nil: false, hide_empty: false`
15
- # - &block [Proc] - describes value for current meta attribute
13
+ #
14
+ # - `*path` [Array of Symbols] - nested hash keys.
15
+ # - `**options` [Hash]
16
+ #
17
+ # - `:const` - describes metadata value (if it is constant)
18
+ # - `:value` - describes metadata value as any `#callable` instance
19
+ # - `:hide_nil` - does not show metadata key if value is nil, `false` by default
20
+ # - `:hide_empty`, does not show metadata key if value is nil or empty, `false` by default
21
+ #
22
+ # - `&block` [Proc] - describes value for current meta attribute
16
23
  #
17
24
  # @example
18
25
  # class AppSerializer < Serega
19
26
  # plugin :root
20
27
  # plugin :metadata
21
28
  #
22
- # meta_attribute(:version) { '1.2.3' }
23
- # meta_attribute(:ab_tests, :names) { %i[foo bar] }
29
+ # meta_attribute(:version, const: '1.2.3')
30
+ # meta_attribute(:ab_tests, :names, value: ABTests.new.method(:names))
24
31
  # meta_attribute(:meta, :paging, hide_nil: true) do |records, ctx|
25
32
  # next unless records.respond_to?(:total_count)
26
33
  #
@@ -28,7 +35,7 @@ class Serega
28
35
  # end
29
36
  # end
30
37
  #
31
- # AppSerializer.to_h(nil) # => {:data=>nil, :version=>"1.2.3", :ab_tests=>{:names=>[:foo, :bar]}}
38
+ # AppSerializer.to_h(nil) # => {:data=>nil, :version=>"1.2.3", :ab_tests=>{:names=> ... }}
32
39
  #
33
40
  module Metadata
34
41
  # @return [Symbol] Plugin name
@@ -64,8 +71,10 @@ class Serega
64
71
 
65
72
  require_relative "meta_attribute"
66
73
  require_relative "validations/check_block"
74
+ require_relative "validations/check_opt_const"
67
75
  require_relative "validations/check_opt_hide_nil"
68
76
  require_relative "validations/check_opt_hide_empty"
77
+ require_relative "validations/check_opt_value"
69
78
  require_relative "validations/check_opts"
70
79
  require_relative "validations/check_path"
71
80
 
@@ -83,7 +92,7 @@ class Serega
83
92
  # @return [void]
84
93
  #
85
94
  def self.after_load_plugin(serializer_class, **_opts)
86
- serializer_class.config.opts[:metadata] = {attribute_keys: %i[path hide_nil hide_empty]}
95
+ serializer_class.config.opts[:metadata] = {attribute_keys: %i[const hide_nil hide_empty value]}
87
96
  end
88
97
 
89
98
  #
@@ -8,14 +8,10 @@ class Serega
8
8
  # Validator for meta_attribute block parameter
9
9
  #
10
10
  class CheckBlock
11
- ALLOWED_PARAM_TYPES = %i[opt req]
12
- private_constant :ALLOWED_PARAM_TYPES
13
-
14
11
  class << self
15
12
  #
16
13
  # Checks block provided with attribute
17
- # Block must have up to two arguments - object and context.
18
- # It should not have any *rest or **key arguments
14
+ # Block must have up to two arguments - object(s) and context.
19
15
  #
20
16
  # @example without arguments
21
17
  # metadata(:version) { CONSTANT_VERSION }
@@ -24,7 +20,7 @@ class Serega
24
20
  # metadata(:paging) { |scope| { { page: scope.page, per_page: scope.per_page, total_count: scope.total_count } }
25
21
  #
26
22
  # @example with two arguments
27
- # metadata(:paging) { |scope, context| { { ... } if context[:with_paging] }
23
+ # metadata(:paging) { |scope, context| { { ... } if context[:pagy] }
28
24
  #
29
25
  # @param block [Proc] Block that returns serialized meta attribute value
30
26
  #
@@ -33,12 +29,16 @@ class Serega
33
29
  # @return [void]
34
30
  #
35
31
  def call(block)
36
- raise SeregaError, "Block must be provided when defining meta attribute" unless block
32
+ SeregaValidations::Utils::CheckExtraKeywordArg.call(block, "block")
33
+ params_count = SeregaUtils::ParamsCount.call(block, max_count: 2)
34
+
35
+ raise SeregaError, block_error if params_count > 2
36
+ end
37
37
 
38
- params = block.parameters
39
- return if (params.count <= 2) && params.all? { |par| ALLOWED_PARAM_TYPES.include?(par[0]) }
38
+ private
40
39
 
41
- raise SeregaError, "Block can have maximum 2 regular parameters (no **keyword or *array args)"
40
+ def block_error
41
+ "Block can have maximum two parameters (object(s), context)"
42
42
  end
43
43
  end
44
44
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module SeregaPlugins
5
+ module Metadata
6
+ class MetaAttribute
7
+ #
8
+ # MetaAttribute `:const` option validator
9
+ #
10
+ class CheckOptConst
11
+ class << self
12
+ #
13
+ # Checks meta_attribute :const option
14
+ #
15
+ # @param opts [Hash] MetaAttribute options
16
+ #
17
+ # @raise [SeregaError] validation error
18
+ #
19
+ # @return [void]
20
+ #
21
+ def call(opts, block = nil)
22
+ return unless opts.key?(:const)
23
+
24
+ check_usage_with_other_params(opts, block)
25
+ end
26
+
27
+ private
28
+
29
+ def check_usage_with_other_params(opts, block)
30
+ raise SeregaError, "Option :const can not be used together with option :value" if opts.key?(:value)
31
+ raise SeregaError, "Option :const can not be used together with block" if block
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module SeregaPlugins
5
+ module Metadata
6
+ class MetaAttribute
7
+ #
8
+ # Validator for meta_attribute :value option
9
+ #
10
+ class CheckOptValue
11
+ class << self
12
+ #
13
+ # Checks attribute :value option
14
+ #
15
+ # @param opts [Hash] Attribute options
16
+ #
17
+ # @raise [SeregaError] SeregaError that option has invalid value
18
+ #
19
+ # @return [void]
20
+ #
21
+ def call(opts, block = nil)
22
+ return unless opts.key?(:value)
23
+
24
+ check_usage_with_other_params(opts, block)
25
+
26
+ check_value(opts[:value])
27
+ end
28
+
29
+ private
30
+
31
+ def check_usage_with_other_params(opts, block)
32
+ raise SeregaError, "Option :value can not be used together with option :const" if opts.key?(:const)
33
+ raise SeregaError, "Option :value can not be used together with block" if block
34
+ end
35
+
36
+ def check_value(value)
37
+ check_value_type(value)
38
+
39
+ SeregaValidations::Utils::CheckExtraKeywordArg.call(value, ":value option")
40
+ params_count = SeregaUtils::ParamsCount.call(value, max_count: 2)
41
+
42
+ raise SeregaError, params_count_error if params_count > 2
43
+ end
44
+
45
+ def check_value_type(value)
46
+ raise SeregaError, type_error if !value.is_a?(Proc) && !value.respond_to?(:call)
47
+ end
48
+
49
+ def type_error
50
+ "Option :value value must be a Proc or respond to #call"
51
+ end
52
+
53
+ def params_count_error
54
+ "Option :value value can have maximum 2 parameters (object(s), context)"
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -10,31 +10,45 @@ class Serega
10
10
  class CheckOpts
11
11
  class << self
12
12
  #
13
- # Validates attribute options
13
+ # Validates meta_attribute options
14
14
  # Checks used options are allowed and then checks options values.
15
15
  #
16
16
  # @param opts [Hash] Attribute options
17
- # @param attribute_keys [Array<Symbol>] Allowed options keys
17
+ # @param block [Proc] Attribute block
18
+ # @param allowed_keys [Array<Symbol>] Allowed options keys
18
19
  #
19
20
  # @raise [SeregaError] when attribute has invalid options
20
21
  #
21
22
  # @return [void]
22
23
  #
23
- def call(opts, attribute_keys)
24
+ def call(opts, block, allowed_keys)
25
+ check_allowed_options_keys(opts, allowed_keys)
26
+ check_each_opt(opts, block)
27
+ check_any_value_provided(opts, block)
28
+ end
29
+
30
+ private
31
+
32
+ def check_allowed_options_keys(opts, allowed_keys)
24
33
  opts.each_key do |key|
25
- next if attribute_keys.include?(key.to_sym)
34
+ next if allowed_keys.include?(key.to_sym)
26
35
 
27
- raise SeregaError, "Invalid option #{key.inspect}. Allowed options are: #{attribute_keys.map(&:inspect).join(", ")}"
36
+ allowed = allowed_keys.map(&:inspect).join(", ")
37
+ raise SeregaError, "Invalid option #{key.inspect}. Allowed options are: #{allowed}"
28
38
  end
29
-
30
- check_each_opt(opts)
31
39
  end
32
40
 
33
- private
34
-
35
- def check_each_opt(opts)
41
+ def check_each_opt(opts, block)
36
42
  CheckOptHideEmpty.call(opts)
37
43
  CheckOptHideNil.call(opts)
44
+ CheckOptValue.call(opts, block)
45
+ CheckOptConst.call(opts, block)
46
+ end
47
+
48
+ def check_any_value_provided(opts, block)
49
+ return if opts.key?(:const) || opts.key?(:value) || block
50
+
51
+ raise SeregaError, "Please provide block argument or add :value or :const option"
38
52
  end
39
53
  end
40
54
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ #
5
+ # Utilities
6
+ #
7
+ module SeregaUtils
8
+ #
9
+ # Utility to count regular parameters of callable object
10
+ #
11
+ class ParamsCount
12
+ NO_NAMED_REST_PARAM = [:rest].freeze
13
+ private_constant :NO_NAMED_REST_PARAM
14
+
15
+ class << self
16
+ #
17
+ # Count parameters for callable object
18
+ #
19
+ # @param object [#call] callable object
20
+ #
21
+ # @return [Integer] count of regular parameters
22
+ #
23
+ def call(object, max_count:)
24
+ # Procs (but not lambdas) can accept all provided parameters
25
+ parameters = object.is_a?(Proc) ? object.parameters : object.method(:call).parameters
26
+ return 1 if parameters[0] == NO_NAMED_REST_PARAM
27
+ return max_count if object.is_a?(Proc) && !object.lambda?
28
+
29
+ count = 0
30
+
31
+ # If all we have is no-name *rest parameters, then we assume we need to provide
32
+ # 1 argument. It is now always correct, but in serialization context it's most common that
33
+ # only one argument is needed.
34
+ parameters.each do |parameter|
35
+ next if parameter == NO_NAMED_REST_PARAM # Workaround for procs like :odd?.to_proc
36
+ param_type = parameter[0]
37
+
38
+ case param_type
39
+ when :req then count += 1
40
+ when :opt then count += 1 if count < max_count
41
+ when :rest then count += max_count - count if max_count > count
42
+ end # else :opt, :keyreq, :key, :keyrest, :block - do nothing
43
+ end
44
+
45
+ count
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -31,7 +31,7 @@ class Serega
31
31
  when NilClass, FalseClass then nil_to_hash(value)
32
32
  when String then string_to_hash(value)
33
33
  when Symbol then symbol_to_hash(value)
34
- else raise SeregaError, "Cant convert #{value.class} class object to hash"
34
+ else raise SeregaError, "Can't convert #{value.class} class object to hash"
35
35
  end
36
36
  end
37
37
 
@@ -14,7 +14,6 @@ class Serega
14
14
  #
15
15
  # Checks block parameter provided with attribute.
16
16
  # Must have up to two arguments - object and context.
17
- # It should not have any *rest or **key arguments
18
17
  #
19
18
  # @example without arguments
20
19
  # attribute(:email) { CONSTANT_EMAIL }
@@ -40,14 +39,14 @@ class Serega
40
39
  private
41
40
 
42
41
  def check_block(block)
43
- params = block.parameters
44
- return if (params.count <= 2) && params.all? { |par| par[0] == :opt }
42
+ SeregaValidations::Utils::CheckExtraKeywordArg.call(block, "block")
43
+ params_count = SeregaUtils::ParamsCount.call(block, max_count: 2)
45
44
 
46
- raise SeregaError, block_error
45
+ raise SeregaError, block_error if params_count > 2
47
46
  end
48
47
 
49
48
  def block_error
50
- "Block can have maximum two regular parameters (no **keyword or *array args)"
49
+ "Block can have maximum two parameters (object, context)"
51
50
  end
52
51
  end
53
52
  end
@@ -21,7 +21,8 @@ class Serega
21
21
  return unless opts.key?(:value)
22
22
 
23
23
  check_usage_with_other_params(opts, block)
24
- check_proc(opts[:value])
24
+
25
+ check_value(opts[:value])
25
26
  end
26
27
 
27
28
  private
@@ -32,22 +33,25 @@ class Serega
32
33
  raise SeregaError, "Option :value can not be used together with block" if block
33
34
  end
34
35
 
35
- def check_proc(value)
36
- raise SeregaError, value_error unless value.is_a?(Proc)
36
+ def check_value(value)
37
+ check_value_type(value)
38
+
39
+ SeregaValidations::Utils::CheckExtraKeywordArg.call(value, ":value option")
40
+ params_count = SeregaUtils::ParamsCount.call(value, max_count: 2)
37
41
 
38
- params = value.parameters
42
+ raise SeregaError, params_count_error if params_count > 2
43
+ end
39
44
 
40
- if value.lambda?
41
- return if (params.count == 2) && params.all? { |par| par[0] == :req }
42
- elsif (params.count <= 2) && params.all? { |par| par[0] == :opt }
43
- return
44
- end
45
+ def check_value_type(value)
46
+ raise SeregaError, type_error if !value.is_a?(Proc) && !value.respond_to?(:call)
47
+ end
45
48
 
46
- raise SeregaError, value_error
49
+ def type_error
50
+ "Option :value value must be a Proc or respond to #call"
47
51
  end
48
52
 
49
- def value_error
50
- "Option :value must be a Proc that is able to accept two parameters (no **keyword or *array args)"
53
+ def params_count_error
54
+ "Option :value value can have maximum 2 parameters (object, context)"
51
55
  end
52
56
  end
53
57
  end
@@ -55,6 +55,7 @@ class Serega
55
55
  # Patched in:
56
56
  # - plugin :batch (checks :batch option)
57
57
  # - plugin :context_metadata (checks context metadata option which is :meta by default)
58
+ # - plugin :formatters (checks :format option)
58
59
  # - plugin :if (checks :if, :if_value, :unless, :unless_value options)
59
60
  # - plugin :preloads (checks :preload option)
60
61
  def check_opts