serega 0.1.4 → 0.3.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 +17 -4
- data/lib/serega/config.rb +69 -27
- data/lib/serega/convert.rb +7 -7
- data/lib/serega/convert_item.rb +4 -4
- data/lib/serega/errors.rb +12 -0
- data/lib/serega/helpers/serializer_class_helper.rb +1 -1
- data/lib/serega/json/adapter.rb +17 -0
- data/lib/serega/json/json.rb +17 -0
- data/lib/serega/json/oj.rb +17 -0
- data/lib/serega/map.rb +25 -15
- data/lib/serega/plugins/activerecord_preloads/activerecord_preloads.rb +3 -3
- data/lib/serega/plugins/activerecord_preloads/lib/preloader.rb +2 -2
- data/lib/serega/plugins/context_metadata/context_metadata.rb +34 -11
- data/lib/serega/plugins/formatters/formatters.rb +35 -6
- data/lib/serega/plugins/hide_nil/hide_nil.rb +7 -7
- data/lib/serega/plugins/metadata/meta_attribute.rb +5 -5
- data/lib/serega/plugins/metadata/metadata.rb +30 -5
- data/lib/serega/plugins/metadata/validations/check_block.rb +4 -4
- data/lib/serega/plugins/metadata/validations/check_opt_hide_empty.rb +3 -3
- data/lib/serega/plugins/metadata/validations/check_opt_hide_nil.rb +3 -3
- data/lib/serega/plugins/metadata/validations/check_opts.rb +3 -3
- data/lib/serega/plugins/metadata/validations/check_path.rb +3 -3
- data/lib/serega/plugins/preloads/lib/enum_deep_freeze.rb +1 -1
- data/lib/serega/plugins/preloads/lib/format_user_preloads.rb +1 -1
- data/lib/serega/plugins/preloads/lib/main_preload_path.rb +1 -1
- data/lib/serega/plugins/preloads/lib/preloads_constructor.rb +2 -2
- data/lib/serega/plugins/preloads/preloads.rb +63 -5
- data/lib/serega/plugins/preloads/validations/check_opt_preload.rb +17 -0
- data/lib/serega/plugins/preloads/validations/check_opt_preload_path.rb +4 -4
- data/lib/serega/plugins/presenter/presenter.rb +6 -6
- data/lib/serega/plugins/root/root.rb +48 -8
- data/lib/serega/plugins/string_modifiers/parse_string_modifiers.rb +1 -1
- data/lib/serega/plugins/string_modifiers/string_modifiers.rb +7 -7
- data/lib/serega/plugins.rb +7 -7
- data/lib/serega/utils/enum_deep_dup.rb +1 -1
- data/lib/serega/utils/to_hash.rb +2 -2
- data/lib/serega/validations/attribute/check_block.rb +3 -3
- data/lib/serega/validations/attribute/check_name.rb +3 -3
- data/lib/serega/validations/attribute/check_opt_const.rb +5 -5
- data/lib/serega/validations/attribute/check_opt_delegate.rb +57 -0
- data/lib/serega/validations/attribute/check_opt_hide.rb +2 -2
- data/lib/serega/validations/attribute/check_opt_key.rb +5 -5
- data/lib/serega/validations/attribute/check_opt_many.rb +2 -2
- data/lib/serega/validations/attribute/check_opt_serializer.rb +3 -3
- data/lib/serega/validations/attribute/check_opt_value.rb +7 -7
- data/lib/serega/validations/check_attribute_params.rb +4 -3
- data/lib/serega/validations/check_initiate_params.rb +23 -10
- data/lib/serega/validations/check_serialize_params.rb +16 -10
- data/lib/serega/{plugins/validate_modifiers/validate.rb → validations/initiate/check_modifiers.rb} +5 -5
- data/lib/serega/validations/utils/check_allowed_keys.rb +2 -2
- data/lib/serega/validations/utils/check_opt_is_bool.rb +2 -2
- data/lib/serega/validations/utils/check_opt_is_hash.rb +2 -2
- data/lib/serega/validations/utils/check_opt_is_string_or_symbol.rb +2 -2
- data/lib/serega.rb +52 -72
- metadata +9 -6
- data/lib/serega/plugins/validate_modifiers/validate_modifiers.rb +0 -44
- data/lib/serega/utils/as_json.rb +0 -35
- data/lib/serega/utils/to_json.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ca43f185a296a7139890f92ca5b7a8c265f3d9db65a0cc3a5e3fff4390d6ac9
|
4
|
+
data.tar.gz: d295ac90b5481f9ca4ff2e8239c7e43e2548df76cc30d50b8f372934f8f78dfe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f75c90f6156452f49290d11eb5caf322437025c2c43ba471bc5bda32185a7c9b00b9003dc836952b660932c407285483b65e3538c7aebe365b110d47502e0d0b
|
7
|
+
data.tar.gz: 925cb9cc61974ce9524ffec2cd3cf869c230beba1d13ecd71b5b3e8aa4e6415acb64bd75845cab58031b0713b2c8253442d53473eff5b16915e57ad7a2e118b0
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/lib/serega/attribute.rb
CHANGED
@@ -4,7 +4,7 @@ class Serega
|
|
4
4
|
#
|
5
5
|
# Stores Attribute data
|
6
6
|
#
|
7
|
-
class
|
7
|
+
class SeregaAttribute
|
8
8
|
#
|
9
9
|
# Stores Attribute instance methods
|
10
10
|
#
|
@@ -36,7 +36,7 @@ class Serega
|
|
36
36
|
self.class.serializer_class::CheckAttributeParams.new(name, opts, block).validate
|
37
37
|
|
38
38
|
@name = name.to_sym
|
39
|
-
@opts =
|
39
|
+
@opts = SeregaUtils::EnumDeepDup.call(opts)
|
40
40
|
@block = block
|
41
41
|
end
|
42
42
|
|
@@ -77,7 +77,7 @@ class Serega
|
|
77
77
|
def value_block
|
78
78
|
return @value_block if instance_variable_defined?(:@value_block)
|
79
79
|
|
80
|
-
@value_block = block || opts[:value] || const_block || keyword_block
|
80
|
+
@value_block = block || opts[:value] || const_block || delegate_block || keyword_block
|
81
81
|
end
|
82
82
|
|
83
83
|
#
|
@@ -123,9 +123,22 @@ class Serega
|
|
123
123
|
key_method_name = key
|
124
124
|
proc { |object| object.public_send(key_method_name) }
|
125
125
|
end
|
126
|
+
|
127
|
+
def delegate_block
|
128
|
+
return unless opts.key?(:delegate)
|
129
|
+
|
130
|
+
key_method_name = key
|
131
|
+
delegate_to = opts[:delegate][:to]
|
132
|
+
|
133
|
+
if opts[:delegate][:allow_nil]
|
134
|
+
proc { |object| object.public_send(delegate_to)&.public_send(key_method_name) }
|
135
|
+
else
|
136
|
+
proc { |object| object.public_send(delegate_to).public_send(key_method_name) }
|
137
|
+
end
|
138
|
+
end
|
126
139
|
end
|
127
140
|
|
128
|
-
extend Serega::
|
141
|
+
extend Serega::SeregaHelpers::SerializerClassHelper
|
129
142
|
include AttributeInstanceMethods
|
130
143
|
end
|
131
144
|
end
|
data/lib/serega/config.rb
CHANGED
@@ -6,43 +6,85 @@ class Serega
|
|
6
6
|
#
|
7
7
|
# Core class that stores serializer configuration
|
8
8
|
#
|
9
|
-
class
|
10
|
-
|
11
|
-
|
9
|
+
class SeregaConfig
|
10
|
+
# :nocov: We can't use both :oj and :json adapters together
|
11
|
+
DEFAULTS = {
|
12
|
+
plugins: [],
|
13
|
+
initiate_keys: %i[only with except check_initiate_params].freeze,
|
14
|
+
attribute_keys: %i[key value serializer many hide const delegate].freeze,
|
15
|
+
serialize_keys: %i[context many].freeze,
|
16
|
+
check_initiate_params: true,
|
17
|
+
max_cached_map_per_serializer_count: 0,
|
18
|
+
to_json: SeregaJSON.adapter == :oj ? SeregaJSON::OjDump : SeregaJSON::JSONDump,
|
19
|
+
from_json: SeregaJSON.adapter == :oj ? SeregaJSON::OjLoad : SeregaJSON::JSONLoad
|
20
|
+
}.freeze
|
21
|
+
# :nocov:
|
12
22
|
|
13
|
-
|
23
|
+
module SeregaConfigInstanceMethods
|
14
24
|
attr_reader :opts
|
15
25
|
|
16
26
|
#
|
17
|
-
# Initializes new config instance
|
18
|
-
# remove possibility of accidental overwriting of parent/nested configs.
|
27
|
+
# Initializes new config instance.
|
19
28
|
#
|
20
29
|
# @param opts [Hash] Initial config options
|
21
30
|
#
|
22
|
-
def initialize(opts =
|
23
|
-
|
31
|
+
def initialize(opts = nil)
|
32
|
+
opts ||= DEFAULTS
|
33
|
+
@opts = SeregaUtils::EnumDeepDup.call(opts)
|
24
34
|
end
|
25
35
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
36
|
+
def plugins
|
37
|
+
opts.fetch(:plugins)
|
38
|
+
end
|
39
|
+
|
40
|
+
def initiate_keys
|
41
|
+
opts.fetch(:initiate_keys)
|
42
|
+
end
|
43
|
+
|
44
|
+
def attribute_keys
|
45
|
+
opts.fetch(:attribute_keys)
|
46
|
+
end
|
47
|
+
|
48
|
+
def serialize_keys
|
49
|
+
opts.fetch(:serialize_keys)
|
50
|
+
end
|
51
|
+
|
52
|
+
def check_initiate_params
|
53
|
+
opts.fetch(:check_initiate_params)
|
54
|
+
end
|
55
|
+
|
56
|
+
def check_initiate_params=(value)
|
57
|
+
raise SeregaError, "Must have boolean value, #{value.inspect} provided" if (value != true) && (value != false)
|
58
|
+
opts[:check_initiate_params] = value
|
59
|
+
end
|
60
|
+
|
61
|
+
def max_cached_map_per_serializer_count
|
62
|
+
opts.fetch(:max_cached_map_per_serializer_count)
|
63
|
+
end
|
64
|
+
|
65
|
+
def max_cached_map_per_serializer_count=(value)
|
66
|
+
raise SeregaError, "Must have Integer value, #{value.inspect} provided" unless value.is_a?(Integer)
|
67
|
+
opts[:max_cached_map_per_serializer_count] = value
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_json
|
71
|
+
opts.fetch(:to_json)
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_json=(value)
|
75
|
+
opts[:to_json] = value
|
76
|
+
end
|
77
|
+
|
78
|
+
def from_json
|
79
|
+
opts.fetch(:from_json)
|
80
|
+
end
|
81
|
+
|
82
|
+
def from_json=(value)
|
83
|
+
opts[:from_json] = value
|
84
|
+
end
|
43
85
|
end
|
44
86
|
|
45
|
-
include
|
46
|
-
extend Serega::
|
87
|
+
include SeregaConfigInstanceMethods
|
88
|
+
extend Serega::SeregaHelpers::SerializerClassHelper
|
47
89
|
end
|
48
90
|
end
|
data/lib/serega/convert.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Serega
|
4
|
-
class
|
5
|
-
module
|
4
|
+
class SeregaConvert
|
5
|
+
module SeregaConvertClassMethods
|
6
6
|
def call(object, **opts)
|
7
7
|
new(object, **opts).to_h
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
module
|
11
|
+
module SeregaConvertInstanceMethods
|
12
12
|
attr_reader :object, :opts
|
13
13
|
|
14
14
|
def initialize(object, **opts)
|
@@ -27,7 +27,7 @@ class Serega
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def one(object)
|
30
|
-
self.class.serializer_class::
|
30
|
+
self.class.serializer_class::SeregaConvertItem.call(object, opts[:context], opts[:map])
|
31
31
|
end
|
32
32
|
|
33
33
|
def many?
|
@@ -38,8 +38,8 @@ class Serega
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
extend Serega::
|
42
|
-
extend
|
43
|
-
include
|
41
|
+
extend Serega::SeregaHelpers::SerializerClassHelper
|
42
|
+
extend SeregaConvertClassMethods
|
43
|
+
include SeregaConvertInstanceMethods
|
44
44
|
end
|
45
45
|
end
|
data/lib/serega/convert_item.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Serega
|
4
|
-
class
|
5
|
-
module
|
4
|
+
class SeregaConvertItem
|
5
|
+
module SeregaConvertItemClassMethods
|
6
6
|
def call(object, context, map)
|
7
7
|
return unless object
|
8
8
|
|
@@ -31,7 +31,7 @@ class Serega
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
extend Serega::
|
35
|
-
extend
|
34
|
+
extend Serega::SeregaHelpers::SerializerClassHelper
|
35
|
+
extend SeregaConvertItemClassMethods
|
36
36
|
end
|
37
37
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Serega
|
4
|
+
# A generic exception Serega uses.
|
5
|
+
class SeregaError < StandardError; end
|
6
|
+
|
7
|
+
# AttributeNotExist is raised when serializer is initiated using not existing attribute
|
8
|
+
# Example:
|
9
|
+
# UserSerializer.new(only: 'FOO', except: 'FOO', with: 'FOO')
|
10
|
+
# UserSerializer.to_h(user, only: 'FOO', except: 'FOO', with: 'FOO' )
|
11
|
+
class AttributeNotExist < SeregaError; end
|
12
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Serega
|
4
|
+
module SeregaJSON
|
5
|
+
class OjDump
|
6
|
+
def self.call(data)
|
7
|
+
::Oj.dump(data, mode: :compat)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class OjLoad
|
12
|
+
def self.call(json_string)
|
13
|
+
::Oj.load(json_string)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/serega/map.rb
CHANGED
@@ -1,27 +1,37 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Serega
|
4
|
-
class
|
4
|
+
class SeregaMap
|
5
5
|
module ClassMethods
|
6
6
|
def call(opts)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@cache[cache_key] ||= begin
|
11
|
-
modifiers = {
|
12
|
-
only: opts&.[](:only) || FROZEN_EMPTY_HASH,
|
13
|
-
except: opts&.[](:except) || FROZEN_EMPTY_HASH,
|
14
|
-
with: opts&.[](:with) || FROZEN_EMPTY_HASH
|
15
|
-
}
|
7
|
+
max_cache_size = serializer_class.config.max_cached_map_per_serializer_count
|
8
|
+
return map_for(opts) if max_cache_size.zero?
|
16
9
|
|
17
|
-
|
18
|
-
@cache.shift if @cache.length >= serializer_class.config[:max_cached_map_per_serializer_count]
|
19
|
-
end
|
20
|
-
end
|
10
|
+
cached_map_for(opts, max_cache_size)
|
21
11
|
end
|
22
12
|
|
23
13
|
private
|
24
14
|
|
15
|
+
def map_for(opts)
|
16
|
+
construct_map(serializer_class, **modifiers(opts))
|
17
|
+
end
|
18
|
+
|
19
|
+
def cached_map_for(opts, max_cache_size)
|
20
|
+
@cache ||= {}
|
21
|
+
cache_key = opts.to_s
|
22
|
+
map = @cache[cache_key] ||= map_for(opts)
|
23
|
+
@cache.shift if @cache.length > max_cache_size
|
24
|
+
map
|
25
|
+
end
|
26
|
+
|
27
|
+
def modifiers(opts)
|
28
|
+
{
|
29
|
+
only: opts[:only] || FROZEN_EMPTY_HASH,
|
30
|
+
except: opts[:except] || FROZEN_EMPTY_HASH,
|
31
|
+
with: opts[:with] || FROZEN_EMPTY_HASH
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
25
35
|
def construct_map(serializer_class, only:, except:, with:)
|
26
36
|
serializer_class.attributes.each_with_object([]) do |(name, attribute), map|
|
27
37
|
next unless attribute.visible?(only: only, except: except, with: with)
|
@@ -44,6 +54,6 @@ class Serega
|
|
44
54
|
end
|
45
55
|
|
46
56
|
extend ClassMethods
|
47
|
-
extend Serega::
|
57
|
+
extend Serega::SeregaHelpers::SerializerClassHelper
|
48
58
|
end
|
49
59
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Serega
|
4
|
-
module
|
4
|
+
module SeregaPlugins
|
5
5
|
#
|
6
6
|
# Plugin that checks used plugins and loads correct Preloader for selected response type
|
7
|
-
# @see Serega::
|
8
|
-
# @see Serega::
|
7
|
+
# @see Serega::SeregaPlugins::JsonApiActiverecordPreloader
|
8
|
+
# @see Serega::SeregaPlugins::SimpleApiActiverecordPreloader
|
9
9
|
#
|
10
10
|
module ActiverecordPreloads
|
11
11
|
# @return [Symbol] plugin name
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Serega
|
4
|
-
module
|
4
|
+
module SeregaPlugins
|
5
5
|
module ActiverecordPreloads
|
6
6
|
class Preloader
|
7
7
|
module ClassMethods
|
8
8
|
def preload(object, preloads)
|
9
9
|
preload_handler = handlers.find { |handler| handler.fit?(object) }
|
10
|
-
raise
|
10
|
+
raise SeregaError, "Can't preload #{preloads.inspect} to #{object.inspect}" unless preload_handler
|
11
11
|
|
12
12
|
preload_handler.preload(object, preloads)
|
13
13
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Serega
|
4
|
-
module
|
4
|
+
module SeregaPlugins
|
5
5
|
module ContextMetadata
|
6
6
|
DEFAULT_CONTEXT_METADATA_KEY = :meta
|
7
7
|
|
@@ -14,27 +14,50 @@ class Serega
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def self.load_plugin(serializer_class, **_opts)
|
17
|
-
serializer_class::
|
18
|
-
serializer_class::
|
17
|
+
serializer_class::SeregaConfig.include(ConfigInstanceMethods)
|
18
|
+
serializer_class::SeregaConvert.include(SeregaConvertInstanceMethods)
|
19
|
+
serializer_class::CheckSerializeParams.include(CheckSerializeParamsInstanceMethods)
|
19
20
|
end
|
20
21
|
|
21
22
|
def self.after_load_plugin(serializer_class, **opts)
|
22
23
|
config = serializer_class.config
|
23
24
|
meta_key = opts[:context_metadata_key] || DEFAULT_CONTEXT_METADATA_KEY
|
24
|
-
config[
|
25
|
-
config
|
25
|
+
config.opts[:context_metadata] = {key: meta_key}
|
26
|
+
config.serialize_keys << meta_key
|
26
27
|
end
|
27
28
|
|
28
|
-
|
29
|
-
|
29
|
+
class ContextMetadataConfig
|
30
|
+
attr_reader :opts
|
31
|
+
|
32
|
+
def initialize(opts)
|
33
|
+
@opts = opts
|
34
|
+
end
|
35
|
+
|
36
|
+
def key
|
37
|
+
opts.fetch(:key)
|
38
|
+
end
|
39
|
+
|
40
|
+
def key=(value)
|
41
|
+
opts[:key] = value
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module ConfigInstanceMethods
|
46
|
+
def context_metadata
|
47
|
+
ContextMetadataConfig.new(opts.fetch(:context_metadata))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
module CheckSerializeParamsInstanceMethods
|
52
|
+
def check_opts
|
30
53
|
super
|
31
54
|
|
32
|
-
meta_key = serializer_class.config
|
33
|
-
|
55
|
+
meta_key = self.class.serializer_class.config.context_metadata.key
|
56
|
+
SeregaValidations::Utils::CheckOptIsHash.call(opts, meta_key)
|
34
57
|
end
|
35
58
|
end
|
36
59
|
|
37
|
-
module
|
60
|
+
module SeregaConvertInstanceMethods
|
38
61
|
def to_h
|
39
62
|
super.tap do |hash|
|
40
63
|
add_context_metadata(hash)
|
@@ -44,7 +67,7 @@ class Serega
|
|
44
67
|
private
|
45
68
|
|
46
69
|
def add_context_metadata(hash)
|
47
|
-
context_metadata_key = self.class.serializer_class.config
|
70
|
+
context_metadata_key = self.class.serializer_class.config.context_metadata.key
|
48
71
|
return unless context_metadata_key
|
49
72
|
|
50
73
|
metadata = opts[context_metadata_key]
|
@@ -1,20 +1,41 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Serega
|
4
|
-
module
|
4
|
+
module SeregaPlugins
|
5
5
|
module Formatters
|
6
6
|
def self.plugin_name
|
7
7
|
:formatters
|
8
8
|
end
|
9
9
|
|
10
10
|
def self.load_plugin(serializer_class, **_opts)
|
11
|
-
serializer_class::
|
11
|
+
serializer_class::SeregaConfig.include(ConfigInstanceMethods)
|
12
|
+
serializer_class::SeregaAttribute.include(AttributeInstanceMethods)
|
12
13
|
end
|
13
14
|
|
14
15
|
def self.after_load_plugin(serializer_class, **_opts)
|
15
16
|
config = serializer_class.config
|
16
|
-
config[
|
17
|
-
config
|
17
|
+
config.opts[:formatters] = {}
|
18
|
+
config.attribute_keys << :format
|
19
|
+
end
|
20
|
+
|
21
|
+
class FormattersConfig
|
22
|
+
attr_reader :opts
|
23
|
+
|
24
|
+
def initialize(opts)
|
25
|
+
@opts = opts
|
26
|
+
end
|
27
|
+
|
28
|
+
def add(formatters)
|
29
|
+
formatters.each_pair do |key, value|
|
30
|
+
opts[key] = value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
module ConfigInstanceMethods
|
36
|
+
def formatters
|
37
|
+
FormattersConfig.new(opts.fetch(:formatters))
|
38
|
+
end
|
18
39
|
end
|
19
40
|
|
20
41
|
module AttributeInstanceMethods
|
@@ -25,7 +46,15 @@ class Serega
|
|
25
46
|
formatter = opts[:format]
|
26
47
|
return original_block unless formatter
|
27
48
|
|
28
|
-
|
49
|
+
new_value_block = formatted_block(formatter, original_block)
|
50
|
+
|
51
|
+
# Detect formatted :const value in advance
|
52
|
+
if opts.key?(:const)
|
53
|
+
const_value = new_value_block.call
|
54
|
+
new_value_block = proc { const_value }
|
55
|
+
end
|
56
|
+
|
57
|
+
@value_block = new_value_block
|
29
58
|
end
|
30
59
|
|
31
60
|
private
|
@@ -35,7 +64,7 @@ class Serega
|
|
35
64
|
value = original_block.call(object, context)
|
36
65
|
|
37
66
|
if formatter.is_a?(Symbol)
|
38
|
-
self.class.serializer_class.config.
|
67
|
+
self.class.serializer_class.config.formatters.opts.fetch(formatter).call(value)
|
39
68
|
else
|
40
69
|
formatter.call(value)
|
41
70
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Serega
|
4
|
-
module
|
4
|
+
module SeregaPlugins
|
5
5
|
#
|
6
6
|
# Plugin adds `:hide_nil` option to attributes to delete them from final result
|
7
7
|
# if value is nil
|
@@ -21,13 +21,13 @@ class Serega
|
|
21
21
|
# @return [void]
|
22
22
|
#
|
23
23
|
def self.load_plugin(serializer_class, **_opts)
|
24
|
-
serializer_class::
|
24
|
+
serializer_class::SeregaAttribute.include(AttributeMethods)
|
25
25
|
serializer_class::CheckAttributeParams.include(CheckAttributeParamsInstanceMethods)
|
26
|
-
serializer_class::
|
26
|
+
serializer_class::SeregaConvertItem.extend(SeregaConvertItemClassMethods)
|
27
27
|
end
|
28
28
|
|
29
29
|
def self.after_load_plugin(serializer_class, **opts)
|
30
|
-
serializer_class.config
|
30
|
+
serializer_class.config.attribute_keys << :hide_nil
|
31
31
|
end
|
32
32
|
|
33
33
|
# Adds #hide_nil? Attribute instance method
|
@@ -52,7 +52,7 @@ class Serega
|
|
52
52
|
#
|
53
53
|
# @param opts [Hash] Attribute options
|
54
54
|
#
|
55
|
-
# @raise [Serega::
|
55
|
+
# @raise [Serega::SeregaError] SeregaError that option has invalid value
|
56
56
|
#
|
57
57
|
# @return [void]
|
58
58
|
#
|
@@ -62,11 +62,11 @@ class Serega
|
|
62
62
|
value = opts[:hide_nil]
|
63
63
|
return if (value == true) || (value == false)
|
64
64
|
|
65
|
-
raise
|
65
|
+
raise SeregaError, "Invalid option :hide_nil => #{value.inspect}. Must have a boolean value"
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
module
|
69
|
+
module SeregaConvertItemClassMethods
|
70
70
|
private
|
71
71
|
|
72
72
|
def attach_value(value, *args)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Serega
|
4
|
-
module
|
4
|
+
module SeregaPlugins
|
5
5
|
module Metadata
|
6
6
|
#
|
7
7
|
# Stores Attribute data
|
@@ -36,8 +36,8 @@ class Serega
|
|
36
36
|
check(path, opts, block)
|
37
37
|
|
38
38
|
@name = path.join(".").to_sym
|
39
|
-
@path =
|
40
|
-
@opts =
|
39
|
+
@path = SeregaUtils::EnumDeepDup.call(path)
|
40
|
+
@opts = SeregaUtils::EnumDeepDup.call(opts)
|
41
41
|
@block = block
|
42
42
|
end
|
43
43
|
|
@@ -61,12 +61,12 @@ class Serega
|
|
61
61
|
|
62
62
|
def check(path, opts, block)
|
63
63
|
CheckPath.call(path)
|
64
|
-
CheckOpts.call(opts, self.class.serializer_class.config
|
64
|
+
CheckOpts.call(opts, self.class.serializer_class.config.metadata.attribute_keys)
|
65
65
|
CheckBlock.call(block)
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
extend Serega::
|
69
|
+
extend Serega::SeregaHelpers::SerializerClassHelper
|
70
70
|
include InstanceMethods
|
71
71
|
end
|
72
72
|
end
|