serega 0.8.3 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 116b00d5c709f65a90899a9eda49f6e2c95cc9a47781a1cddf2499057553f427
4
- data.tar.gz: 5f8fe19470218be68c09704964228be0381e677f5bd3cbcf9688f92974e9392d
3
+ metadata.gz: 6b6c3672a4fc40557f4fef3e650de56c84bf23d96defabd3f3f04aa5f273aa90
4
+ data.tar.gz: 79bcc2c3526b0ae141de69003e0834c94f9b7bade028cbc85bed20c3f3ba1757
5
5
  SHA512:
6
- metadata.gz: 047de5335017cf65ee0f887124f81a755b94e19eea0e53a56ae24cb81698e7bdcc7e8eb6eba9256b5160a24bb011a5c0a1c1628cca77c7e7951b8883629ad96f
7
- data.tar.gz: 5836df28c6e1cf2238d8c8471280dc806dd41a0cbbe474a101118d801e460830cda97dcb419e0885f9106d1e4e5ae795776ff5cc475555bdab6cb4c5408c1c94
6
+ metadata.gz: edcc6856f212848b721af517bb0f77695e6e7f2adbc7bb687e4573a62efe84e02266301cc3e70647b7cd8385b96901436ce1ded9446e9712f3884d8d6348c855
7
+ data.tar.gz: e0fec25bc4471ebbf3b6fbfb1967101af7f8cd7e703cb56eba935fd51bc6de0efe87d802be8257a950648afc633ed3ceb3bfc78f67b3905197ffa0a6e39ada32
data/README.md CHANGED
@@ -20,6 +20,7 @@ It has some great features:
20
20
  - Built-in object presenter ([presenter][presenter] plugin)
21
21
  - Adding custom metadata (via [metadata][metadata] or [context_metadata][context_metadata] plugins)
22
22
  - Attributes formatters ([formatters][formatters] plugin)
23
+ - Conditional attributes ([if][if] plugin)
23
24
 
24
25
  ## Installation
25
26
 
@@ -94,9 +95,11 @@ class UserSerializer < Serega
94
95
  # It allows to specify associations to preload to attribute value
95
96
  attribute :email, preload: :emails, value: proc { |user| user.emails.find(&:verified?) }
96
97
 
97
- # Option `:hide_nil` can be specified when enabled `:hide_nil` plugin
98
- # It is literally hides attribute if its value is nil
99
- attribute :email, hide_nil: true
98
+ # Options `:if`, `:unless`, `:if_value`, `:unless_value` can be specified when enabled `:if` plugin
99
+ # They hide attribute key and value from response when conditions satisfied
100
+ # See more usage examples in :if plugin section.
101
+ attribute :email, if: proc { |user, ctx| user == ctx[:current_user] }
102
+ attribute :email, if_value: :present?
100
103
 
101
104
  # Option `:format` can be specified when enabled `:formatters` plugin
102
105
  # It changes attribute value
@@ -600,16 +603,45 @@ PostSerializer.new(with: "user(email)").to_h(post)
600
603
  PostSerializer.new(with: {user: %i[email, username]}).to_h(post)
601
604
  ```
602
605
 
603
- ### Plugin :hide_nil
606
+ ### Plugin :if
604
607
 
605
- Allows to hide attributes with `nil` values
608
+ Plugin adds `:if`, `:unless`, `:if_value`, `:unless_value` options to
609
+ attributes so we can remove attributes from response in various ways.
606
610
 
607
- ```ruby
608
- class UserSerializer < Serega
609
- plugin :hide_nil
611
+ Use `:if` and `:unless` when you want to hide attributes before finding attribute value,
612
+ and use `:if_value` and `:unless_value` to hide attributes after we find final value.
610
613
 
611
- attribute :email, hide_nil: true
612
- end
614
+ Options `:if` and `:unless` accept currently serialized object and context as parameters.
615
+ Options `:if_value` and `:unless_value` accept already found serialized value and context as parameters.
616
+
617
+ Options `:if_value` and `:unless_value` cannot be used with :serializer option, as
618
+ serialized objects have no "serialized value". Use `:if` and `:unless` in this case.
619
+
620
+ See also a `:hide` option that is available without any plugins to hide
621
+ attribute without conditions. Look at [select serialized fields](#selecting-fields) for `:hide` usage examples.
622
+
623
+ ```ruby
624
+ class UserSerializer < Serega
625
+ attribute :email, if: :active? # if user.active?
626
+ attribute :email, if: proc {|user| user.active?} # same
627
+ attribute :email, if: proc {|user, ctx| user == ctx[:current_user]} # using context
628
+ attribute :email, if: CustomPolicy.method(:view_email?) # You can provide own callable object
629
+
630
+ attribute :email, unless: :hidden? # unless user.hidden?
631
+ attribute :email, unless: proc {|user| user.hidden?} # same
632
+ attribute :email, unless: proc {|user, context| context[:show_emails]} # using context
633
+ attribute :email, unless: CustomPolicy.method(:hide_email?) # You can provide own callable object
634
+
635
+ attribute :email, if_value: :present? # if email.present?
636
+ attribute :email, if_value: proc {|email| email.present?} # same
637
+ attribute :email, if_value: proc {|email, ctx| ctx[:show_emails]} # using context
638
+ attribute :email, if_value: CustomPolicy.method(:view_email?) # You can provide own callable object
639
+
640
+ attribute :email, unless_value: :blank? # unless email.blank?
641
+ attribute :email, unless_value: proc {|email| email.blank?} # same
642
+ attribute :email, unless_value: proc {|email, context| context[:show_emails]} # using context
643
+ attribute :email, unless_value: CustomPolicy.method(:hide_email?) # You can provide own callable object
644
+ end
613
645
  ```
614
646
 
615
647
  ## Errors
@@ -648,3 +680,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
648
680
  [presenter]: #plugin-presenter
649
681
  [root]: #plugin-root
650
682
  [string_modifiers]: #plugin-string_modifiers
683
+ [if]: #plugin-if
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.3
1
+ 0.9.0
@@ -43,10 +43,14 @@ class Serega
43
43
 
44
44
  def serialize_object(object)
45
45
  points.each_with_object({}) do |point, container|
46
- attach_value(object, point, container)
46
+ serialize_point(object, point, container)
47
47
  end
48
48
  end
49
49
 
50
+ def serialize_point(object, point, container)
51
+ attach_value(object, point, container)
52
+ end
53
+
50
54
  def attach_value(object, point, container)
51
55
  value = point.value(object, context)
52
56
  final_value = final_value(value, point)
@@ -264,13 +264,17 @@ class Serega
264
264
  batch = point.batch
265
265
 
266
266
  if batch
267
- key = batch.key.call(object, context)
268
- opts[:batch_loaders].get(point, self).remember(key, container)
269
- container[point.name] = nil # Reserve attribute place in resulted hash. We will set correct value later
267
+ remember_key_for_batch_loading(batch, object, point, container)
270
268
  else
271
269
  super
272
270
  end
273
271
  end
272
+
273
+ def remember_key_for_batch_loading(batch, object, point, container)
274
+ key = batch.key.call(object, context)
275
+ opts[:batch_loaders].get(point, self).remember(key, container)
276
+ container[point.name] = nil # Reserve attribute place in resulted hash. We will set correct value later
277
+ end
274
278
  end
275
279
  end
276
280
 
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module SeregaPlugins
5
+ #
6
+ # Plugin adds `:if`, `:unless`, `:if_value`, `:unless_value` options to
7
+ # attributes so we can remove attributes from response in various ways.
8
+ #
9
+ # Use `:if` and `:unless` when you want to hide attributes before finding attribute value,
10
+ # and use `:if_value` and `:unless_value` to hide attributes after we find final value.
11
+ #
12
+ # Options `:if` and `:unless` accept currently serialized object and context as parameters.
13
+ # Options `:if_value` and `:unless_value` accept already found serialized value and context as parameters.
14
+ #
15
+ # Options `:if_value` and `:unless_value` cannot be used with :serializer option, as
16
+ # serialized objects have no "serialized value". Use `:if` and `:unless` in this case.
17
+ #
18
+ # See also a `:hide` option that is available without any plugins to hide
19
+ # attribute without conditions. Look at README.md#selecting-fields for `:hide` usage examples.
20
+ #
21
+ # Examples:
22
+ # class UserSerializer < Serega
23
+ # attribute :email, if: :active? # if user.active?
24
+ # attribute :email, if: proc {|user| user.active?} # same
25
+ # attribute :email, if: proc {|user, ctx| user == ctx[:current_user]} # using context
26
+ # attribute :email, if: CustomPolicy.method(:view_email?) # You can provide own callable object
27
+ #
28
+ # attribute :email, unless: :hidden? # unless user.hidden?
29
+ # attribute :email, unless: proc {|user| user.hidden?} # same
30
+ # attribute :email, unless: proc {|user, context| context[:show_emails]} # using context
31
+ # attribute :email, unless: CustomPolicy.method(:hide_email?) # You can provide own callable object
32
+ #
33
+ # attribute :email, if_value: :present? # if email.present?
34
+ # attribute :email, if_value: proc {|email| email.present?} # same
35
+ # attribute :email, if_value: proc {|email, ctx| ctx[:show_emails]} # using context
36
+ # attribute :email, if_value: CustomPolicy.method(:view_email?) # You can provide own callable object
37
+ #
38
+ # attribute :email, unless_value: :blank? # unless email.blank?
39
+ # attribute :email, unless_value: proc {|email| email.blank?} # same
40
+ # attribute :email, unless_value: proc {|email, context| context[:show_emails]} # using context
41
+ # attribute :email, unless_value: CustomPolicy.method(:hide_email?) # You can provide own callable object
42
+ # end
43
+ #
44
+ module If
45
+ # @return [Symbol] Plugin name
46
+ def self.plugin_name
47
+ :if
48
+ end
49
+
50
+ #
51
+ # Applies plugin code to specific serializer
52
+ #
53
+ # @param serializer_class [Class<Serega>] Current serializer class
54
+ # @param _opts [Hash] Loaded plugins options
55
+ #
56
+ # @return [void]
57
+ #
58
+ def self.load_plugin(serializer_class, **_opts)
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
+
64
+ serializer_class::SeregaMapPoint.include(MapPointInstanceMethods)
65
+ serializer_class::CheckAttributeParams.include(CheckAttributeParamsInstanceMethods)
66
+ serializer_class::SeregaObjectSerializer.include(SeregaObjectSerializerInstanceMethods)
67
+ end
68
+
69
+ # Checks requirements and loads additional plugins
70
+ #
71
+ # @param serializer_class [Class<Serega>] Current serializer class
72
+ # @param opts [Hash] loaded plugins opts
73
+ #
74
+ # @return [void]
75
+ #
76
+ def self.before_load_plugin(serializer_class, **opts)
77
+ if serializer_class.plugin_used?(:batch)
78
+ raise SeregaError, "Plugin `#{plugin_name}` must be loaded before `batch`"
79
+ end
80
+ end
81
+
82
+ #
83
+ # Adds config options and runs other callbacks after plugin was loaded
84
+ #
85
+ # @param serializer_class [Class<Serega>] Current serializer class
86
+ # @param opts [Hash] loaded plugins opts
87
+ #
88
+ # @return [void]
89
+ #
90
+ def self.after_load_plugin(serializer_class, **opts)
91
+ serializer_class.config.attribute_keys << :if << :if_value << :unless << :unless_value
92
+ end
93
+
94
+ #
95
+ # Serega::SeregaMapPoint additional/patched instance methods
96
+ #
97
+ # @see Serega::SeregaMapPoint::InstanceMethods
98
+ #
99
+ module MapPointInstanceMethods
100
+ #
101
+ # @return [Boolean] Should we show attribute or not
102
+ # Conditions for this checks are specified by :if and :unless attribute options.
103
+ #
104
+ def satisfy_if_conditions?(obj, ctx)
105
+ check_if_unless(obj, ctx, :if, :unless)
106
+ end
107
+
108
+ #
109
+ # @return [Boolean] Should we show attribute with specific value or not.
110
+ # Conditions for this checks are specified by :if_value and :unless_value attribute options.
111
+ #
112
+ def satisfy_if_value_conditions?(value, ctx)
113
+ check_if_unless(value, ctx, :if_value, :unless_value)
114
+ end
115
+
116
+ private
117
+
118
+ def check_if_unless(obj, ctx, opt_if_name, opt_unless_name)
119
+ opt_if = attribute.opts[opt_if_name]
120
+ opt_unless = attribute.opts[opt_unless_name]
121
+ return true if opt_if.nil? && opt_unless.nil?
122
+
123
+ res_if =
124
+ case opt_if
125
+ when NilClass then true
126
+ when Symbol then obj.public_send(opt_if)
127
+ else opt_if.call(obj, ctx)
128
+ end
129
+
130
+ res_unless =
131
+ case opt_unless
132
+ when NilClass then true
133
+ when Symbol then !obj.public_send(opt_unless)
134
+ else !opt_unless.call(obj, ctx)
135
+ end
136
+
137
+ res_if && res_unless
138
+ end
139
+ end
140
+
141
+ #
142
+ # Serega::SeregaValidations::CheckAttributeParams additional/patched class methods
143
+ #
144
+ # @see Serega::SeregaValidations::CheckAttributeParams
145
+ #
146
+ module CheckAttributeParamsInstanceMethods
147
+ private
148
+
149
+ def check_opts
150
+ super
151
+
152
+ CheckOptIf.call(opts)
153
+ CheckOptUnless.call(opts)
154
+ CheckOptIfValue.call(opts)
155
+ CheckOptUnlessValue.call(opts)
156
+ end
157
+ end
158
+
159
+ #
160
+ # SeregaObjectSerializer additional/patched class methods
161
+ #
162
+ # @see Serega::SeregaObjectSerializer
163
+ #
164
+ module SeregaObjectSerializerInstanceMethods
165
+ private
166
+
167
+ def serialize_point(object, point, _container)
168
+ return unless point.satisfy_if_conditions?(object, context)
169
+ super
170
+ end
171
+
172
+ def attach_final_value(value, point, _container)
173
+ return unless point.satisfy_if_value_conditions?(value, context)
174
+ super
175
+ end
176
+ end
177
+ end
178
+
179
+ register_plugin(If.plugin_name, If)
180
+ end
181
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module SeregaPlugins
5
+ module If
6
+ #
7
+ # Validator for attribute :if option
8
+ #
9
+ class CheckOptIf
10
+ class << self
11
+ #
12
+ # Checks attribute :if option that must be [nil, Symbol, Proc, #call]
13
+ #
14
+ # @param opts [Hash] Attribute options
15
+ #
16
+ # @raise [SeregaError] Attribute validation error
17
+ #
18
+ # @return [void]
19
+ #
20
+ def call(opts)
21
+ return unless opts.key?(:if)
22
+
23
+ check_type(opts[:if])
24
+ end
25
+
26
+ private
27
+
28
+ def check_type(value)
29
+ return if value.is_a?(Symbol)
30
+
31
+ raise SeregaError, must_be_callable unless value.respond_to?(:call)
32
+
33
+ if value.is_a?(Proc)
34
+ check_block(value)
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)
42
+
43
+ raise SeregaError, block_parameters_error
44
+ end
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)
61
+ end
62
+ end
63
+
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
+ def must_be_callable
73
+ "Invalid attribute option :if. It must be a Symbol, a Proc or respond to :call"
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module SeregaPlugins
5
+ module If
6
+ #
7
+ # Validator for attribute :if_value option
8
+ #
9
+ class CheckOptIfValue
10
+ class << self
11
+ #
12
+ # Checks attribute :if_value option that must be [nil, Symbol, Proc, #call]
13
+ #
14
+ # @param opts [Hash] Attribute options
15
+ #
16
+ # @raise [SeregaError] Attribute validation error
17
+ #
18
+ # @return [void]
19
+ #
20
+ def call(opts)
21
+ return unless opts.key?(:if_value)
22
+
23
+ check_usage_with_other_params(opts)
24
+ check_type(opts[:if_value])
25
+ end
26
+
27
+ private
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
+ def check_usage_with_other_params(opts)
42
+ raise SeregaError, "Option :if_value can not be used together with option :serializer" if opts.key?(:serializer)
43
+ end
44
+
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
56
+
57
+ def valid_parameters?(data, accepted_count:)
58
+ params = data.parameters
59
+ accepted_count.include?(params.count) && valid_parameters_types?(params)
60
+ end
61
+
62
+ def valid_parameters_types?(params)
63
+ params.all? do |param|
64
+ type = param[0]
65
+ (type == :req) || (type == :opt)
66
+ end
67
+ end
68
+
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
+ def must_be_callable
78
+ "Invalid attribute option :if_value. It must be a Symbol, a Proc or respond to :call"
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module SeregaPlugins
5
+ module If
6
+ #
7
+ # Validator for attribute :unless option
8
+ #
9
+ class CheckOptUnless
10
+ class << self
11
+ #
12
+ # Checks attribute :unless option that must be [nil, Symbol, Proc, #call]
13
+ #
14
+ # @param opts [Hash] Attribute options
15
+ #
16
+ # @raise [SeregaError] Attribute validation error
17
+ #
18
+ # @return [void]
19
+ #
20
+ def call(opts)
21
+ return unless opts.key?(:unless)
22
+
23
+ check_type(opts[:unless])
24
+ end
25
+
26
+ private
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
+ def check_type(value)
38
+ return if value.is_a?(Symbol)
39
+
40
+ raise SeregaError, must_be_callable unless value.respond_to?(:call)
41
+
42
+ if value.is_a?(Proc)
43
+ check_block(value)
44
+ else
45
+ check_callable(value)
46
+ end
47
+ end
48
+
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)
70
+ end
71
+ end
72
+
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
+ def must_be_callable
82
+ "Invalid attribute option :unless. It must be a Symbol, a Proc or respond to :call"
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module SeregaPlugins
5
+ module If
6
+ #
7
+ # Validator for attribute :unless_value option
8
+ #
9
+ class CheckOptUnlessValue
10
+ class << self
11
+ #
12
+ # Checks attribute :unless_value option that must be [nil, Symbol, Proc, #call]
13
+ #
14
+ # @param opts [Hash] Attribute options
15
+ #
16
+ # @raise [SeregaError] Attribute validation error
17
+ #
18
+ # @return [void]
19
+ #
20
+ def call(opts)
21
+ return unless opts.key?(:unless_value)
22
+
23
+ check_usage_with_other_params(opts)
24
+ check_type(opts[:unless_value])
25
+ end
26
+
27
+ private
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
+ def check_usage_with_other_params(opts)
42
+ raise SeregaError, "Option :unless_value can not be used together with option :serializer" if opts.key?(:serializer)
43
+ end
44
+
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
56
+
57
+ def valid_parameters?(data, accepted_count:)
58
+ params = data.parameters
59
+ accepted_count.include?(params.count) && valid_parameters_types?(params)
60
+ end
61
+
62
+ def valid_parameters_types?(params)
63
+ params.all? do |param|
64
+ type = param[0]
65
+ (type == :req) || (type == :opt)
66
+ end
67
+ end
68
+
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
+ def must_be_callable
78
+ "Invalid attribute option :unless_value. It must be a Symbol, a Proc or respond to :call"
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serega
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.3
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Glushkov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-14 00:00:00.000000000 Z
11
+ date: 2023-03-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  JSON Serializer
@@ -53,7 +53,11 @@ files:
53
53
  - lib/serega/plugins/batch/lib/validations/check_opt_batch.rb
54
54
  - lib/serega/plugins/context_metadata/context_metadata.rb
55
55
  - lib/serega/plugins/formatters/formatters.rb
56
- - lib/serega/plugins/hide_nil/hide_nil.rb
56
+ - lib/serega/plugins/if/if.rb
57
+ - lib/serega/plugins/if/validations/check_opt_if.rb
58
+ - lib/serega/plugins/if/validations/check_opt_if_value.rb
59
+ - lib/serega/plugins/if/validations/check_opt_unless.rb
60
+ - lib/serega/plugins/if/validations/check_opt_unless_value.rb
57
61
  - lib/serega/plugins/metadata/meta_attribute.rb
58
62
  - lib/serega/plugins/metadata/metadata.rb
59
63
  - lib/serega/plugins/metadata/validations/check_block.rb
@@ -115,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
119
  - !ruby/object:Gem::Version
116
120
  version: '0'
117
121
  requirements: []
118
- rubygems_version: 3.4.6
122
+ rubygems_version: 3.4.7
119
123
  signing_key:
120
124
  specification_version: 4
121
125
  summary: JSON Serializer
@@ -1,106 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- module SeregaPlugins
5
- #
6
- # Plugin adds `:hide_nil` option to attributes to delete them from final result
7
- # if value is nil
8
- #
9
- module HideNil
10
- # @return [Symbol] Plugin name
11
- def self.plugin_name
12
- :hide_nil
13
- end
14
-
15
- #
16
- # Applies plugin code to specific serializer
17
- #
18
- # @param serializer_class [Class<Serega>] Current serializer class
19
- # @param _opts [Hash] Loaded plugins options
20
- #
21
- # @return [void]
22
- #
23
- def self.load_plugin(serializer_class, **_opts)
24
- serializer_class::SeregaAttribute.include(AttributeInstanceMethods)
25
- serializer_class::CheckAttributeParams.include(CheckAttributeParamsInstanceMethods)
26
- serializer_class::SeregaObjectSerializer.include(SeregaObjectSerializerInstanceMethods)
27
- end
28
-
29
- #
30
- # Adds config options and runs other callbacks after plugin was loaded
31
- #
32
- # @param serializer_class [Class<Serega>] Current serializer class
33
- # @param opts [Hash] loaded plugins opts
34
- #
35
- # @return [void]
36
- #
37
- def self.after_load_plugin(serializer_class, **opts)
38
- serializer_class.config.attribute_keys << :hide_nil
39
- end
40
-
41
- #
42
- # Serega::SeregaAttribute additional/patched instance methods
43
- #
44
- # @see Serega::SeregaValidations::CheckAttributeParams
45
- #
46
- module AttributeInstanceMethods
47
- # Check hide_nil is specified
48
- def hide_nil?
49
- !!opts[:hide_nil]
50
- end
51
- end
52
-
53
- #
54
- # Serega::SeregaValidations::CheckAttributeParams additional/patched class methods
55
- #
56
- # @see Serega::SeregaValidations::CheckAttributeParams
57
- #
58
- module CheckAttributeParamsInstanceMethods
59
- private
60
-
61
- def check_opts
62
- super
63
- CheckOptHideNil.call(opts)
64
- end
65
- end
66
-
67
- #
68
- # Validator class for :hide_nil attribute option
69
- #
70
- class CheckOptHideNil
71
- #
72
- # Checks attribute :hide_nil option
73
- #
74
- # @param opts [Hash] Attribute options
75
- #
76
- # @raise [Serega::SeregaError] SeregaError that option has invalid value
77
- #
78
- # @return [void]
79
- #
80
- def self.call(opts)
81
- return unless opts.key?(:hide_nil)
82
-
83
- value = opts[:hide_nil]
84
- return if (value == true) || (value == false)
85
-
86
- raise SeregaError, "Invalid option :hide_nil => #{value.inspect}. Must have a boolean value"
87
- end
88
- end
89
-
90
- #
91
- # SeregaObjectSerializer additional/patched class methods
92
- #
93
- # @see Serega::SeregaObjectSerializer
94
- #
95
- module SeregaObjectSerializerInstanceMethods
96
- private
97
-
98
- def attach_final_value(final_value, *)
99
- super unless final_value.nil?
100
- end
101
- end
102
- end
103
-
104
- register_plugin(HideNil.plugin_name, HideNil)
105
- end
106
- end