servactory 2.1.1 → 2.2.0.rc1

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.
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 +3 -3
  34. metadata +11 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f71f5e26bf004c9e435dc60e22099e52a55a3b2a2bd0686668151f238c039d4a
4
- data.tar.gz: 4c85082a8367d0839ff1fa6a43ef66675294ca3f85d1bf73405b587f654ba638
3
+ metadata.gz: 5c12708849de24be4c1dc728185784afde60fa4cddad681d52d591561b4acacd
4
+ data.tar.gz: d1d5d7334b5e6b1ecc7f92b526faa60f67521fc73a3f33ab4d30f8b2e2b94f5c
5
5
  SHA512:
6
- metadata.gz: a6390fd3762d4d7c1ef7e42f0ff0f18a0d866760544f4c93d439a853a33a55dbf83f6343b205f19af30b6f715455fbf4b7544ed1dc9d94216994c92e8e2647a5
7
- data.tar.gz: d8e3dc501fe810719134a94dbb9a1bae166ca3df335c497a6a1cf5487dd796158620e901e579461072b9adfed013d934db6319748022c9ca7ff1c24062d42ec1
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