serega 0.6.1 → 0.7.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/VERSION +1 -1
- data/lib/serega/attribute.rb +2 -2
- data/lib/serega/config.rb +23 -1
- data/lib/serega/errors.rb +8 -5
- data/lib/serega/helpers/serializer_class_helper.rb +5 -0
- data/lib/serega/json/adapter.rb +6 -0
- data/lib/serega/json/json.rb +20 -0
- data/lib/serega/json/oj.rb +20 -0
- data/lib/serega/map.rb +17 -0
- data/lib/serega/map_point.rb +36 -1
- data/lib/serega/object_serializer.rb +17 -4
- data/lib/serega/plugins/activerecord_preloads/activerecord_preloads.rb +66 -18
- data/lib/serega/plugins/activerecord_preloads/lib/preloader.rb +100 -40
- data/lib/serega/plugins/batch/batch.rb +136 -10
- data/lib/serega/plugins/batch/lib/loader.rb +33 -1
- data/lib/serega/plugins/batch/lib/loaders.rb +15 -2
- data/lib/serega/plugins/batch/lib/plugins_extensions.rb +23 -1
- data/lib/serega/plugins/batch/lib/validations/check_batch_opt_key.rb +12 -0
- data/lib/serega/plugins/batch/lib/validations/check_batch_opt_loader.rb +12 -0
- data/lib/serega/plugins/batch/lib/validations/check_opt_batch.rb +12 -0
- data/lib/serega/plugins/context_metadata/context_metadata.rb +95 -13
- data/lib/serega/plugins/formatters/formatters.rb +94 -8
- data/lib/serega/plugins/hide_nil/hide_nil.rb +33 -7
- data/lib/serega/plugins/metadata/metadata.rb +108 -35
- data/lib/serega/plugins/metadata/validations/check_block.rb +3 -0
- data/lib/serega/plugins/metadata/validations/check_opt_hide_empty.rb +4 -1
- data/lib/serega/plugins/metadata/validations/check_opt_hide_nil.rb +4 -1
- data/lib/serega/plugins/metadata/validations/check_opts.rb +3 -0
- data/lib/serega/plugins/metadata/validations/check_path.rb +3 -0
- data/lib/serega/plugins/preloads/lib/enum_deep_freeze.rb +10 -1
- data/lib/serega/plugins/preloads/lib/format_user_preloads.rb +13 -4
- data/lib/serega/plugins/preloads/lib/main_preload_path.rb +16 -3
- data/lib/serega/plugins/preloads/lib/preloads_constructor.rb +4 -6
- data/lib/serega/plugins/preloads/preloads.rb +145 -12
- data/lib/serega/plugins/preloads/validations/check_opt_preload.rb +11 -0
- data/lib/serega/plugins/preloads/validations/check_opt_preload_path.rb +12 -0
- data/lib/serega/plugins/presenter/presenter.rb +20 -11
- data/lib/serega/plugins/root/root.rb +131 -19
- data/lib/serega/plugins/string_modifiers/parse_string_modifiers.rb +42 -12
- data/lib/serega/plugins/string_modifiers/string_modifiers.rb +14 -0
- data/lib/serega/plugins.rb +7 -1
- data/lib/serega/utils/enum_deep_dup.rb +5 -0
- data/lib/serega/utils/to_hash.rb +21 -3
- data/lib/serega/validations/attribute/check_block.rb +7 -2
- data/lib/serega/validations/attribute/check_name.rb +6 -0
- data/lib/serega/validations/attribute/check_opt_const.rb +12 -9
- data/lib/serega/validations/attribute/check_opt_delegate.rb +13 -10
- data/lib/serega/validations/attribute/check_opt_hide.rb +3 -0
- data/lib/serega/validations/attribute/check_opt_key.rb +12 -9
- data/lib/serega/validations/attribute/check_opt_many.rb +3 -0
- data/lib/serega/validations/attribute/check_opt_serializer.rb +3 -0
- data/lib/serega/validations/attribute/check_opt_value.rb +12 -9
- data/lib/serega/validations/check_attribute_params.rb +29 -1
- data/lib/serega/validations/check_initiate_params.rb +17 -0
- data/lib/serega/validations/check_serialize_params.rb +16 -0
- data/lib/serega/validations/initiate/check_modifiers.rb +15 -0
- data/lib/serega/validations/utils/check_allowed_keys.rb +14 -0
- data/lib/serega/validations/utils/check_opt_is_bool.rb +11 -0
- data/lib/serega/validations/utils/check_opt_is_hash.rb +11 -0
- data/lib/serega/validations/utils/check_opt_is_string_or_symbol.rb +11 -0
- data/lib/serega/version.rb +4 -0
- data/lib/serega.rb +83 -24
- metadata +2 -3
- data/lib/serega/serializer.rb +0 -32
@@ -2,36 +2,109 @@
|
|
2
2
|
|
3
3
|
class Serega
|
4
4
|
module SeregaPlugins
|
5
|
+
#
|
6
|
+
# Plugin :root
|
7
|
+
#
|
8
|
+
# Allows to add root key to your serialized data
|
9
|
+
#
|
10
|
+
# Accepts options:
|
11
|
+
# - :root - specifies root for all responses
|
12
|
+
# - :root_one - specifies root for single object serialization only
|
13
|
+
# - :root_many - specifies root for multiple objects serialization only
|
14
|
+
#
|
15
|
+
# Adds additional config options:
|
16
|
+
# - config.root.one
|
17
|
+
# - config.root.many
|
18
|
+
# - config.root.one=
|
19
|
+
# - config.root_many=
|
20
|
+
#
|
21
|
+
# Default root is `:data`.
|
22
|
+
#
|
23
|
+
# Root also can be changed per serialization.
|
24
|
+
#
|
25
|
+
# Also root can be removed for all responses by providing `root: nil`. In this case no root will be added to response, but
|
26
|
+
# you still can to add it per serialization
|
27
|
+
#
|
28
|
+
# @example Define plugin
|
29
|
+
# class UserSerializer < Serega
|
30
|
+
# plugin :root # default root is :data
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# class UserSerializer < Serega
|
34
|
+
# plugin :root, root: :users
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# class UserSerializer < Serega
|
38
|
+
# plugin :root, root_one: :user, root_many: :people
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# class UserSerializer < Serega
|
42
|
+
# plugin :root, root: nil # no root by default
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# @example Change root per serialization:
|
46
|
+
# class UserSerializer < Serega
|
47
|
+
# plugin :root
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# UserSerializer.to_h(nil) # => {:data=>nil}
|
51
|
+
# UserSerializer.to_h(nil, root: :user) # => {:user=>nil}
|
52
|
+
# UserSerializer.to_h(nil, root: nil) # => nil
|
53
|
+
#
|
5
54
|
module Root
|
6
55
|
# @return [Symbol] Default response root key
|
7
56
|
ROOT_DEFAULT = :data
|
8
57
|
|
58
|
+
# @return [Symbol] Plugin name
|
9
59
|
def self.plugin_name
|
10
60
|
:root
|
11
61
|
end
|
12
62
|
|
63
|
+
#
|
64
|
+
# Applies plugin code to specific serializer
|
65
|
+
#
|
66
|
+
# @param serializer_class [Class<Serega>] Current serializer class
|
67
|
+
# @param _opts [Hash] Loaded plugins options
|
68
|
+
#
|
69
|
+
# @return [void]
|
70
|
+
#
|
13
71
|
def self.load_plugin(serializer_class, **_opts)
|
14
72
|
serializer_class.extend(ClassMethods)
|
73
|
+
serializer_class.include(InstanceMethods)
|
15
74
|
serializer_class::SeregaConfig.include(ConfigInstanceMethods)
|
16
|
-
serializer_class::SeregaSerializer.include(SerializerInstanceMethods)
|
17
75
|
end
|
18
76
|
|
77
|
+
#
|
78
|
+
# Adds config options and runs other callbacks after plugin was loaded
|
79
|
+
#
|
80
|
+
# @param serializer_class [Class<Serega>] Current serializer class
|
81
|
+
# @param opts [Hash] loaded plugins opts
|
82
|
+
#
|
83
|
+
# @return [void]
|
84
|
+
#
|
19
85
|
def self.after_load_plugin(serializer_class, **opts)
|
20
86
|
config = serializer_class.config
|
21
|
-
default = opts
|
22
|
-
one = (
|
23
|
-
many = (
|
24
|
-
config.opts[:root] = {
|
87
|
+
default = opts.fetch(:root, ROOT_DEFAULT)
|
88
|
+
one = opts.fetch(:root_one, default)
|
89
|
+
many = opts.fetch(:root_many, default)
|
90
|
+
config.opts[:root] = {}
|
91
|
+
config.root = {one: one, many: many}
|
92
|
+
|
25
93
|
config.serialize_keys << :root
|
26
94
|
end
|
27
95
|
|
96
|
+
#
|
97
|
+
# Serega additional/patched class methods
|
98
|
+
#
|
99
|
+
# @see Serega
|
100
|
+
#
|
28
101
|
module ClassMethods
|
29
102
|
#
|
30
103
|
# Configures response root key
|
31
104
|
#
|
32
|
-
# @param root [String, Symbol] Specifies common root when serializing one or multiple objects
|
33
|
-
# @param
|
34
|
-
# @param
|
105
|
+
# @param root [String, Symbol, nil] Specifies common root when serializing one or multiple objects
|
106
|
+
# @param one [String, Symbol, nil] Specifies root when serializing one object
|
107
|
+
# @param many [String, Symbol, nil] Specifies root when serializing multiple objects
|
35
108
|
#
|
36
109
|
# @return [Hash] Configured root names
|
37
110
|
#
|
@@ -39,63 +112,102 @@ class Serega
|
|
39
112
|
one ||= root
|
40
113
|
many ||= root
|
41
114
|
|
42
|
-
one = one.to_sym if one
|
43
|
-
many = many.to_sym if many
|
44
|
-
|
45
115
|
config.root = {one: one, many: many}
|
46
116
|
end
|
47
117
|
end
|
48
118
|
|
119
|
+
# Root config object
|
49
120
|
class RootConfig
|
50
121
|
attr_reader :opts
|
51
122
|
|
123
|
+
#
|
124
|
+
# Initializes RootConfig object
|
125
|
+
#
|
126
|
+
# @param opts [Hash] root options
|
127
|
+
# @option opts [Symbol, String, nil] :one root for single-object serialization
|
128
|
+
# @option opts [Symbol, String, nil] :many root for many-objects serialization
|
129
|
+
#
|
130
|
+
# @return [Serega::SeregaPlugins::Root::RootConfig] RootConfig object
|
131
|
+
#
|
52
132
|
def initialize(opts)
|
53
133
|
@opts = opts
|
54
134
|
end
|
55
135
|
|
136
|
+
# @return [Symbol, String, nil] defined root for single-object serialization
|
56
137
|
def one
|
57
138
|
opts.fetch(:one)
|
58
139
|
end
|
59
140
|
|
141
|
+
# @return [Symbol, String, nil] defined root for many-objects serialization
|
60
142
|
def many
|
61
143
|
opts.fetch(:many)
|
62
144
|
end
|
63
145
|
|
146
|
+
#
|
147
|
+
# Set root for single-object serialization
|
148
|
+
#
|
149
|
+
# @param value [Symbol, String, nil] root key
|
150
|
+
#
|
151
|
+
# @return [Symbol, String, nil] root key for single-object serialization
|
64
152
|
def one=(value)
|
65
153
|
opts[:one] = value
|
66
154
|
end
|
67
155
|
|
156
|
+
#
|
157
|
+
# Set root for multiple-object serialization
|
158
|
+
#
|
159
|
+
# @param value [Symbol, String, nil] root key
|
160
|
+
#
|
161
|
+
# @return [Symbol, String, nil] root key for multiple-object serialization
|
68
162
|
def many=(value)
|
69
163
|
opts[:many] = value
|
70
164
|
end
|
71
165
|
end
|
72
166
|
|
167
|
+
#
|
168
|
+
# Serega::SeregaConfig additional/patched class methods
|
169
|
+
#
|
170
|
+
# @see Serega::SeregaConfig
|
171
|
+
#
|
73
172
|
module ConfigInstanceMethods
|
173
|
+
# @return [Serega::SeregaPlugins::Root::RootConfig] current root config
|
74
174
|
def root
|
75
175
|
@root ||= RootConfig.new(opts.fetch(:root))
|
76
176
|
end
|
77
177
|
|
178
|
+
# Set root for one-object and many-objects serialization types
|
179
|
+
#
|
180
|
+
# @param value [Hash]
|
181
|
+
# @option value [Symbol, String, nil] :one Root for one-object serialization type
|
182
|
+
# @option value [Symbol, String, nil] :many Root for many-objects serialization type
|
183
|
+
#
|
184
|
+
# @return [void]
|
78
185
|
def root=(value)
|
79
186
|
root.one = value.fetch(:one)
|
80
187
|
root.many = value.fetch(:many)
|
81
188
|
end
|
82
189
|
end
|
83
190
|
|
84
|
-
|
85
|
-
|
191
|
+
#
|
192
|
+
# Serega additional/patched instance methods
|
193
|
+
#
|
194
|
+
# @see Serega
|
195
|
+
#
|
196
|
+
module InstanceMethods
|
197
|
+
private
|
198
|
+
|
199
|
+
def serialize(object, opts)
|
86
200
|
result = super
|
87
|
-
root = build_root(
|
201
|
+
root = build_root(object, opts)
|
88
202
|
result = {root => result} if root
|
89
203
|
result
|
90
204
|
end
|
91
205
|
|
92
|
-
|
93
|
-
|
94
|
-
def build_root(result, opts)
|
206
|
+
def build_root(object, opts)
|
95
207
|
return opts[:root] if opts.key?(:root)
|
96
208
|
|
97
|
-
root = self.class.
|
98
|
-
|
209
|
+
root = self.class.config.root
|
210
|
+
(opts.fetch(:many) { object.is_a?(Enumerable) }) ? root.many : root.one
|
99
211
|
end
|
100
212
|
end
|
101
213
|
end
|
@@ -2,23 +2,53 @@
|
|
2
2
|
|
3
3
|
class Serega
|
4
4
|
module SeregaPlugins
|
5
|
+
#
|
6
|
+
# Plugin :string_modifiers
|
7
|
+
#
|
8
|
+
# Allows to specify modifiers as strings.
|
9
|
+
#
|
10
|
+
# Serialized attributes must be split with `,` and nested attributes can be defined inside brackets `(`, `)`.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# PostSerializer.plugin :string_modifiers
|
14
|
+
# PostSerializer.new(only: "id,user(id,username)").to_h(post)
|
15
|
+
# PostSerializer.new(except: "user(username,email)").to_h(post)
|
16
|
+
# PostSerializer.new(with: "user(email)").to_h(post)
|
17
|
+
|
18
|
+
# # Modifiers can still be provided old way with nested hashes or arrays.
|
19
|
+
# PostSerializer.new(with: {user: %i[email, username]}).to_h(post)
|
20
|
+
#
|
5
21
|
module StringModifiers
|
22
|
+
#
|
23
|
+
# Modifiers parser
|
24
|
+
#
|
6
25
|
class ParseStringModifiers
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
26
|
+
#
|
27
|
+
# Parses provided fields
|
28
|
+
#
|
29
|
+
# @param fields [String,Hash,Array,nil]
|
30
|
+
#
|
31
|
+
# @return [Hash] parsed modifiers in form of nested hash
|
32
|
+
#
|
11
33
|
def self.call(fields)
|
12
34
|
return fields unless fields.is_a?(String)
|
13
35
|
|
14
36
|
new.parse(fields)
|
15
37
|
end
|
16
38
|
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
39
|
+
#
|
40
|
+
# Parses string modifiers
|
41
|
+
#
|
42
|
+
# @param fields [String]
|
43
|
+
#
|
44
|
+
# @return [Hash] parsed modifiers in form of nested hash
|
45
|
+
#
|
46
|
+
# @example
|
47
|
+
# parse("user") => { user: {} }
|
48
|
+
# parse("user(id)") => { user: { id: {} } }
|
49
|
+
# parse("user(id,name)") => { user: { id: {}, name: {} } }
|
50
|
+
# parse("user,comments") => { user: {}, comments: {} }
|
51
|
+
# parse("user(comments(text))") => { user: { comments: { text: {} } } }
|
22
52
|
def parse(fields)
|
23
53
|
res = {}
|
24
54
|
attribute = +""
|
@@ -26,12 +56,12 @@ class Serega
|
|
26
56
|
|
27
57
|
fields.each_char do |char|
|
28
58
|
case char
|
29
|
-
when
|
59
|
+
when ","
|
30
60
|
add_attribute(res, path_stack, attribute, FROZEN_EMPTY_HASH)
|
31
|
-
when
|
61
|
+
when ")"
|
32
62
|
add_attribute(res, path_stack, attribute, FROZEN_EMPTY_HASH)
|
33
63
|
path_stack&.pop
|
34
|
-
when
|
64
|
+
when "("
|
35
65
|
name = add_attribute(res, path_stack, attribute, {})
|
36
66
|
(path_stack ||= []).push(name) if name
|
37
67
|
else
|
@@ -3,15 +3,29 @@
|
|
3
3
|
class Serega
|
4
4
|
module SeregaPlugins
|
5
5
|
module StringModifiers
|
6
|
+
# @return [Symbol] Plugin name
|
6
7
|
def self.plugin_name
|
7
8
|
:string_modifiers
|
8
9
|
end
|
9
10
|
|
11
|
+
#
|
12
|
+
# Applies plugin code to specific serializer
|
13
|
+
#
|
14
|
+
# @param serializer_class [Class<Serega>] Current serializer class
|
15
|
+
# @param _opts [Hash] Loaded plugins options
|
16
|
+
#
|
17
|
+
# @return [void]
|
18
|
+
#
|
10
19
|
def self.load_plugin(serializer_class, **_opts)
|
11
20
|
serializer_class.include(InstanceMethods)
|
12
21
|
require_relative "./parse_string_modifiers"
|
13
22
|
end
|
14
23
|
|
24
|
+
#
|
25
|
+
# Serega additional/patched instance methods
|
26
|
+
#
|
27
|
+
# @see Serega
|
28
|
+
#
|
15
29
|
module InstanceMethods
|
16
30
|
private
|
17
31
|
|
data/lib/serega/plugins.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Serega
|
4
|
-
#
|
4
|
+
# Plugins are stored here
|
5
5
|
module SeregaPlugins
|
6
6
|
@plugins = {}
|
7
7
|
|
@@ -9,8 +9,14 @@ class Serega
|
|
9
9
|
#
|
10
10
|
# Registers given plugin to be able to load it using symbol name.
|
11
11
|
#
|
12
|
+
# @param name [Symbol] Plugin name
|
13
|
+
# @param mod [Module] Plugin module
|
14
|
+
#
|
12
15
|
# @example Register plugin
|
13
16
|
# Serega::SeregaPlugins.register_plugin(:plugin_name, PluginModule)
|
17
|
+
#
|
18
|
+
# @return [void]
|
19
|
+
#
|
14
20
|
def register_plugin(name, mod)
|
15
21
|
@plugins[name] = mod
|
16
22
|
end
|
data/lib/serega/utils/to_hash.rb
CHANGED
@@ -2,8 +2,28 @@
|
|
2
2
|
|
3
3
|
class Serega
|
4
4
|
module SeregaUtils
|
5
|
+
#
|
6
|
+
# Utility to transform almost anything to Hash
|
7
|
+
#
|
5
8
|
class ToHash
|
6
|
-
|
9
|
+
class << self
|
10
|
+
#
|
11
|
+
# Constructs deep hashes from provided data
|
12
|
+
#
|
13
|
+
# @param value [Array, Hash, String, Symbol, NilClass, FalseClass] Value to transform
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
# Serega::SeregaUtils::ToHash.(nil) # => {}
|
17
|
+
# Serega::SeregaUtils::ToHash.(false) # => {}
|
18
|
+
# Serega::SeregaUtils::ToHash.(:foo) # => {:foo=>{}}
|
19
|
+
# Serega::SeregaUtils::ToHash.("foo") # => {:foo=>{}}
|
20
|
+
# Serega::SeregaUtils::ToHash.(%w[foo bar]) # => {:foo=>{}, :bar=>{}}
|
21
|
+
# Serega::SeregaUtils::ToHash.({ foo: nil, bar: false }) # => {:foo=>{}, :bar=>{}}
|
22
|
+
# Serega::SeregaUtils::ToHash.({ foo: :bar }) # => {:foo=>{:bar=>{}}}
|
23
|
+
# Serega::SeregaUtils::ToHash.({ foo: [:bar] }) # => {:foo=>{:bar=>{}}}
|
24
|
+
#
|
25
|
+
# @return [Hash] Transformed data
|
26
|
+
#
|
7
27
|
def call(value)
|
8
28
|
case value
|
9
29
|
when Array then array_to_hash(value)
|
@@ -45,8 +65,6 @@ class Serega
|
|
45
65
|
{value => Serega::FROZEN_EMPTY_HASH}
|
46
66
|
end
|
47
67
|
end
|
48
|
-
|
49
|
-
extend ClassMethods
|
50
68
|
end
|
51
69
|
end
|
52
70
|
end
|
@@ -2,11 +2,17 @@
|
|
2
2
|
|
3
3
|
class Serega
|
4
4
|
module SeregaValidations
|
5
|
+
#
|
6
|
+
# Attribute parameters validators
|
7
|
+
#
|
5
8
|
module Attribute
|
9
|
+
#
|
10
|
+
# Attribute `block` parameter validator
|
11
|
+
#
|
6
12
|
class CheckBlock
|
7
13
|
class << self
|
8
14
|
#
|
9
|
-
# Checks
|
15
|
+
# Checks block parameter provided with attribute.
|
10
16
|
# Must have up to two arguments - object and context.
|
11
17
|
# It should not have any *rest or **key arguments
|
12
18
|
#
|
@@ -19,7 +25,6 @@ class Serega
|
|
19
25
|
# @example with two arguments
|
20
26
|
# attribute(:email) { |obj, context| context['is_current'] ? obj.email : nil }
|
21
27
|
#
|
22
|
-
# @param opts [Proc] Attribute opts, we will check :value option
|
23
28
|
# @param block [Proc] Block that returns serialized attribute value
|
24
29
|
#
|
25
30
|
# @raise [SeregaError] SeregaError that block has invalid arguments
|
@@ -3,8 +3,14 @@
|
|
3
3
|
class Serega
|
4
4
|
module SeregaValidations
|
5
5
|
module Attribute
|
6
|
+
#
|
7
|
+
# Attribute `name` parameter validator
|
8
|
+
#
|
6
9
|
class CheckName
|
10
|
+
# Regexp for valid one-char attribute name
|
7
11
|
FORMAT_ONE_CHAR = /\A[a-zA-Z0-9]\z/
|
12
|
+
|
13
|
+
# Regexp for valid multi-chars attribute name
|
8
14
|
FORMAT_MANY_CHARS = /\A[a-zA-Z0-9][a-zA-Z0-9_-]*?[a-zA-Z0-9]\z/ # allow '-' and '_' in the middle
|
9
15
|
|
10
16
|
private_constant :FORMAT_ONE_CHAR, :FORMAT_MANY_CHARS
|
@@ -3,17 +3,20 @@
|
|
3
3
|
class Serega
|
4
4
|
module SeregaValidations
|
5
5
|
module Attribute
|
6
|
+
#
|
7
|
+
# Attribute `:const` option validator
|
8
|
+
#
|
6
9
|
class CheckOptConst
|
7
|
-
#
|
8
|
-
# Checks attribute :const option
|
9
|
-
#
|
10
|
-
# @param opts [Hash] Attribute options
|
11
|
-
#
|
12
|
-
# @raise [SeregaError] Attribute validation error
|
13
|
-
#
|
14
|
-
# @return [void]
|
15
|
-
#
|
16
10
|
class << self
|
11
|
+
#
|
12
|
+
# Checks attribute :const option
|
13
|
+
#
|
14
|
+
# @param opts [Hash] Attribute options
|
15
|
+
#
|
16
|
+
# @raise [SeregaError] Attribute validation error
|
17
|
+
#
|
18
|
+
# @return [void]
|
19
|
+
#
|
17
20
|
def call(opts, block = nil)
|
18
21
|
return unless opts.key?(:const)
|
19
22
|
|
@@ -3,18 +3,21 @@
|
|
3
3
|
class Serega
|
4
4
|
module SeregaValidations
|
5
5
|
module Attribute
|
6
|
+
#
|
7
|
+
# Attribute `:delegate` option validator
|
8
|
+
#
|
6
9
|
class CheckOptDelegate
|
7
|
-
#
|
8
|
-
# Checks attribute :delegate option
|
9
|
-
# It must have :to option and can have :optional allow_nil option
|
10
|
-
#
|
11
|
-
# @param opts [Hash] Attribute options
|
12
|
-
#
|
13
|
-
# @raise [SeregaError] Attribute validation error
|
14
|
-
#
|
15
|
-
# @return [void]
|
16
|
-
#
|
17
10
|
class << self
|
11
|
+
#
|
12
|
+
# Checks attribute :delegate option
|
13
|
+
# It must have :to option and can have :optional allow_nil option
|
14
|
+
#
|
15
|
+
# @param opts [Hash] Attribute options
|
16
|
+
#
|
17
|
+
# @raise [SeregaError] Attribute validation error
|
18
|
+
#
|
19
|
+
# @return [void]
|
20
|
+
#
|
18
21
|
def call(opts, block = nil)
|
19
22
|
return unless opts.key?(:delegate)
|
20
23
|
|
@@ -3,17 +3,20 @@
|
|
3
3
|
class Serega
|
4
4
|
module SeregaValidations
|
5
5
|
module Attribute
|
6
|
+
#
|
7
|
+
# Attribute `:key` option validator
|
8
|
+
#
|
6
9
|
class CheckOptKey
|
7
|
-
#
|
8
|
-
# Checks attribute :key option
|
9
|
-
#
|
10
|
-
# @param opts [Hash] Attribute options
|
11
|
-
#
|
12
|
-
# @raise [SeregaError] SeregaError that option has invalid value
|
13
|
-
#
|
14
|
-
# @return [void]
|
15
|
-
#
|
16
10
|
class << self
|
11
|
+
#
|
12
|
+
# Checks attribute :key option
|
13
|
+
#
|
14
|
+
# @param opts [Hash] Attribute options
|
15
|
+
#
|
16
|
+
# @raise [SeregaError] SeregaError that option has invalid value
|
17
|
+
#
|
18
|
+
# @return [void]
|
19
|
+
#
|
17
20
|
def call(opts, block = nil)
|
18
21
|
return unless opts.key?(:key)
|
19
22
|
|
@@ -3,17 +3,20 @@
|
|
3
3
|
class Serega
|
4
4
|
module SeregaValidations
|
5
5
|
module Attribute
|
6
|
+
#
|
7
|
+
# Attribute `:value` option validator
|
8
|
+
#
|
6
9
|
class CheckOptValue
|
7
|
-
#
|
8
|
-
# Checks attribute :value option
|
9
|
-
#
|
10
|
-
# @param opts [Hash] Attribute options
|
11
|
-
#
|
12
|
-
# @raise [SeregaError] SeregaError that option has invalid value
|
13
|
-
#
|
14
|
-
# @return [void]
|
15
|
-
#
|
16
10
|
class << self
|
11
|
+
#
|
12
|
+
# Checks attribute :value option
|
13
|
+
#
|
14
|
+
# @param opts [Hash] Attribute options
|
15
|
+
#
|
16
|
+
# @raise [SeregaError] SeregaError that option has invalid value
|
17
|
+
#
|
18
|
+
# @return [void]
|
19
|
+
#
|
17
20
|
def call(opts, block = nil)
|
18
21
|
return unless opts.key?(:value)
|
19
22
|
|
@@ -1,17 +1,45 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Serega
|
4
|
+
#
|
5
|
+
# Validations
|
6
|
+
#
|
4
7
|
module SeregaValidations
|
8
|
+
#
|
9
|
+
# Validations for attribute params
|
10
|
+
#
|
5
11
|
class CheckAttributeParams
|
12
|
+
#
|
13
|
+
# Validations for attribute params instance methods
|
14
|
+
#
|
6
15
|
module InstanceMethods
|
7
|
-
|
16
|
+
# @return [Symbol] validated attribute name
|
17
|
+
attr_reader :name
|
8
18
|
|
19
|
+
# @return [Hash] validated attribute options
|
20
|
+
attr_reader :opts
|
21
|
+
|
22
|
+
# @return [nil, Proc] validated attribute block
|
23
|
+
attr_reader :block
|
24
|
+
|
25
|
+
#
|
26
|
+
# Initializes attribute params validator
|
27
|
+
#
|
28
|
+
# @param name [Symbol] attribute name
|
29
|
+
# @param opts [Hash] attribute options
|
30
|
+
# @param block [nil, Proc] block provided to attribute
|
31
|
+
#
|
32
|
+
# @return [void]
|
33
|
+
#
|
9
34
|
def initialize(name, opts, block)
|
10
35
|
@name = name
|
11
36
|
@opts = opts
|
12
37
|
@block = block
|
13
38
|
end
|
14
39
|
|
40
|
+
#
|
41
|
+
# Validates attribute params
|
42
|
+
#
|
15
43
|
def validate
|
16
44
|
check_name
|
17
45
|
check_opts
|