serega 0.1.1 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d35551791e1f846527be7fa3176db641f292dae4e5d8108464e52af67cd5025d
4
- data.tar.gz: 729261f9aa1a2734e40390ea0a253bd7e931a7bd31665cbd7846394b51042fa4
3
+ metadata.gz: cd45eb1a9dc3574d752395461dfcb44502996f8a9f46369dfbc325ece5e41e68
4
+ data.tar.gz: '0395711231e3aeb8ef5b75387ccb99d0b91dce0b01f52646fc308e32e6cadfb1'
5
5
  SHA512:
6
- metadata.gz: 878c59b774c71dabfe9ebf745a0349ebd25fb329e44cd9cba53e2f405844e6639d6f153813e0c475fc03f158b5c04a3fdfad4f41c952d1cd4afcddaed251fbcb
7
- data.tar.gz: 4fac4c3293292a6644c2976cfbb65ba91c2b8aa0ed8dddd5e24b3ac9ed01b9c954973cce94095a63c377c373f3a26c0ac6ee397109b5f79414f1ef6b0e066632
6
+ metadata.gz: '074159a4a437b0419995614774d2467075ff6a18ae4300f25ea4026253112a40a93073d9e56d80a523e7769afca754e0395d833f3b92a7687a59360d8df87327'
7
+ data.tar.gz: ff386d77eb7af6fc9a5daa9c8280a179efb34266243f353a0d935ca31090abaf9c02af69abe3eedcec7d5b6d7d48274a883507455b6272c78ba9e0ea30eaa4a5
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.1.2
@@ -33,11 +33,11 @@ class Serega
33
33
  # @param block [Proc] Proc that receives object and context and finds attribute value
34
34
  #
35
35
  def initialize(name:, opts: {}, block: nil)
36
- check(name, opts, block)
36
+ self.class.serializer_class::CheckAttributeParams.new(name, opts, block).validate
37
37
 
38
38
  @name = name.to_sym
39
39
  @opts = Utils::EnumDeepDup.call(opts)
40
- @block = opts[:value] || block
40
+ @block = block
41
41
  end
42
42
 
43
43
  # @return [Symbol] Object method name to will be used to get attribute value unless block provided
@@ -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 || keyword_block
80
+ @value_block = block || opts[:value] || const_block || keyword_block
81
81
  end
82
82
 
83
83
  #
@@ -112,16 +112,17 @@ class Serega
112
112
 
113
113
  private
114
114
 
115
+ def const_block
116
+ return unless opts.key?(:const)
117
+
118
+ const = opts[:const]
119
+ proc { const }
120
+ end
121
+
115
122
  def keyword_block
116
123
  key_method_name = key
117
124
  proc { |object| object.public_send(key_method_name) }
118
125
  end
119
-
120
- def check(name, opts, block)
121
- CheckName.call(name)
122
- CheckOpts.call(opts, self.class.serializer_class.config[:attribute_keys])
123
- CheckBlock.call(opts, block)
124
- end
125
126
  end
126
127
 
127
128
  extend Serega::Helpers::SerializerClassHelper
@@ -22,7 +22,7 @@ class Serega
22
22
  #
23
23
  def self.load_plugin(serializer_class, **_opts)
24
24
  serializer_class::Attribute.include(AttributeMethods)
25
- serializer_class::Attribute::CheckOpts.extend(CheckOptsClassMethods)
25
+ serializer_class::CheckAttributeParams.include(CheckAttributeParamsInstanceMethods)
26
26
  serializer_class::ConvertItem.extend(ConvertItemClassMethods)
27
27
  end
28
28
 
@@ -37,10 +37,10 @@ class Serega
37
37
  end
38
38
  end
39
39
 
40
- module CheckOptsClassMethods
40
+ module CheckAttributeParamsInstanceMethods
41
41
  private
42
42
 
43
- def check_each_opt(opts)
43
+ def check_opts
44
44
  super
45
45
  CheckOptHideNil.call(opts)
46
46
  end
@@ -23,7 +23,7 @@ class Serega
23
23
  serializer_class.include(InstanceMethods)
24
24
  serializer_class::Attribute.include(AttributeMethods)
25
25
 
26
- serializer_class::Attribute::CheckOpts.extend(CheckOptsClassMethods)
26
+ serializer_class::CheckAttributeParams.include(CheckAttributeParamsInstanceMethods)
27
27
 
28
28
  require_relative "./lib/enum_deep_freeze"
29
29
  require_relative "./lib/format_user_preloads"
@@ -85,10 +85,10 @@ class Serega
85
85
  end
86
86
  end
87
87
 
88
- module CheckOptsClassMethods
88
+ module CheckAttributeParamsInstanceMethods
89
89
  private
90
90
 
91
- def check_each_opt(opts)
91
+ def check_opts
92
92
  super
93
93
  CheckOptPreloadPath.call(opts)
94
94
  end
@@ -1,79 +1,49 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Serega
4
- class Attribute
5
- class CheckBlock
6
- class << self
7
- #
8
- # Checks :value option or a block provided with attribute
9
- # Must have up to two arguments - object and context.
10
- # It should not have any *rest or **key arguments
11
- #
12
- # @example without arguments
13
- # attribute(:email) { CONSTANT_EMAIL }
14
- #
15
- # @example with one argument
16
- # attribute(:email) { |obj| obj.confirmed_email }
17
- #
18
- # @example with two arguments
19
- # attribute(:email) { |obj, context| context['is_current'] ? obj.email : nil }
20
- #
21
- # @param opts [Proc] Attribute opts, we will check :value option
22
- # @param block [Proc] Block that returns serialized attribute value
23
- #
24
- # @raise [Error] Error that block has invalid arguments
25
- #
26
- # @return [void]
27
- #
28
- def call(opts, block)
29
- check_both_provided(opts, block)
4
+ module Validations
5
+ module Attribute
6
+ class CheckBlock
7
+ class << self
8
+ #
9
+ # Checks :value option or a block provided with attribute
10
+ # Must have up to two arguments - object and context.
11
+ # It should not have any *rest or **key arguments
12
+ #
13
+ # @example without arguments
14
+ # attribute(:email) { CONSTANT_EMAIL }
15
+ #
16
+ # @example with one argument
17
+ # attribute(:email) { |obj| obj.confirmed_email }
18
+ #
19
+ # @example with two arguments
20
+ # attribute(:email) { |obj, context| context['is_current'] ? obj.email : nil }
21
+ #
22
+ # @param opts [Proc] Attribute opts, we will check :value option
23
+ # @param block [Proc] Block that returns serialized attribute value
24
+ #
25
+ # @raise [Error] Error that block has invalid arguments
26
+ #
27
+ # @return [void]
28
+ #
29
+ def call(block)
30
+ return unless block
30
31
 
31
- if block
32
32
  check_block(block)
33
- elsif opts.key?(:value)
34
- check_value(opts[:value])
35
33
  end
36
- end
37
-
38
- private
39
-
40
- def check_both_provided(opts, block)
41
- if opts.key?(:value) && block
42
- raise Error, both_error
43
- end
44
- end
45
-
46
- def check_block(block)
47
- params = block.parameters
48
- return if (params.count <= 2) && params.all? { |par| par[0] == :opt }
49
-
50
- raise Error, block_error
51
- end
52
34
 
53
- def check_value(value)
54
- raise Error, value_error unless value.is_a?(Proc)
35
+ private
55
36
 
56
- params = value.parameters
37
+ def check_block(block)
38
+ params = block.parameters
39
+ return if (params.count <= 2) && params.all? { |par| par[0] == :opt }
57
40
 
58
- if value.lambda?
59
- return if (params.count == 2) && params.all? { |par| par[0] == :req }
60
- elsif (params.count <= 2) && params.all? { |par| par[0] == :opt }
61
- return
41
+ raise Error, block_error
62
42
  end
63
43
 
64
- raise Error, value_error
65
- end
66
-
67
- def block_error
68
- "Block can have maximum two regular parameters (no **keyword or *array args)"
69
- end
70
-
71
- def value_error
72
- "Option :value must be a Proc that is able to accept two parameters (no **keyword or *array args)"
73
- end
74
-
75
- def both_error
76
- "Block and a :value option can not be provided together"
44
+ def block_error
45
+ "Block can have maximum two regular parameters (no **keyword or *array args)"
46
+ end
77
47
  end
78
48
  end
79
49
  end
@@ -1,43 +1,45 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Serega
4
- class Attribute
5
- class CheckName
6
- FORMAT_ONE_CHAR = /\A[a-zA-Z0-9]\z/
7
- FORMAT_MANY_CHARS = /\A[a-zA-Z0-9][a-zA-Z0-9_-]*?[a-zA-Z0-9]\z/ # allow '-' and '_' in the middle
8
-
9
- private_constant :FORMAT_ONE_CHAR, :FORMAT_MANY_CHARS
10
-
11
- class << self
12
- #
13
- # Checks allowed characters.
14
- # Globally allowed characters: "a-z", "A-Z", "0-9".
15
- # Minus and low line "-", "_" also allowed except as the first or last character.
16
- #
17
- # @param name [String, Symbol] Attribute name
18
- #
19
- # @raise [Error] when name has invalid format
20
- # @return [void]
21
- #
22
- def call(name)
23
- name = name.to_s
24
-
25
- valid =
26
- case name.size
27
- when 0 then false
28
- when 1 then name.match?(FORMAT_ONE_CHAR)
29
- else name.match?(FORMAT_MANY_CHARS)
30
- end
31
-
32
- return if valid
33
-
34
- raise Error, message(name)
35
- end
36
-
37
- private
38
-
39
- def message(name)
40
- %(Invalid attribute name = #{name.inspect}. Globally allowed characters: "a-z", "A-Z", "0-9". Minus and low line "-", "_" also allowed except as the first or last character)
4
+ module Validations
5
+ module Attribute
6
+ class CheckName
7
+ FORMAT_ONE_CHAR = /\A[a-zA-Z0-9]\z/
8
+ FORMAT_MANY_CHARS = /\A[a-zA-Z0-9][a-zA-Z0-9_-]*?[a-zA-Z0-9]\z/ # allow '-' and '_' in the middle
9
+
10
+ private_constant :FORMAT_ONE_CHAR, :FORMAT_MANY_CHARS
11
+
12
+ class << self
13
+ #
14
+ # Checks allowed characters.
15
+ # Globally allowed characters: "a-z", "A-Z", "0-9".
16
+ # Minus and low line "-", "_" also allowed except as the first or last character.
17
+ #
18
+ # @param name [String, Symbol] Attribute name
19
+ #
20
+ # @raise [Error] when name has invalid format
21
+ # @return [void]
22
+ #
23
+ def call(name)
24
+ name = name.to_s
25
+
26
+ valid =
27
+ case name.size
28
+ when 0 then false
29
+ when 1 then name.match?(FORMAT_ONE_CHAR)
30
+ else name.match?(FORMAT_MANY_CHARS)
31
+ end
32
+
33
+ return if valid
34
+
35
+ raise Error, message(name)
36
+ end
37
+
38
+ private
39
+
40
+ def message(name)
41
+ %(Invalid attribute name = #{name.inspect}. Globally allowed characters: "a-z", "A-Z", "0-9". Minus and low line "-", "_" also allowed except as the first or last character)
42
+ end
41
43
  end
42
44
  end
43
45
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module Validations
5
+ module Attribute
6
+ class CheckOptConst
7
+ #
8
+ # Checks attribute :const option
9
+ #
10
+ # @param opts [Hash] Attribute options
11
+ #
12
+ # @raise [Error] Attribute validation error
13
+ #
14
+ # @return [void]
15
+ #
16
+ class << self
17
+ def call(opts, block = nil)
18
+ return unless opts.key?(:const)
19
+
20
+ check_usage_with_other_params(opts, block)
21
+ end
22
+
23
+ private
24
+
25
+ def check_usage_with_other_params(opts, block)
26
+ raise Error, "Option :const can not be used together with option :key" if opts.key?(:key)
27
+ raise Error, "Option :const can not be used together with option :value" if opts.key?(:value)
28
+ raise Error, "Option :const can not be used together with block" if block
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,19 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Serega
4
- class Attribute
5
- class CheckOptHide
6
- #
7
- # Checks attribute :hide option
8
- #
9
- # @param opts [Hash] Attribute options
10
- #
11
- # @raise [Error] Error that option has invalid value
12
- #
13
- # @return [void]
14
- #
15
- def self.call(opts)
16
- CheckOptIsBool.call(opts, :hide)
4
+ module Validations
5
+ module Attribute
6
+ class CheckOptHide
7
+ #
8
+ # Checks attribute :hide option
9
+ #
10
+ # @param opts [Hash] Attribute options
11
+ #
12
+ # @raise [Error] Error that option has invalid value
13
+ #
14
+ # @return [void]
15
+ #
16
+ def self.call(opts)
17
+ Utils::CheckOptIsBool.call(opts, :hide)
18
+ end
17
19
  end
18
20
  end
19
21
  end
@@ -1,24 +1,34 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Serega
4
- class Attribute
5
- class CheckOptKey
6
- #
7
- # Checks attribute :key option
8
- #
9
- # @param opts [Hash] Attribute options
10
- #
11
- # @raise [Error] Error that option has invalid value
12
- #
13
- # @return [void]
14
- #
15
- def self.call(opts)
16
- return unless opts.key?(:key)
4
+ module Validations
5
+ module Attribute
6
+ class CheckOptKey
7
+ #
8
+ # Checks attribute :key option
9
+ #
10
+ # @param opts [Hash] Attribute options
11
+ #
12
+ # @raise [Error] Error that option has invalid value
13
+ #
14
+ # @return [void]
15
+ #
16
+ class << self
17
+ def call(opts, block = nil)
18
+ return unless opts.key?(:key)
17
19
 
18
- value = opts[:key]
19
- return if value.is_a?(String) || value.is_a?(Symbol)
20
+ check_usage_with_other_params(opts, block)
21
+ Utils::CheckOptIsStringOrSymbol.call(opts, :key)
22
+ end
20
23
 
21
- raise Error, "Invalid option :key => #{value.inspect}. Must be a String or a Symbol"
24
+ private
25
+
26
+ def check_usage_with_other_params(opts, block)
27
+ raise Error, "Option :key can not be used together with option :const" if opts.key?(:const)
28
+ raise Error, "Option :key can not be used together with option :value" if opts.key?(:value)
29
+ raise Error, "Option :key can not be used together with block" if block
30
+ end
31
+ end
22
32
  end
23
33
  end
24
34
  end
@@ -1,19 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Serega
4
- class Attribute
5
- class CheckOptMany
6
- #
7
- # Checks attribute :many option
8
- #
9
- # @param opts [Hash] Attribute options
10
- #
11
- # @raise [Error] Error that option has invalid value
12
- #
13
- # @return [void]
14
- #
15
- def self.call(opts)
16
- CheckOptIsBool.call(opts, :many)
4
+ module Validations
5
+ module Attribute
6
+ class CheckOptMany
7
+ #
8
+ # Checks attribute :many option
9
+ #
10
+ # @param opts [Hash] Attribute options
11
+ #
12
+ # @raise [Error] Error that option has invalid value
13
+ #
14
+ # @return [void]
15
+ #
16
+ def self.call(opts)
17
+ Utils::CheckOptIsBool.call(opts, :many)
18
+ end
17
19
  end
18
20
  end
19
21
  end
@@ -1,34 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Serega
4
- class Attribute
5
- class CheckOptSerializer
6
- class << self
7
- #
8
- # Checks attribute :serializer option
9
- #
10
- # @param opts [Hash] Attribute options
11
- #
12
- # @raise [Error] Error that option has invalid value
13
- #
14
- # @return [void]
15
- #
16
- def call(opts)
17
- return unless opts.key?(:serializer)
4
+ module Validations
5
+ module Attribute
6
+ class CheckOptSerializer
7
+ class << self
8
+ #
9
+ # Checks attribute :serializer option
10
+ #
11
+ # @param opts [Hash] Attribute options
12
+ #
13
+ # @raise [Error] Error that option has invalid value
14
+ #
15
+ # @return [void]
16
+ #
17
+ def call(opts)
18
+ return unless opts.key?(:serializer)
18
19
 
19
- value = opts[:serializer]
20
- return if valid_serializer?(value)
20
+ value = opts[:serializer]
21
+ return if valid_serializer?(value)
21
22
 
22
- raise Error, "Invalid option :serializer => #{value.inspect}." \
23
- " Can be a Serega subclass, a String or a Proc without arguments"
24
- end
23
+ raise Error, "Invalid option :serializer => #{value.inspect}." \
24
+ " Can be a Serega subclass, a String or a Proc without arguments"
25
+ end
25
26
 
26
- private
27
+ private
27
28
 
28
- def valid_serializer?(value)
29
- value.is_a?(String) ||
30
- (value.is_a?(Proc) && (value.parameters.count == 0)) ||
31
- (value.is_a?(Class) && (value < Serega))
29
+ def valid_serializer?(value)
30
+ value.is_a?(String) ||
31
+ (value.is_a?(Proc) && (value.parameters.count == 0)) ||
32
+ (value.is_a?(Class) && (value < Serega))
33
+ end
32
34
  end
33
35
  end
34
36
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module Validations
5
+ module Attribute
6
+ class CheckOptValue
7
+ #
8
+ # Checks attribute :value option
9
+ #
10
+ # @param opts [Hash] Attribute options
11
+ #
12
+ # @raise [Error] Error that option has invalid value
13
+ #
14
+ # @return [void]
15
+ #
16
+ class << self
17
+ def call(opts, block = nil)
18
+ return unless opts.key?(:value)
19
+
20
+ check_usage_with_other_params(opts, block)
21
+ check_proc(opts[:value])
22
+ end
23
+
24
+ private
25
+
26
+ def check_usage_with_other_params(opts, block)
27
+ raise Error, "Option :value can not be used together with option :key" if opts.key?(:key)
28
+ raise Error, "Option :value can not be used together with option :const" if opts.key?(:const)
29
+ raise Error, "Option :value can not be used together with block" if block
30
+ end
31
+
32
+ def check_proc(value)
33
+ raise Error, value_error unless value.is_a?(Proc)
34
+
35
+ params = value.parameters
36
+
37
+ if value.lambda?
38
+ return if (params.count == 2) && params.all? { |par| par[0] == :req }
39
+ elsif (params.count <= 2) && params.all? { |par| par[0] == :opt }
40
+ return
41
+ end
42
+
43
+ raise Error, value_error
44
+ end
45
+
46
+ def value_error
47
+ "Option :value must be a Proc that is able to accept two parameters (no **keyword or *array args)"
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module Validations
5
+ class CheckAttributeParams
6
+ module InstanceMethods
7
+ attr_reader :name, :opts, :block
8
+
9
+ def initialize(name, opts, block)
10
+ @name = name
11
+ @opts = opts
12
+ @block = block
13
+ end
14
+
15
+ def validate
16
+ check_name
17
+ check_opts
18
+ check_block
19
+ end
20
+
21
+ private
22
+
23
+ def check_name
24
+ Attribute::CheckName.call(name)
25
+ end
26
+
27
+ def check_opts
28
+ Utils::CheckAllowedKeys.call(opts, allowed_opts_keys)
29
+
30
+ Attribute::CheckOptConst.call(opts, block)
31
+ Attribute::CheckOptHide.call(opts)
32
+ Attribute::CheckOptKey.call(opts, block)
33
+ Attribute::CheckOptMany.call(opts)
34
+ Attribute::CheckOptSerializer.call(opts)
35
+ Attribute::CheckOptValue.call(opts, block)
36
+ end
37
+
38
+ def check_block
39
+ Attribute::CheckBlock.call(block)
40
+ end
41
+
42
+ def allowed_opts_keys
43
+ self.class.serializer_class.config[:attribute_keys]
44
+ end
45
+ end
46
+
47
+ include InstanceMethods
48
+ extend Serega::Helpers::SerializerClassHelper
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module Validations
5
+ class CheckInitiateParams
6
+ module ClassMethods
7
+ def call(opts)
8
+ check_opts(opts)
9
+ end
10
+
11
+ private
12
+
13
+ def check_opts(opts)
14
+ Utils::CheckAllowedKeys.call(opts, allowed_opts_keys)
15
+ end
16
+
17
+ def allowed_opts_keys
18
+ serializer_class.config[:initiate_keys]
19
+ end
20
+ end
21
+
22
+ extend ClassMethods
23
+ extend Serega::Helpers::SerializerClassHelper
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module Validations
5
+ class CheckSerializeParams
6
+ module ClassMethods
7
+ def call(opts)
8
+ check_opts(opts)
9
+ end
10
+
11
+ private
12
+
13
+ def check_opts(opts)
14
+ Utils::CheckAllowedKeys.call(opts, allowed_opts_keys)
15
+
16
+ Utils::CheckOptIsHash.call(opts, :context)
17
+ Utils::CheckOptIsBool.call(opts, :many)
18
+ end
19
+
20
+ def allowed_opts_keys
21
+ serializer_class.config[:serialize_keys]
22
+ end
23
+ end
24
+
25
+ extend ClassMethods
26
+ extend Serega::Helpers::SerializerClassHelper
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module Validations
5
+ module Utils
6
+ class CheckAllowedKeys
7
+ def self.call(opts, allowed_keys)
8
+ opts.each_key do |key|
9
+ next if allowed_keys.include?(key)
10
+
11
+ raise Error, "Invalid option #{key.inspect}. Allowed options are: #{allowed_keys.map(&:inspect).join(", ")}"
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module Validations
5
+ module Utils
6
+ class CheckOptIsBool
7
+ def self.call(opts, key)
8
+ return unless opts.key?(key)
9
+
10
+ value = opts[key]
11
+ return if value.equal?(true) || value.equal?(false)
12
+
13
+ raise Error, "Invalid option #{key.inspect} => #{value.inspect}. Must have a boolean value"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module Validations
5
+ module Utils
6
+ class CheckOptIsHash
7
+ def self.call(opts, key)
8
+ return unless opts.key?(key)
9
+
10
+ value = opts[key]
11
+ return if value.is_a?(Hash)
12
+
13
+ raise Error, "Invalid option #{key.inspect} => #{value.inspect}. Must have a Hash value"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Serega
4
+ module Validations
5
+ module Utils
6
+ class CheckOptIsStringOrSymbol
7
+ def self.call(opts, key)
8
+ return unless opts.key?(key)
9
+
10
+ value = opts[key]
11
+ return if value.is_a?(String) || value.is_a?(Symbol)
12
+
13
+ raise Error, "Invalid option #{key.inspect} => #{value.inspect}. Must be a String or a Symbol"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
data/lib/serega.rb CHANGED
@@ -21,16 +21,21 @@ require_relative "serega/utils/to_json"
21
21
  require_relative "serega/utils/as_json"
22
22
 
23
23
  require_relative "serega/attribute"
24
- require_relative "serega/validations/check_allowed_keys"
25
- require_relative "serega/validations/check_opt_is_bool"
26
- require_relative "serega/validations/check_opt_is_hash"
24
+ require_relative "serega/validations/utils/check_allowed_keys"
25
+ require_relative "serega/validations/utils/check_opt_is_bool"
26
+ require_relative "serega/validations/utils/check_opt_is_hash"
27
+ require_relative "serega/validations/utils/check_opt_is_string_or_symbol"
27
28
  require_relative "serega/validations/attribute/check_block"
28
29
  require_relative "serega/validations/attribute/check_name"
30
+ require_relative "serega/validations/attribute/check_opt_const"
29
31
  require_relative "serega/validations/attribute/check_opt_hide"
30
32
  require_relative "serega/validations/attribute/check_opt_key"
31
33
  require_relative "serega/validations/attribute/check_opt_many"
32
34
  require_relative "serega/validations/attribute/check_opt_serializer"
33
- require_relative "serega/validations/attribute/check_opts"
35
+ require_relative "serega/validations/attribute/check_opt_value"
36
+ require_relative "serega/validations/check_attribute_params"
37
+ require_relative "serega/validations/check_initiate_params"
38
+ require_relative "serega/validations/check_serialize_params"
34
39
 
35
40
  require_relative "serega/config"
36
41
  require_relative "serega/convert"
@@ -43,13 +48,25 @@ class Serega
43
48
  {
44
49
  plugins: [],
45
50
  initiate_keys: %i[only with except],
46
- attribute_keys: %i[key value serializer many hide],
51
+ attribute_keys: %i[key value serializer many hide const],
47
52
  serialize_keys: %i[context many],
48
53
  max_cached_map_per_serializer_count: 50,
49
54
  to_json: ->(data) { Utils::ToJSON.call(data) }
50
55
  }
51
56
  )
52
57
 
58
+ check_attribute_params_class = Class.new(Validations::CheckAttributeParams)
59
+ check_attribute_params_class.serializer_class = self
60
+ const_set(:CheckAttributeParams, check_attribute_params_class)
61
+
62
+ check_initiate_params_class = Class.new(Validations::CheckInitiateParams)
63
+ check_initiate_params_class.serializer_class = self
64
+ const_set(:CheckInitiateParams, check_initiate_params_class)
65
+
66
+ check_serialize_params_class = Class.new(Validations::CheckSerializeParams)
67
+ check_serialize_params_class.serializer_class = self
68
+ const_set(:CheckSerializeParams, check_serialize_params_class)
69
+
53
70
  # Core serializer class methods
54
71
  module ClassMethods
55
72
  # @return [Config] current serializer config
@@ -77,6 +94,18 @@ class Serega
77
94
  convert_item_class.serializer_class = subclass
78
95
  subclass.const_set(:ConvertItem, convert_item_class)
79
96
 
97
+ check_attribute_params_class = Class.new(self::CheckAttributeParams)
98
+ check_attribute_params_class.serializer_class = subclass
99
+ subclass.const_set(:CheckAttributeParams, check_attribute_params_class)
100
+
101
+ check_initiate_params_class = Class.new(self::CheckInitiateParams)
102
+ check_initiate_params_class.serializer_class = subclass
103
+ subclass.const_set(:CheckInitiateParams, check_initiate_params_class)
104
+
105
+ check_serialize_params_class = Class.new(self::CheckSerializeParams)
106
+ check_serialize_params_class.serializer_class = subclass
107
+ subclass.const_set(:CheckSerializeParams, check_serialize_params_class)
108
+
80
109
  # Assign same attributes
81
110
  attributes.each_value do |attr|
82
111
  subclass.attribute(attr.name, **attr.opts, &attr.block)
@@ -167,11 +196,15 @@ class Serega
167
196
  attribute(name, serializer: serializer, **opts, &block)
168
197
  end
169
198
 
170
- def to_h(object, opts = FROZEN_EMPTY_HASH)
199
+ def call(object, opts = FROZEN_EMPTY_HASH)
171
200
  initiate_keys = config[:initiate_keys]
172
201
  new(opts.slice(*initiate_keys)).to_h(object, opts.except(*initiate_keys))
173
202
  end
174
203
 
204
+ def to_h(object, opts = FROZEN_EMPTY_HASH)
205
+ call(object, opts)
206
+ end
207
+
175
208
  def to_json(object, opts = FROZEN_EMPTY_HASH)
176
209
  initiate_keys = config[:initiate_keys]
177
210
  new(opts.slice(*initiate_keys)).to_json(object, opts.except(*initiate_keys))
@@ -197,7 +230,7 @@ class Serega
197
230
  # @param with [Array, Hash, String, Symbol] Attributes (usually hidden) to serialize additionally
198
231
  #
199
232
  def initialize(opts = FROZEN_EMPTY_HASH)
200
- CheckAllowedKeys.call(opts, self.class.config[:initiate_keys])
233
+ self.class::CheckInitiateParams.call(opts)
201
234
  opts = prepare_modifiers(opts) if opts && (opts != FROZEN_EMPTY_HASH)
202
235
  @opts = opts
203
236
  end
@@ -210,15 +243,18 @@ class Serega
210
243
  #
211
244
  # @return [Hash] Serialization result
212
245
  #
213
- def to_h(object, opts = {})
214
- CheckAllowedKeys.call(opts, self.class.config[:serialize_keys])
215
- CheckOptIsHash.call(opts, :context)
216
- CheckOptIsBool.call(opts, :many)
246
+ def call(object, opts = {})
247
+ self.class::CheckSerializeParams.call(opts)
217
248
  opts[:context] ||= {}
218
249
 
219
250
  self.class::Convert.call(object, **opts, map: map)
220
251
  end
221
252
 
253
+ # @see #call
254
+ def to_h(object, opts = {})
255
+ call(object, opts)
256
+ end
257
+
222
258
  #
223
259
  # Serializes provided object to json
224
260
  #
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.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Glushkov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-13 00:00:00.000000000 Z
11
+ date: 2022-07-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -56,14 +56,19 @@ files:
56
56
  - lib/serega/utils/to_json.rb
57
57
  - lib/serega/validations/attribute/check_block.rb
58
58
  - lib/serega/validations/attribute/check_name.rb
59
+ - lib/serega/validations/attribute/check_opt_const.rb
59
60
  - lib/serega/validations/attribute/check_opt_hide.rb
60
61
  - lib/serega/validations/attribute/check_opt_key.rb
61
62
  - lib/serega/validations/attribute/check_opt_many.rb
62
63
  - lib/serega/validations/attribute/check_opt_serializer.rb
63
- - lib/serega/validations/attribute/check_opts.rb
64
- - lib/serega/validations/check_allowed_keys.rb
65
- - lib/serega/validations/check_opt_is_bool.rb
66
- - lib/serega/validations/check_opt_is_hash.rb
64
+ - lib/serega/validations/attribute/check_opt_value.rb
65
+ - lib/serega/validations/check_attribute_params.rb
66
+ - lib/serega/validations/check_initiate_params.rb
67
+ - lib/serega/validations/check_serialize_params.rb
68
+ - lib/serega/validations/utils/check_allowed_keys.rb
69
+ - lib/serega/validations/utils/check_opt_is_bool.rb
70
+ - lib/serega/validations/utils/check_opt_is_hash.rb
71
+ - lib/serega/validations/utils/check_opt_is_string_or_symbol.rb
67
72
  - lib/serega/version.rb
68
73
  homepage: https://github.com/aglushkov/serega
69
74
  licenses:
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- class Attribute
5
- class CheckOpts
6
- module ClassMethods
7
- #
8
- # Validates attribute options
9
- # Checks used options are allowed and then checks options values.
10
- #
11
- # @param opts [Hash] Attribute options
12
- # @param attribute_keys [Array<Symbol>] Allowed options keys
13
- #
14
- # @raise [Error] when attribute has invalid options
15
- #
16
- # @return [void]
17
- #
18
- def call(opts, attribute_keys)
19
- CheckAllowedKeys.call(opts, attribute_keys)
20
- check_each_opt(opts)
21
- end
22
-
23
- private
24
-
25
- def check_each_opt(opts)
26
- CheckOptHide.call(opts)
27
- CheckOptKey.call(opts)
28
- CheckOptMany.call(opts)
29
- CheckOptSerializer.call(opts)
30
- end
31
- end
32
-
33
- extend ClassMethods
34
- end
35
- end
36
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- class CheckAllowedKeys
5
- def self.call(opts, allowed_keys)
6
- opts.each_key do |key|
7
- next if allowed_keys.include?(key)
8
-
9
- raise Error, "Invalid option #{key.inspect}. Allowed options are: #{allowed_keys.map(&:inspect).join(", ")}"
10
- end
11
- end
12
- end
13
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- class CheckOptIsBool
5
- def self.call(opts, key)
6
- return unless opts.key?(key)
7
-
8
- value = opts[key]
9
- return if value.equal?(true) || value.equal?(false)
10
-
11
- raise Error, "Invalid option #{key.inspect} => #{value.inspect}. Must have a boolean value"
12
- end
13
- end
14
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Serega
4
- class CheckOptIsHash
5
- def self.call(opts, key)
6
- return unless opts.key?(key)
7
-
8
- value = opts[key]
9
- return if value.is_a?(Hash)
10
-
11
- raise Error, "Invalid option #{key.inspect} => #{value.inspect}. Must have a Hash value"
12
- end
13
- end
14
- end