serega 0.15.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.
- checksums.yaml +4 -4
- data/README.md +121 -22
- data/VERSION +1 -1
- data/lib/serega/attribute.rb +5 -5
- data/lib/serega/attribute_normalizer.rb +29 -11
- data/lib/serega/config.rb +1 -1
- data/lib/serega/object_serializer.rb +1 -1
- data/lib/serega/plan.rb +11 -11
- data/lib/serega/plan_point.rb +5 -5
- data/lib/serega/plugins/activerecord_preloads/activerecord_preloads.rb +1 -1
- data/lib/serega/plugins/batch/batch.rb +15 -15
- data/lib/serega/plugins/batch/lib/batch_config.rb +11 -8
- data/lib/serega/plugins/batch/lib/modules/attribute_normalizer.rb +26 -11
- data/lib/serega/plugins/batch/lib/validations/check_batch_opt_key.rb +5 -35
- data/lib/serega/plugins/batch/lib/validations/check_batch_opt_loader.rb +5 -35
- data/lib/serega/plugins/batch/lib/validations/check_opt_batch.rb +2 -2
- data/lib/serega/plugins/camel_case/camel_case.rb +195 -0
- data/lib/serega/plugins/depth_limit/depth_limit.rb +185 -0
- data/lib/serega/plugins/explicit_many_option/explicit_many_option.rb +1 -1
- data/lib/serega/plugins/formatters/formatters.rb +88 -14
- data/lib/serega/plugins/if/if.rb +47 -23
- data/lib/serega/plugins/if/validations/check_opt_if.rb +4 -36
- data/lib/serega/plugins/if/validations/check_opt_if_value.rb +7 -39
- data/lib/serega/plugins/if/validations/check_opt_unless.rb +4 -45
- data/lib/serega/plugins/if/validations/check_opt_unless_value.rb +7 -39
- data/lib/serega/plugins/metadata/meta_attribute.rb +21 -5
- data/lib/serega/plugins/metadata/metadata.rb +22 -13
- data/lib/serega/plugins/metadata/validations/check_block.rb +10 -10
- data/lib/serega/plugins/metadata/validations/check_opt_const.rb +38 -0
- data/lib/serega/plugins/metadata/validations/check_opt_value.rb +61 -0
- data/lib/serega/plugins/metadata/validations/check_opts.rb +24 -10
- data/lib/serega/plugins/preloads/lib/modules/attribute_normalizer.rb +1 -1
- data/lib/serega/plugins/preloads/lib/preload_paths.rb +12 -5
- data/lib/serega/plugins/preloads/lib/preloads_constructor.rb +1 -1
- data/lib/serega/plugins/preloads/preloads.rb +12 -12
- data/lib/serega/plugins/root/root.rb +1 -1
- data/lib/serega/plugins/string_modifiers/string_modifiers.rb +1 -1
- data/lib/serega/utils/params_count.rb +50 -0
- data/lib/serega/utils/to_hash.rb +1 -1
- data/lib/serega/validations/attribute/check_block.rb +4 -5
- data/lib/serega/validations/attribute/check_opt_const.rb +1 -1
- data/lib/serega/validations/attribute/check_opt_delegate.rb +9 -4
- data/lib/serega/validations/attribute/{check_opt_key.rb → check_opt_method.rb} +8 -8
- data/lib/serega/validations/attribute/check_opt_value.rb +17 -13
- data/lib/serega/validations/check_attribute_params.rb +3 -2
- data/lib/serega/validations/check_initiate_params.rb +1 -1
- data/lib/serega/validations/check_serialize_params.rb +1 -1
- data/lib/serega/validations/utils/check_allowed_keys.rb +4 -2
- data/lib/serega/validations/utils/check_extra_keyword_arg.rb +33 -0
- data/lib/serega.rb +26 -11
- metadata +10 -4
data/lib/serega/plugins/if/if.rb
CHANGED
@@ -56,15 +56,16 @@ class Serega
|
|
56
56
|
# @return [void]
|
57
57
|
#
|
58
58
|
def self.load_plugin(serializer_class, **_opts)
|
59
|
-
require_relative "
|
60
|
-
require_relative "
|
61
|
-
require_relative "
|
62
|
-
require_relative "
|
59
|
+
require_relative "validations/check_opt_if"
|
60
|
+
require_relative "validations/check_opt_if_value"
|
61
|
+
require_relative "validations/check_opt_unless"
|
62
|
+
require_relative "validations/check_opt_unless_value"
|
63
63
|
|
64
|
-
serializer_class::SeregaAttribute.include(
|
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(
|
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
|
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 =
|
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
|
-
|
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
|
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
|
34
|
-
|
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
|
-
|
44
|
-
|
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
|
46
|
-
return if
|
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
|
-
|
58
|
-
|
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
|
-
|
63
|
-
|
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
|
-
|
43
|
-
|
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
|
-
|
50
|
-
|
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
|
46
|
-
return if
|
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
|
-
|
58
|
-
|
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
|
-
|
63
|
-
|
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
|
-
|
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
|
-
#
|
14
|
-
# -
|
15
|
-
# -
|
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
|
23
|
-
# meta_attribute(:ab_tests, :names
|
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=>
|
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
|
@@ -62,12 +69,14 @@ class Serega
|
|
62
69
|
serializer_class.include(InstanceMethods)
|
63
70
|
serializer_class::SeregaConfig.include(ConfigInstanceMethods)
|
64
71
|
|
65
|
-
require_relative "
|
66
|
-
require_relative "
|
67
|
-
require_relative "
|
68
|
-
require_relative "
|
69
|
-
require_relative "
|
70
|
-
require_relative "
|
72
|
+
require_relative "meta_attribute"
|
73
|
+
require_relative "validations/check_block"
|
74
|
+
require_relative "validations/check_opt_const"
|
75
|
+
require_relative "validations/check_opt_hide_nil"
|
76
|
+
require_relative "validations/check_opt_hide_empty"
|
77
|
+
require_relative "validations/check_opt_value"
|
78
|
+
require_relative "validations/check_opts"
|
79
|
+
require_relative "validations/check_path"
|
71
80
|
|
72
81
|
meta_attribute_class = Class.new(MetaAttribute)
|
73
82
|
meta_attribute_class.serializer_class = serializer_class
|
@@ -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[
|
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[:
|
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
|
-
|
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
|
-
|
39
|
-
return if (params.count <= 2) && params.all? { |par| ALLOWED_PARAM_TYPES.include?(par[0]) }
|
38
|
+
private
|
40
39
|
|
41
|
-
|
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
|