serega 0.16.0 → 0.17.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 (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