servactory 2.0.3 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/config/locales/en.yml +3 -3
  3. data/config/locales/ru.yml +3 -3
  4. data/lib/servactory/context/workspace/inputs.rb +8 -6
  5. data/lib/servactory/context/workspace/internals.rb +2 -2
  6. data/lib/servactory/context/workspace/outputs.rb +2 -2
  7. data/lib/servactory/context/workspace.rb +5 -0
  8. data/lib/servactory/inputs/input.rb +20 -2
  9. data/lib/servactory/inputs/tools/validation.rb +5 -3
  10. data/lib/servactory/inputs/validations/required.rb +10 -9
  11. data/lib/servactory/inputs/workspace.rb +1 -2
  12. data/lib/servactory/internals/internal.rb +22 -1
  13. data/lib/servactory/maintenance/attributes/options/registrar.rb +11 -11
  14. data/lib/servactory/maintenance/attributes/tools/check_errors.rb +22 -0
  15. data/lib/servactory/maintenance/attributes/tools/validation.rb +81 -0
  16. data/lib/servactory/maintenance/attributes/validations/base.rb +23 -0
  17. data/lib/servactory/maintenance/attributes/validations/errors.rb +18 -0
  18. data/lib/servactory/maintenance/attributes/validations/inclusion.rb +75 -0
  19. data/lib/servactory/maintenance/attributes/validations/must.rb +102 -0
  20. data/lib/servactory/maintenance/attributes/validations/type.rb +62 -0
  21. data/lib/servactory/maintenance/validations/types.rb +10 -18
  22. data/lib/servactory/outputs/output.rb +22 -1
  23. data/lib/servactory/version.rb +2 -2
  24. metadata +10 -12
  25. data/lib/servactory/inputs/tools/check_errors.rb +0 -20
  26. data/lib/servactory/inputs/tools/distributor.rb +0 -24
  27. data/lib/servactory/inputs/validations/inclusion.rb +0 -66
  28. data/lib/servactory/inputs/validations/must.rb +0 -99
  29. data/lib/servactory/inputs/validations/type.rb +0 -52
  30. data/lib/servactory/internals/validations/base.rb +0 -17
  31. data/lib/servactory/internals/validations/type.rb +0 -31
  32. data/lib/servactory/outputs/validations/base.rb +0 -17
  33. data/lib/servactory/outputs/validations/type.rb +0 -31
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Maintenance
5
+ module Attributes
6
+ module Validations
7
+ class Must < Base
8
+ DEFAULT_MESSAGE = lambda do |service_class_name:, input:, value:, code:|
9
+ I18n.t(
10
+ "servactory.#{input.i18n_name}.validations.must.default_error",
11
+ service_class_name: service_class_name,
12
+ "#{input.system_name}_name": input.name,
13
+ value: value,
14
+ code: code
15
+ )
16
+ end
17
+
18
+ SYNTAX_ERROR_MESSAGE = lambda do |service_class_name:, input:, value:, code:, exception_message:|
19
+ I18n.t(
20
+ "servactory.#{input.i18n_name}.validations.must.syntax_error",
21
+ service_class_name: service_class_name,
22
+ "#{input.system_name}_name": input.name,
23
+ value: value,
24
+ code: code,
25
+ exception_message: exception_message
26
+ )
27
+ end
28
+
29
+ private_constant :DEFAULT_MESSAGE, :SYNTAX_ERROR_MESSAGE
30
+
31
+ def self.check(context:, attribute:, value:, check_key:, check_options:)
32
+ return unless should_be_checked_for?(attribute, check_key)
33
+
34
+ new(context: context, attribute: attribute, value: value, check_options: check_options).check
35
+ end
36
+
37
+ def self.should_be_checked_for?(attribute, check_key)
38
+ check_key == :must && attribute.must_present?
39
+ end
40
+
41
+ ##########################################################################
42
+
43
+ def initialize(context:, attribute:, value:, check_options:)
44
+ super()
45
+
46
+ @context = context
47
+ @attribute = attribute
48
+ @value = value
49
+ @check_options = check_options
50
+ end
51
+
52
+ def check
53
+ @check_options.each do |code, options|
54
+ message = call_or_fetch_message_from(code, options)
55
+
56
+ next if message.blank?
57
+
58
+ add_error_with(message, code)
59
+ end
60
+
61
+ errors
62
+ end
63
+
64
+ private
65
+
66
+ def call_or_fetch_message_from(code, options)
67
+ check, message = options.values_at(:is, :message)
68
+
69
+ return if check.call(value: @value)
70
+
71
+ message.presence || DEFAULT_MESSAGE
72
+ rescue StandardError => e
73
+ add_syntax_error_with(SYNTAX_ERROR_MESSAGE, code, e.message)
74
+ end
75
+
76
+ ########################################################################
77
+
78
+ def add_error_with(message, code)
79
+ add_error(
80
+ message: message,
81
+ service_class_name: @context.class.name,
82
+ "#{@attribute.system_name}": @attribute,
83
+ value: @value,
84
+ code: code
85
+ )
86
+ end
87
+
88
+ def add_syntax_error_with(message, code, exception_message)
89
+ add_error(
90
+ message: message,
91
+ service_class_name: @context.class.name,
92
+ "#{@attribute.system_name}": @attribute,
93
+ value: @value,
94
+ code: code,
95
+ exception_message: exception_message
96
+ )
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Maintenance
5
+ module Attributes
6
+ module Validations
7
+ class Type < Base
8
+ def self.check(context:, attribute:, value:, check_key:, **)
9
+ return unless should_be_checked_for?(attribute, value, check_key)
10
+
11
+ new(context: context, attribute: attribute, value: value).check
12
+ end
13
+
14
+ # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
15
+ def self.should_be_checked_for?(attribute, value, check_key)
16
+ check_key == :types && (
17
+ (
18
+ attribute.input? && (
19
+ attribute.required? || (
20
+ attribute.optional? && !attribute.default.nil?
21
+ ) || (
22
+ attribute.optional? && !value.nil?
23
+ )
24
+ )
25
+ ) || attribute.internal? || attribute.output?
26
+ )
27
+ end
28
+ # rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
29
+
30
+ def initialize(context:, attribute:, value:)
31
+ super()
32
+
33
+ @context = context
34
+ @attribute = attribute
35
+ @value = value
36
+ end
37
+
38
+ def check
39
+ Servactory::Maintenance::Validations::Types.validate!(
40
+ context: @context,
41
+ attribute: @attribute,
42
+ types: @attribute.types,
43
+ value: prepared_value,
44
+ error_callback: ->(**args) { add_error(**args) }
45
+ )
46
+ end
47
+
48
+ private
49
+
50
+ def prepared_value
51
+ @prepared_value ||=
52
+ if @attribute.input? && @attribute.optional? && !@attribute.default.nil? && @value.blank?
53
+ @attribute.default
54
+ else
55
+ @value
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -6,7 +6,6 @@ module Servactory
6
6
  class Types # rubocop:disable Metrics/ClassLength
7
7
  DEFAULT_MESSAGE = lambda do | # rubocop:disable Metrics/BlockLength
8
8
  service_class_name:,
9
- attribute_system_name:,
10
9
  attribute:,
11
10
  value:,
12
11
  key_name:,
@@ -18,7 +17,7 @@ module Servactory
18
17
 
19
18
  if collection_message.is_a?(Proc)
20
19
  collection_message.call(
21
- "#{attribute_system_name}_name": attribute.name,
20
+ "#{attribute.system_name}_name": attribute.name,
22
21
  expected_type: expected_type,
23
22
  given_type: given_type
24
23
  )
@@ -26,17 +25,17 @@ module Servactory
26
25
  collection_message
27
26
  elsif value.is_a?(attribute.types.fetch(0, Array))
28
27
  I18n.t(
29
- "servactory.#{attribute_system_name.to_s.pluralize}.checks.type.default_error.for_collection.wrong_element_type", # rubocop:disable Layout/LineLength
28
+ "servactory.#{attribute.i18n_name}.validations.type.default_error.for_collection.wrong_element_type",
30
29
  service_class_name: service_class_name,
31
- "#{attribute_system_name}_name": attribute.name,
30
+ "#{attribute.system_name}_name": attribute.name,
32
31
  expected_type: expected_type,
33
32
  given_type: given_type
34
33
  )
35
34
  else
36
35
  I18n.t(
37
- "servactory.#{attribute_system_name.to_s.pluralize}.checks.type.default_error.for_collection.wrong_type", # rubocop:disable Layout/LineLength
36
+ "servactory.#{attribute.i18n_name}.validations.type.default_error.for_collection.wrong_type",
38
37
  service_class_name: service_class_name,
39
- "#{attribute_system_name}_name": attribute.name,
38
+ "#{attribute.system_name}_name": attribute.name,
40
39
  expected_type: attribute.types.fetch(0, Array),
41
40
  given_type: value.class.name
42
41
  )
@@ -46,7 +45,7 @@ module Servactory
46
45
 
47
46
  if hash_message.is_a?(Proc)
48
47
  hash_message.call(
49
- "#{attribute_system_name}_name": attribute.name,
48
+ "#{attribute.system_name}_name": attribute.name,
50
49
  key_name: key_name,
51
50
  expected_type: expected_type,
52
51
  given_type: given_type
@@ -55,9 +54,9 @@ module Servactory
55
54
  hash_message
56
55
  else
57
56
  I18n.t(
58
- "servactory.#{attribute_system_name.to_s.pluralize}.checks.type.default_error.for_hash.wrong_element_type", # rubocop:disable Layout/LineLength
57
+ "servactory.#{attribute.i18n_name}.validations.type.default_error.for_hash.wrong_element_type",
59
58
  service_class_name: service_class_name,
60
- "#{attribute_system_name}_name": attribute.name,
59
+ "#{attribute.system_name}_name": attribute.name,
61
60
  key_name: key_name,
62
61
  expected_type: expected_type,
63
62
  given_type: given_type
@@ -65,9 +64,9 @@ module Servactory
65
64
  end
66
65
  else
67
66
  I18n.t(
68
- "servactory.#{attribute_system_name.to_s.pluralize}.checks.type.default_error.default",
67
+ "servactory.#{attribute.i18n_name}.validations.type.default_error.default",
69
68
  service_class_name: service_class_name,
70
- "#{attribute_system_name}_name": attribute.name,
69
+ "#{attribute.system_name}_name": attribute.name,
71
70
  expected_type: expected_type,
72
71
  given_type: given_type
73
72
  )
@@ -117,7 +116,6 @@ module Servactory
117
116
  return @error_callback.call(
118
117
  message: DEFAULT_MESSAGE,
119
118
  service_class_name: @context.class.name,
120
- attribute_system_name: attribute_system_name,
121
119
  attribute: @attribute,
122
120
  value: @value,
123
121
  key_name: nil,
@@ -130,7 +128,6 @@ module Servactory
130
128
  return @error_callback.call(
131
129
  message: DEFAULT_MESSAGE,
132
130
  service_class_name: @context.class.name,
133
- attribute_system_name: attribute_system_name,
134
131
  attribute: @attribute,
135
132
  value: @value,
136
133
  key_name: first_error.fetch(:key_name),
@@ -142,7 +139,6 @@ module Servactory
142
139
  @error_callback.call(
143
140
  message: DEFAULT_MESSAGE,
144
141
  service_class_name: @context.class.name,
145
- attribute_system_name: attribute_system_name,
146
142
  attribute: @attribute,
147
143
  value: @value,
148
144
  key_name: nil,
@@ -153,10 +149,6 @@ module Servactory
153
149
 
154
150
  private
155
151
 
156
- def attribute_system_name
157
- @attribute.class.name.demodulize.downcase.to_sym
158
- end
159
-
160
152
  def prepared_types
161
153
  @prepared_types ||=
162
154
  if @attribute.collection_mode?
@@ -3,7 +3,8 @@
3
3
  module Servactory
4
4
  module Outputs
5
5
  class Output
6
- attr_reader :name
6
+ attr_reader :name,
7
+ :collection_of_options
7
8
 
8
9
  def initialize(
9
10
  name,
@@ -49,6 +50,26 @@ module Servactory
49
50
  def options_for_checks
50
51
  @collection_of_options.options_for_checks
51
52
  end
53
+
54
+ def system_name
55
+ self.class.name.demodulize.downcase.to_sym
56
+ end
57
+
58
+ def i18n_name
59
+ system_name.to_s.pluralize
60
+ end
61
+
62
+ def input?
63
+ false
64
+ end
65
+
66
+ def internal?
67
+ false
68
+ end
69
+
70
+ def output?
71
+ true
72
+ end
52
73
  end
53
74
  end
54
75
  end
@@ -3,8 +3,8 @@
3
3
  module Servactory
4
4
  module VERSION
5
5
  MAJOR = 2
6
- MINOR = 0
7
- PATCH = 3
6
+ MINOR = 1
7
+ PATCH = 0
8
8
  PRE = nil
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH, PRE].compact.join(".")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: servactory
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anton Sokolov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-16 00:00:00.000000000 Z
11
+ date: 2023-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -255,23 +255,16 @@ files:
255
255
  - lib/servactory/inputs/collection.rb
256
256
  - lib/servactory/inputs/dsl.rb
257
257
  - lib/servactory/inputs/input.rb
258
- - lib/servactory/inputs/tools/check_errors.rb
259
- - lib/servactory/inputs/tools/distributor.rb
260
258
  - lib/servactory/inputs/tools/rules.rb
261
259
  - lib/servactory/inputs/tools/unnecessary.rb
262
260
  - lib/servactory/inputs/tools/validation.rb
263
261
  - lib/servactory/inputs/validations/base.rb
264
262
  - lib/servactory/inputs/validations/errors.rb
265
- - lib/servactory/inputs/validations/inclusion.rb
266
- - lib/servactory/inputs/validations/must.rb
267
263
  - lib/servactory/inputs/validations/required.rb
268
- - lib/servactory/inputs/validations/type.rb
269
264
  - lib/servactory/inputs/workspace.rb
270
265
  - lib/servactory/internals/collection.rb
271
266
  - lib/servactory/internals/dsl.rb
272
267
  - lib/servactory/internals/internal.rb
273
- - lib/servactory/internals/validations/base.rb
274
- - lib/servactory/internals/validations/type.rb
275
268
  - lib/servactory/maintenance/attributes/define_conflict.rb
276
269
  - lib/servactory/maintenance/attributes/define_method.rb
277
270
  - lib/servactory/maintenance/attributes/option.rb
@@ -279,6 +272,13 @@ files:
279
272
  - lib/servactory/maintenance/attributes/option_helpers_collection.rb
280
273
  - lib/servactory/maintenance/attributes/options/registrar.rb
281
274
  - lib/servactory/maintenance/attributes/options_collection.rb
275
+ - lib/servactory/maintenance/attributes/tools/check_errors.rb
276
+ - lib/servactory/maintenance/attributes/tools/validation.rb
277
+ - lib/servactory/maintenance/attributes/validations/base.rb
278
+ - lib/servactory/maintenance/attributes/validations/errors.rb
279
+ - lib/servactory/maintenance/attributes/validations/inclusion.rb
280
+ - lib/servactory/maintenance/attributes/validations/must.rb
281
+ - lib/servactory/maintenance/attributes/validations/type.rb
282
282
  - lib/servactory/maintenance/collection_mode/class_names_collection.rb
283
283
  - lib/servactory/maintenance/hash_mode/class_names_collection.rb
284
284
  - lib/servactory/maintenance/validations/collection.rb
@@ -287,8 +287,6 @@ files:
287
287
  - lib/servactory/outputs/collection.rb
288
288
  - lib/servactory/outputs/dsl.rb
289
289
  - lib/servactory/outputs/output.rb
290
- - lib/servactory/outputs/validations/base.rb
291
- - lib/servactory/outputs/validations/type.rb
292
290
  - lib/servactory/result.rb
293
291
  - lib/servactory/test_kit/fake_type.rb
294
292
  - lib/servactory/test_kit/result.rb
@@ -319,7 +317,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
319
317
  - !ruby/object:Gem::Version
320
318
  version: '0'
321
319
  requirements: []
322
- rubygems_version: 3.4.17
320
+ rubygems_version: 3.5.1
323
321
  signing_key:
324
322
  specification_version: 4
325
323
  summary: A set of tools for building reliable services of any complexity
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Servactory
4
- module Inputs
5
- module Tools
6
- class CheckErrors
7
- extend Forwardable
8
- def_delegators :@collection, :merge, :reject, :first, :empty?
9
-
10
- def initialize(collection = Set.new)
11
- @collection = collection
12
- end
13
-
14
- def not_blank
15
- CheckErrors.new(reject(&:blank?))
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Servactory
4
- module Inputs
5
- module Tools
6
- class Distributor
7
- def self.assign!(...)
8
- new(...).assign!
9
- end
10
-
11
- def initialize(incoming_arguments, collection_of_inputs)
12
- @incoming_arguments = incoming_arguments
13
- @collection_of_inputs = collection_of_inputs
14
- end
15
-
16
- def assign!
17
- @collection_of_inputs.map do |input|
18
- input.value = @incoming_arguments.fetch(input.name, nil)
19
- end
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Servactory
4
- module Inputs
5
- module Validations
6
- class Inclusion < Base
7
- DEFAULT_MESSAGE = lambda do |service_class_name:, input:, value:|
8
- I18n.t(
9
- "servactory.inputs.checks.inclusion.default_error",
10
- service_class_name: service_class_name,
11
- input_name: input.name,
12
- input_inclusion: input.inclusion[:in],
13
- value: value
14
- )
15
- end
16
-
17
- private_constant :DEFAULT_MESSAGE
18
-
19
- def self.check(context:, input:, check_key:, **)
20
- return unless should_be_checked_for?(input, check_key)
21
-
22
- new(context: context, input: input).check
23
- end
24
-
25
- def self.should_be_checked_for?(input, check_key)
26
- check_key == :inclusion && (
27
- input.required? || (
28
- input.optional? && !input.default.nil?
29
- ) || (
30
- input.optional? && !input.value.nil?
31
- )
32
- )
33
- end
34
-
35
- ##########################################################################
36
-
37
- def initialize(context:, input:)
38
- super()
39
-
40
- @context = context
41
- @input = input
42
- end
43
-
44
- def check
45
- inclusion_in, message = @input.inclusion.values_at(:in, :message)
46
-
47
- return if inclusion_in.nil?
48
- return if inclusion_in.include?(@input.value)
49
-
50
- add_error_with(message)
51
- end
52
-
53
- private
54
-
55
- def add_error_with(message)
56
- add_error(
57
- message: message.presence || DEFAULT_MESSAGE,
58
- service_class_name: @context.class.name,
59
- input: @input,
60
- value: @input.value
61
- )
62
- end
63
- end
64
- end
65
- end
66
- end
@@ -1,99 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Servactory
4
- module Inputs
5
- module Validations
6
- class Must < Base
7
- DEFAULT_MESSAGE = lambda do |service_class_name:, input:, value:, code:|
8
- I18n.t(
9
- "servactory.inputs.checks.must.default_error",
10
- service_class_name: service_class_name,
11
- input_name: input.name,
12
- value: value,
13
- code: code
14
- )
15
- end
16
-
17
- SYNTAX_ERROR_MESSAGE = lambda do |service_class_name:, input:, value:, code:, exception_message:|
18
- I18n.t(
19
- "servactory.inputs.checks.must.syntax_error",
20
- service_class_name: service_class_name,
21
- input_name: input.name,
22
- value: value,
23
- code: code,
24
- exception_message: exception_message
25
- )
26
- end
27
-
28
- private_constant :DEFAULT_MESSAGE, :SYNTAX_ERROR_MESSAGE
29
-
30
- def self.check(context:, input:, check_key:, check_options:)
31
- return unless should_be_checked_for?(input, check_key)
32
-
33
- new(context: context, input: input, check_options: check_options).check
34
- end
35
-
36
- def self.should_be_checked_for?(input, check_key)
37
- check_key == :must && input.must_present?
38
- end
39
-
40
- ##########################################################################
41
-
42
- def initialize(context:, input:, check_options:)
43
- super()
44
-
45
- @context = context
46
- @input = input
47
- @check_options = check_options
48
- end
49
-
50
- def check
51
- @check_options.each do |code, options|
52
- message = call_or_fetch_message_from(code, options)
53
-
54
- next if message.blank?
55
-
56
- add_error_with(message, code)
57
- end
58
-
59
- errors
60
- end
61
-
62
- private
63
-
64
- def call_or_fetch_message_from(code, options)
65
- check, message = options.values_at(:is, :message)
66
-
67
- return if check.call(value: @input.value)
68
-
69
- message.presence || DEFAULT_MESSAGE
70
- rescue StandardError => e
71
- add_syntax_error_with(SYNTAX_ERROR_MESSAGE, code, e.message)
72
- end
73
-
74
- ########################################################################
75
-
76
- def add_error_with(message, code)
77
- add_error(
78
- message: message,
79
- service_class_name: @context.class.name,
80
- input: @input,
81
- value: @input.value,
82
- code: code
83
- )
84
- end
85
-
86
- def add_syntax_error_with(message, code, exception_message)
87
- add_error(
88
- message: message,
89
- service_class_name: @context.class.name,
90
- input: @input,
91
- value: @input.value,
92
- code: code,
93
- exception_message: exception_message
94
- )
95
- end
96
- end
97
- end
98
- end
99
- end
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Servactory
4
- module Inputs
5
- module Validations
6
- class Type < Base
7
- def self.check(context:, input:, check_key:, **)
8
- return unless should_be_checked_for?(input, check_key)
9
-
10
- new(context: context, input: input).check
11
- end
12
-
13
- def self.should_be_checked_for?(input, check_key)
14
- check_key == :types && (
15
- input.required? || (
16
- input.optional? && !input.default.nil?
17
- ) || (
18
- input.optional? && !input.value.nil?
19
- )
20
- )
21
- end
22
-
23
- def initialize(context:, input:)
24
- super()
25
-
26
- @context = context
27
- @input = input
28
- end
29
-
30
- def check
31
- Servactory::Maintenance::Validations::Types.validate!(
32
- context: @context,
33
- attribute: @input,
34
- types: @input.types,
35
- value: prepared_value,
36
- error_callback: ->(**args) { add_error(**args) }
37
- )
38
- end
39
-
40
- private
41
-
42
- def prepared_value
43
- @prepared_value ||= if @input.optional? && !@input.default.nil? && @input.value.blank?
44
- @input.default
45
- else
46
- @input.value
47
- end
48
- end
49
- end
50
- end
51
- end
52
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Servactory
4
- module Internals
5
- module Validations
6
- class Base
7
- protected
8
-
9
- def raise_error_with(message:, **attributes)
10
- message = message.call(**attributes) if message.is_a?(Proc)
11
-
12
- raise @context.class.config.internal_error_class.new(message: message)
13
- end
14
- end
15
- end
16
- end
17
- end