servactory 2.1.0 → 2.2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -5
  3. data/config/locales/en.yml +19 -5
  4. data/config/locales/ru.yml +19 -5
  5. data/lib/servactory/actions/tools/runner.rb +40 -1
  6. data/lib/servactory/configuration/dsl.rb +1 -0
  7. data/lib/servactory/configuration/setup.rb +10 -0
  8. data/lib/servactory/context/callable.rb +3 -1
  9. data/lib/servactory/context/workspace.rb +22 -3
  10. data/lib/servactory/errors/failure.rb +5 -3
  11. data/lib/servactory/errors/input_error.rb +1 -1
  12. data/lib/servactory/errors/internal_error.rb +5 -3
  13. data/lib/servactory/errors/output_error.rb +5 -3
  14. data/lib/servactory/{errors → exceptions}/base.rb +1 -1
  15. data/lib/servactory/exceptions/success.rb +15 -0
  16. data/lib/servactory/inputs/translator/required.rb +24 -0
  17. data/lib/servactory/inputs/validations/required.rb +10 -15
  18. data/lib/servactory/internals/dsl.rb +3 -1
  19. data/lib/servactory/internals/internal.rb +24 -3
  20. data/lib/servactory/maintenance/attributes/option_helpers_collection.rb +1 -1
  21. data/lib/servactory/maintenance/attributes/translator/inclusion.rb +27 -0
  22. data/lib/servactory/maintenance/attributes/translator/must.rb +42 -0
  23. data/lib/servactory/maintenance/attributes/translator/type.rb +94 -0
  24. data/lib/servactory/maintenance/attributes/validations/inclusion.rb +1 -13
  25. data/lib/servactory/maintenance/attributes/validations/must.rb +6 -25
  26. data/lib/servactory/maintenance/validations/collection.rb +18 -14
  27. data/lib/servactory/maintenance/validations/object_schema.rb +3 -3
  28. data/lib/servactory/maintenance/validations/types.rb +6 -77
  29. data/lib/servactory/outputs/dsl.rb +3 -1
  30. data/lib/servactory/outputs/output.rb +24 -3
  31. data/lib/servactory/result.rb +70 -8
  32. data/lib/servactory/utils.rb +8 -0
  33. data/lib/servactory/version.rb +2 -2
  34. metadata +11 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1fd508e1e2a77b4d74acb00666dbc5149009fdb11f927144554f3d4d66a63887
4
- data.tar.gz: ac3cd518c70d56f1089e2975afffedca41983555e4c54fc5d815d94ea0d1fa4c
3
+ metadata.gz: 5c12708849de24be4c1dc728185784afde60fa4cddad681d52d591561b4acacd
4
+ data.tar.gz: d1d5d7334b5e6b1ecc7f92b526faa60f67521fc73a3f33ab4d30f8b2e2b94f5c
5
5
  SHA512:
6
- metadata.gz: bcf0363a0d2d83cfd6ddffd4ea19254a51c2cf93eb33b83f79ee6129f7e38a8fe1bbedfc19cde97d3cfc78ee3d48d8550afa39c7d1d78488a10bfb8d7be609e8
7
- data.tar.gz: 5ad30d0c89119bd1a9ccfc6b536c14276cd6197f28ef2d449f0f38a3ce3c962bba6bea7a60c4b365ff76adaa1bd284a8ddc0908b6319dc3bd895458f5d7d8ddd
6
+ metadata.gz: ccf9a3ae3d9a1d9336ff447018c5aa17dc62348a19b37184d18296ca2eb03174fe90c37ff30d85d70ac31236f4efc8903e594afcd87f5b0ddbd10b188b8c75d7
7
+ data.tar.gz: 0fac6ae21c307e87ce9b022c6e0c140162d8c8536325586df72022eb72e8545516c4a988224b554b9bc0af4a89895b796848614572ad42429f323c84c45b19a2
data/README.md CHANGED
@@ -13,15 +13,15 @@
13
13
  </p>
14
14
 
15
15
  <p align="center">
16
- <a href="https://rubygems.org/gems/servactory"><img src="https://img.shields.io/gem/v/servactory?logo=rubygems&logoColor=fff" alt="Gem version"></a>
17
- <a href="https://github.com/afuno/servactory/releases"><img src="https://img.shields.io/github/release-date/afuno/servactory" alt="Release Date"></a>
16
+ <a href="https://rubygems.org/gems/servactory"><img src="https://img.shields.io/gem/v/servactory?logo=rubygems&logoColor=fff" alt="Gem version"></a>
17
+ <a href="https://github.com/afuno/servactory/releases"><img src="https://img.shields.io/github/release-date/afuno/servactory" alt="Release Date"></a>
18
18
  </p>
19
19
 
20
20
  ## Documentation
21
21
 
22
22
  See [servactory.com](https://servactory.com) for documentation.
23
23
 
24
- ## Example
24
+ ## Quick Start
25
25
 
26
26
  ### Installation
27
27
 
@@ -29,7 +29,7 @@ See [servactory.com](https://servactory.com) for documentation.
29
29
  gem "servactory"
30
30
  ```
31
31
 
32
- ### Service
32
+ ### Define service
33
33
 
34
34
  ```ruby
35
35
  class UserService::Authenticate < Servactory::Base
@@ -50,7 +50,7 @@ class UserService::Authenticate < Servactory::Base
50
50
  end
51
51
  ```
52
52
 
53
- ### Usage
53
+ ### Usage in controller
54
54
 
55
55
  ```ruby
56
56
  class SessionsController < ApplicationController
@@ -1,5 +1,12 @@
1
1
  en:
2
2
  servactory:
3
+ common:
4
+ undefined_local_variable_or_method: "[%{service_class_name}] Undefined local variable or method `%{method_name}`"
5
+ undefined_method:
6
+ missing_name: "[%{service_class_name}] Undefined method `%{method_name}` for `%{missing_name}`"
7
+ methods:
8
+ call:
9
+ not_used: "[%{service_class_name}] Nothing to perform. Use `make` or create a `call` method."
3
10
  inputs:
4
11
  undefined:
5
12
  getter: "[%{service_class_name}] Undefined input attribute `%{input_name}`"
@@ -31,12 +38,17 @@ en:
31
38
  getter: "[%{service_class_name}] Undefined internal attribute `%{internal_name}`"
32
39
  setter: "[%{service_class_name}] Undefined internal attribute `%{internal_name}`"
33
40
  validations:
41
+ inclusion:
42
+ default_error: "[%{service_class_name}] Wrong value in `%{internal_name}`, must be one of `%{internal_inclusion}`"
43
+ must:
44
+ default_error: "[%{service_class_name}] Internal attribute `%{internal_name}` must \"%{code}\""
45
+ syntax_error: "[%{service_class_name}] Syntax error inside `%{code}` of `%{internal_name}` internal attribute"
34
46
  type:
35
47
  default_error:
36
48
  default: "[%{service_class_name}] Wrong type of internal attribute `%{internal_name}`, expected `%{expected_type}`, got `%{given_type}`"
37
49
  for_collection:
38
50
  wrong_type: "[%{service_class_name}] Wrong internal attribute collection type `%{internal_name}`, expected `%{expected_type}`, got `%{given_type}`"
39
- wrong_element_type: "[%{service_class_name}] Wrong element type in internal attribute collection `%{internal_name}`, expected `%{expected_type}`"
51
+ wrong_element_type: "[%{service_class_name}] Wrong element type in internal attribute collection `%{internal_name}`, expected `%{expected_type}`, got `%{given_type}`"
40
52
  for_hash:
41
53
  wrong_element_type: "[%{service_class_name}] Wrong type in internal attribute hash `%{internal_name}`, expected `%{expected_type}` for `%{key_name}`, got `%{given_type}`"
42
54
  outputs:
@@ -44,14 +56,16 @@ en:
44
56
  getter: "[%{service_class_name}] Undefined output attribute `%{output_name}`"
45
57
  setter: "[%{service_class_name}] Undefined output attribute `%{output_name}`"
46
58
  validations:
59
+ inclusion:
60
+ default_error: "[%{service_class_name}] Wrong value in `%{output_name}`, must be one of `%{output_inclusion}`"
61
+ must:
62
+ default_error: "[%{service_class_name}] Output attribute `%{output_name}` must \"%{code}\""
63
+ syntax_error: "[%{service_class_name}] Syntax error inside `%{code}` of `%{output_name}` output attribute"
47
64
  type:
48
65
  default_error:
49
66
  default: "[%{service_class_name}] Wrong type of output attribute `%{output_name}`, expected `%{expected_type}`, got `%{given_type}`"
50
67
  for_collection:
51
68
  wrong_type: "[%{service_class_name}] Wrong output attribute collection type `%{output_name}`, expected `%{expected_type}`, got `%{given_type}`"
52
- wrong_element_type: "[%{service_class_name}] Wrong element type in output attribute collection `%{output_name}`, expected `%{expected_type}`"
69
+ wrong_element_type: "[%{service_class_name}] Wrong element type in output attribute collection `%{output_name}`, expected `%{expected_type}`, got `%{given_type}`"
53
70
  for_hash:
54
71
  wrong_element_type: "[%{service_class_name}] Wrong type in output attribute hash `%{output_name}`, expected `%{expected_type}` for `%{key_name}`, got `%{given_type}`"
55
- methods:
56
- call:
57
- not_used: Nothing to perform. Use `make` or create a `call` method.
@@ -1,5 +1,12 @@
1
1
  ru:
2
2
  servactory:
3
+ common:
4
+ undefined_local_variable_or_method: "[%{service_class_name}] Неопределенная локальная переменная или метод `%{method_name}`"
5
+ undefined_method:
6
+ missing_name: "[%{service_class_name}] Неопределенный метод `%{method_name}` для `%{missing_name}`"
7
+ methods:
8
+ call:
9
+ not_used: "[%{service_class_name}] Нечего выполнять. Используйте `make` или создайте метод `call`."
3
10
  inputs:
4
11
  undefined:
5
12
  getter: "[%{service_class_name}] Неизвестный входящий атрибут `%{input_name}`"
@@ -32,12 +39,17 @@ ru:
32
39
  getter: "[%{service_class_name}] Неизвестный внутренний атрибут `%{internal_name}`"
33
40
  setter: "[%{service_class_name}] Неизвестный внутренний атрибут `%{internal_name}`"
34
41
  validations:
42
+ inclusion:
43
+ default_error: "[%{service_class_name}] Неправильное значение в `%{internal_name}`, должно быть одним из `%{internal_inclusion}`"
44
+ must:
45
+ default_error: "[%{service_class_name}] Внутренний атрибут `%{internal_name}` должен \"%{code}\""
46
+ syntax_error: "[%{service_class_name}] Синтаксическая ошибка внутри `%{code}` внутреннего атрибута `%{internal_name}`"
35
47
  type:
36
48
  default_error:
37
49
  default: "[%{service_class_name}] Неправильный тип внутреннего атрибута `%{internal_name}`, ожидалось `%{expected_type}`, получено `%{given_type}`"
38
50
  for_collection:
39
51
  wrong_type: "[%{service_class_name}] Неправильный тип коллекции внутреннего атрибута `%{internal_name}`, ожидалось `%{expected_type}`, получено `%{given_type}`"
40
- wrong_element_type: "[%{service_class_name}] Неправильный тип элемента в коллекции внутреннего атрибута `%{internal_name}`, ожидалось `%{expected_type}`"
52
+ wrong_element_type: "[%{service_class_name}] Неправильный тип элемента в коллекции внутреннего атрибута `%{internal_name}`, ожидалось `%{expected_type}`, получено `%{given_type}`"
41
53
  for_hash:
42
54
  wrong_element_type: "[%{service_class_name}] Неправильный тип в хеше внутреннего атрибута `%{internal_name}`, для `%{key_name}` ожидалось `%{expected_type}`, получено `%{given_type}`"
43
55
  outputs:
@@ -45,13 +57,15 @@ ru:
45
57
  getter: "[%{service_class_name}] Неизвестный выходящий атрибут `%{output_name}`"
46
58
  setter: "[%{service_class_name}] Неизвестный выходящий атрибут `%{output_name}`"
47
59
  validations:
60
+ inclusion:
61
+ default_error: "[%{service_class_name}] Неправильное значение в `%{output_name}`, должно быть одним из `%{output_inclusion}`"
62
+ must:
63
+ default_error: "[%{service_class_name}] Выходящий атрибут `%{output_name}` должен \"%{code}\""
64
+ syntax_error: "[%{service_class_name}] Синтаксическая ошибка внутри `%{code}` выходящего атрибута `%{output_name}`"
48
65
  type:
49
66
  default: "[%{service_class_name}] Неправильный тип выходящего атрибута `%{output_name}`, ожидалось `%{expected_type}`, получено `%{given_type}`"
50
67
  for_collection:
51
68
  wrong_type: "[%{service_class_name}] Неправильный тип коллекции выходящего атрибута `%{output_name}`, ожидалось `%{expected_type}`, получено `%{given_type}`"
52
- wrong_element_type: "[%{service_class_name}] Неправильный тип элемента в коллекции выходящего атрибута `%{output_name}`, ожидалось `%{expected_type}`"
69
+ wrong_element_type: "[%{service_class_name}] Неправильный тип элемента в коллекции выходящего атрибута `%{output_name}`, ожидалось `%{expected_type}`, получено `%{given_type}`"
53
70
  for_hash:
54
71
  wrong_element_type: "[%{service_class_name}] Неправильный тип в хеше выходящего атрибута `%{output_name}`, для `%{key_name}` ожидалось `%{expected_type}`, получено `%{given_type}`"
55
- methods:
56
- call:
57
- not_used: Нечего исполнять. Используйте `make` или создайте метод `call`.
@@ -51,10 +51,18 @@ module Servactory
51
51
  methods.each do |method|
52
52
  next if unnecessary_for_make?(method)
53
53
 
54
- @context.send(method.name)
54
+ call_method(method)
55
55
  end
56
56
  end
57
57
 
58
+ def call_method(method)
59
+ @context.send(method.name)
60
+ rescue NoMethodError => e
61
+ rescue_no_method_error_with(exception: e)
62
+ rescue NameError
63
+ rescue_name_error_with(method: method)
64
+ end
65
+
58
66
  def unnecessary_for_stage?(stage)
59
67
  condition = stage.condition
60
68
  is_condition_opposite = stage.is_condition_opposite
@@ -79,6 +87,37 @@ module Servactory
79
87
 
80
88
  !condition.call(context: @context)
81
89
  end
90
+
91
+ ########################################################################
92
+
93
+ def rescue_no_method_error_with(exception:) # rubocop:disable Metrics/MethodLength
94
+ raise @context.class.config.failure_class.new(
95
+ type: :base,
96
+ message: I18n.t(
97
+ "servactory.common.undefined_method.missing_name",
98
+ service_class_name: @context.class.name,
99
+ method_name: exception.name,
100
+ missing_name: if exception.missing_name.nil?
101
+ exception.missing_name.inspect
102
+ elsif exception.missing_name == "NilClass"
103
+ nil.inspect
104
+ else
105
+ exception.missing_name
106
+ end
107
+ )
108
+ )
109
+ end
110
+
111
+ def rescue_name_error_with(method:)
112
+ raise @context.class.config.failure_class.new(
113
+ type: :base,
114
+ message: I18n.t(
115
+ "servactory.common.undefined_local_variable_or_method",
116
+ service_class_name: @context.class.name,
117
+ method_name: method.name
118
+ )
119
+ )
120
+ end
82
121
  end
83
122
  end
84
123
  end
@@ -15,6 +15,7 @@ module Servactory
15
15
  child.config.internal_error_class = config.internal_error_class
16
16
  child.config.output_error_class = config.output_error_class
17
17
 
18
+ child.config.success_class = config.success_class
18
19
  child.config.failure_class = config.failure_class
19
20
 
20
21
  child.config.collection_mode_class_names = config.collection_mode_class_names
@@ -6,10 +6,13 @@ module Servactory
6
6
  attr_accessor :input_error_class,
7
7
  :internal_error_class,
8
8
  :output_error_class,
9
+ :success_class,
9
10
  :failure_class,
10
11
  :collection_mode_class_names,
11
12
  :hash_mode_class_names,
12
13
  :input_option_helpers,
14
+ :internal_option_helpers,
15
+ :output_option_helpers,
13
16
  :action_aliases,
14
17
  :action_shortcuts
15
18
 
@@ -18,6 +21,7 @@ module Servactory
18
21
  @internal_error_class = Servactory::Errors::InternalError
19
22
  @output_error_class = Servactory::Errors::OutputError
20
23
 
24
+ @success_class = Servactory::Exceptions::Success
21
25
  @failure_class = Servactory::Errors::Failure
22
26
 
23
27
  @collection_mode_class_names =
@@ -29,6 +33,12 @@ module Servactory
29
33
  @input_option_helpers =
30
34
  Servactory::Maintenance::Attributes::OptionHelpersCollection.new(default_input_option_helpers)
31
35
 
36
+ @internal_option_helpers =
37
+ Servactory::Maintenance::Attributes::OptionHelpersCollection.new
38
+
39
+ @output_option_helpers =
40
+ Servactory::Maintenance::Attributes::OptionHelpersCollection.new
41
+
32
42
  @action_aliases = Servactory::Actions::Aliases::Collection.new
33
43
  @action_shortcuts = Servactory::Actions::Shortcuts::Collection.new
34
44
  end
@@ -3,7 +3,7 @@
3
3
  module Servactory
4
4
  module Context
5
5
  module Callable
6
- def call!(arguments = {})
6
+ def call!(arguments = {}) # rubocop:disable Metrics/MethodLength
7
7
  context = send(:new)
8
8
 
9
9
  context.send(
@@ -16,6 +16,8 @@ module Servactory
16
16
  )
17
17
 
18
18
  Servactory::Result.success_for(context: context)
19
+ rescue config.success_class => e
20
+ Servactory::Result.success_for(context: e.context)
19
21
  end
20
22
 
21
23
  def call(arguments = {})
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Servactory
4
4
  module Context
5
- module Workspace
5
+ module Workspace # rubocop:disable Metrics/ModuleLength
6
6
  def inputs
7
7
  @inputs ||= Inputs.new(
8
8
  context: self,
@@ -25,6 +25,10 @@ module Servactory
25
25
  )
26
26
  end
27
27
 
28
+ def success!
29
+ raise self.class.config.success_class.new(context: self)
30
+ end
31
+
28
32
  def fail_input!(input_name, message:)
29
33
  raise self.class.config.input_error_class.new(
30
34
  input_name: input_name,
@@ -32,8 +36,22 @@ module Servactory
32
36
  )
33
37
  end
34
38
 
35
- def fail!(message:, meta: nil)
36
- raise self.class.config.failure_class.new(message: message, meta: meta)
39
+ def fail_internal!(internal_name, message:)
40
+ raise self.class.config.internal_error_class.new(
41
+ internal_name: internal_name,
42
+ message: message
43
+ )
44
+ end
45
+
46
+ def fail_output!(output_name, message:)
47
+ raise self.class.config.output_error_class.new(
48
+ output_name: output_name,
49
+ message: message
50
+ )
51
+ end
52
+
53
+ def fail!(type = :base, message:, meta: nil)
54
+ raise self.class.config.failure_class.new(type: type, message: message, meta: meta)
37
55
  end
38
56
 
39
57
  def fail_result!(service_result)
@@ -78,6 +96,7 @@ module Servactory
78
96
 
79
97
  def call
80
98
  raise self.class.config.failure_class.new(
99
+ type: :base,
81
100
  message: I18n.t(
82
101
  "servactory.methods.call.not_used",
83
102
  service_class_name: self.class.name
@@ -2,11 +2,13 @@
2
2
 
3
3
  module Servactory
4
4
  module Errors
5
- class Failure < Base
6
- attr_reader :message,
5
+ class Failure < Servactory::Exceptions::Base
6
+ attr_reader :type,
7
+ :message,
7
8
  :meta
8
9
 
9
- def initialize(message:, meta: nil)
10
+ def initialize(type:, message:, meta: nil)
11
+ @type = type
10
12
  @message = message
11
13
  @meta = meta
12
14
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Servactory
4
4
  module Errors
5
- class InputError < Base
5
+ class InputError < Servactory::Exceptions::Base
6
6
  attr_reader :message,
7
7
  :input_name
8
8
 
@@ -2,11 +2,13 @@
2
2
 
3
3
  module Servactory
4
4
  module Errors
5
- class InternalError < Base
6
- attr_reader :message
5
+ class InternalError < Servactory::Exceptions::Base
6
+ attr_reader :message,
7
+ :internal_name
7
8
 
8
- def initialize(message:)
9
+ def initialize(message:, internal_name: nil)
9
10
  @message = message
11
+ @internal_name = internal_name&.to_sym
10
12
 
11
13
  super(message)
12
14
  end
@@ -2,11 +2,13 @@
2
2
 
3
3
  module Servactory
4
4
  module Errors
5
- class OutputError < Base
6
- attr_reader :message
5
+ class OutputError < Servactory::Exceptions::Base
6
+ attr_reader :message,
7
+ :output_name
7
8
 
8
- def initialize(message:)
9
+ def initialize(message:, output_name: nil)
9
10
  @message = message
11
+ @output_name = output_name&.to_sym
10
12
 
11
13
  super(message)
12
14
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Servactory
4
- module Errors
4
+ module Exceptions
5
5
  class Base < StandardError
6
6
  end
7
7
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Exceptions
5
+ class Success < Base
6
+ attr_reader :context
7
+
8
+ def initialize(context:)
9
+ @context = context
10
+
11
+ super
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Inputs
5
+ module Translator
6
+ module Required
7
+ module_function
8
+
9
+ def default_message
10
+ lambda do |service_class_name:, input:, value:|
11
+ i18n_key = "servactory.inputs.validations.required.default_error."
12
+ i18n_key += input.collection_mode? && value.present? ? "for_collection" : "default"
13
+
14
+ I18n.t(
15
+ i18n_key,
16
+ service_class_name: service_class_name,
17
+ input_name: input.name
18
+ )
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -4,19 +4,6 @@ module Servactory
4
4
  module Inputs
5
5
  module Validations
6
6
  class Required < Base
7
- DEFAULT_MESSAGE = lambda do |service_class_name:, input:, value:|
8
- i18n_key = "servactory.inputs.validations.required.default_error."
9
- i18n_key += input.collection_mode? && value.present? ? "for_collection" : "default"
10
-
11
- I18n.t(
12
- i18n_key,
13
- service_class_name: service_class_name,
14
- input_name: input.name
15
- )
16
- end
17
-
18
- private_constant :DEFAULT_MESSAGE
19
-
20
7
  def self.check(context:, attribute:, value:, check_key:, **)
21
8
  return unless should_be_checked_for?(attribute, check_key)
22
9
 
@@ -39,7 +26,7 @@ module Servactory
39
26
 
40
27
  def check
41
28
  if @input.collection_mode? && Servactory::Utils.value_present?(@value)
42
- return if @value.respond_to?(:all?) && @value.all?(&:present?)
29
+ return if collection_valid?
43
30
  elsif Servactory::Utils.value_present?(@value)
44
31
  return
45
32
  end
@@ -51,9 +38,17 @@ module Servactory
51
38
 
52
39
  private
53
40
 
41
+ def collection_valid?
42
+ collection_valid_for?(values: @value)
43
+ end
44
+
45
+ def collection_valid_for?(values:)
46
+ values.respond_to?(:all?) && values.flatten.all?(&:present?)
47
+ end
48
+
54
49
  def add_error_with(message)
55
50
  add_error(
56
- message: message.presence || DEFAULT_MESSAGE,
51
+ message: message.presence || Servactory::Inputs::Translator::Required.default_message,
57
52
  service_class_name: @context.class.name,
58
53
  input: @input,
59
54
  value: @value
@@ -16,11 +16,13 @@ module Servactory
16
16
 
17
17
  private
18
18
 
19
- def internal(name, **options)
19
+ def internal(name, *helpers, **options)
20
20
  collection_of_internals << Internal.new(
21
21
  name,
22
+ *helpers,
22
23
  collection_mode_class_names: config.collection_mode_class_names,
23
24
  hash_mode_class_names: config.hash_mode_class_names,
25
+ option_helpers: config.internal_option_helpers,
24
26
  **options
25
27
  )
26
28
  end
@@ -8,15 +8,18 @@ module Servactory
8
8
 
9
9
  def initialize(
10
10
  name,
11
+ *helpers,
11
12
  collection_mode_class_names:,
12
13
  hash_mode_class_names:,
14
+ option_helpers:,
13
15
  **options
14
16
  )
15
17
  @name = name
16
18
  @collection_mode_class_names = collection_mode_class_names
17
19
  @hash_mode_class_names = hash_mode_class_names
20
+ @option_helpers = option_helpers
18
21
 
19
- register_options(options: options)
22
+ register_options(helpers: helpers, options: options)
20
23
  end
21
24
 
22
25
  def method_missing(name, *args, &block)
@@ -31,7 +34,9 @@ module Servactory
31
34
  @collection_of_options.names.include?(name) || super
32
35
  end
33
36
 
34
- def register_options(options:) # rubocop:disable Metrics/MethodLength
37
+ def register_options(helpers:, options:) # rubocop:disable Metrics/MethodLength
38
+ options = apply_helpers_for_options(helpers: helpers, options: options) if helpers.present?
39
+
35
40
  options_registrar = Servactory::Maintenance::Attributes::Options::Registrar.register(
36
41
  attribute: self,
37
42
  collection_mode_class_names: @collection_mode_class_names,
@@ -40,13 +45,29 @@ module Servactory
40
45
  features: {
41
46
  types: true,
42
47
  collection: true,
43
- hash: true
48
+ hash: true,
49
+ inclusion: true,
50
+ must: true
44
51
  }
45
52
  )
46
53
 
47
54
  @collection_of_options = options_registrar.collection
48
55
  end
49
56
 
57
+ def apply_helpers_for_options(helpers:, options:)
58
+ prepared_options = {}
59
+
60
+ helpers.each do |helper|
61
+ found_helper = @option_helpers.find_by(name: helper)
62
+
63
+ next if found_helper.blank?
64
+
65
+ prepared_options.merge!(found_helper.equivalent)
66
+ end
67
+
68
+ options.merge(prepared_options)
69
+ end
70
+
50
71
  def options_for_checks
51
72
  @collection_of_options.options_for_checks
52
73
  end
@@ -7,7 +7,7 @@ module Servactory
7
7
  extend Forwardable
8
8
  def_delegators :@collection, :<<, :find, :merge
9
9
 
10
- def initialize(collection)
10
+ def initialize(collection = Set.new)
11
11
  @collection = collection
12
12
  end
13
13
 
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Maintenance
5
+ module Attributes
6
+ module Translator
7
+ module Inclusion
8
+ module_function
9
+
10
+ def default_message
11
+ lambda do |service_class_name:, value:, input: nil, internal: nil, output: nil|
12
+ attribute = Servactory::Utils.define_attribute_with(input: input, internal: internal, output: output)
13
+
14
+ I18n.t(
15
+ "servactory.#{attribute.i18n_name}.validations.inclusion.default_error",
16
+ service_class_name: service_class_name,
17
+ "#{attribute.system_name}_name": attribute.name,
18
+ "#{attribute.system_name}_inclusion": attribute.inclusion[:in],
19
+ value: value
20
+ )
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Maintenance
5
+ module Attributes
6
+ module Translator
7
+ module Must
8
+ module_function
9
+
10
+ def default_message
11
+ lambda do |service_class_name:, value:, code:, input: nil, internal: nil, output: nil|
12
+ attribute = Servactory::Utils.define_attribute_with(input: input, internal: internal, output: output)
13
+
14
+ I18n.t(
15
+ "servactory.#{attribute.i18n_name}.validations.must.default_error",
16
+ service_class_name: service_class_name,
17
+ "#{attribute.system_name}_name": attribute.name,
18
+ value: value,
19
+ code: code
20
+ )
21
+ end
22
+ end
23
+
24
+ def syntax_error_message # rubocop:disable Metrics/MethodLength
25
+ lambda do |service_class_name:, value:, code:, exception_message:, input: nil, internal: nil, output: nil|
26
+ attribute = Servactory::Utils.define_attribute_with(input: input, internal: internal, output: output)
27
+
28
+ I18n.t(
29
+ "servactory.#{attribute.i18n_name}.validations.must.syntax_error",
30
+ service_class_name: service_class_name,
31
+ "#{attribute.system_name}_name": attribute.name,
32
+ value: value,
33
+ code: code,
34
+ exception_message: exception_message
35
+ )
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end