servactory 2.6.3 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/config/locales/en.yml +12 -0
  3. data/config/locales/ru.yml +12 -0
  4. data/lib/servactory/actions/dsl.rb +2 -2
  5. data/lib/servactory/actions/tools/runner.rb +1 -1
  6. data/lib/servactory/configuration/factory.rb +1 -31
  7. data/lib/servactory/configuration/setup.rb +3 -3
  8. data/lib/servactory/context/callable.rb +7 -7
  9. data/lib/servactory/context/workspace/inputs.rb +2 -2
  10. data/lib/servactory/context/workspace/internals.rb +3 -3
  11. data/lib/servactory/context/workspace/outputs.rb +3 -3
  12. data/lib/servactory/context/workspace.rb +19 -19
  13. data/lib/servactory/info/dsl.rb +3 -3
  14. data/lib/servactory/inputs/input.rb +5 -5
  15. data/lib/servactory/inputs/tools/validation.rb +7 -7
  16. data/lib/servactory/inputs/validations/required.rb +1 -1
  17. data/lib/servactory/internals/internal.rb +5 -5
  18. data/lib/servactory/maintenance/attributes/option.rb +13 -13
  19. data/lib/servactory/maintenance/attributes/tools/validation.rb +5 -5
  20. data/lib/servactory/maintenance/attributes/translator/inclusion.rb +2 -2
  21. data/lib/servactory/maintenance/attributes/translator/must.rb +8 -8
  22. data/lib/servactory/maintenance/attributes/translator/type.rb +12 -12
  23. data/lib/servactory/maintenance/attributes/validations/inclusion.rb +1 -1
  24. data/lib/servactory/maintenance/attributes/validations/must.rb +7 -7
  25. data/lib/servactory/maintenance/attributes/validations/type.rb +1 -1
  26. data/lib/servactory/maintenance/validations/object_schema.rb +11 -11
  27. data/lib/servactory/outputs/output.rb +5 -5
  28. data/lib/servactory/result.rb +15 -4
  29. data/lib/servactory/test_kit/result.rb +2 -2
  30. data/lib/servactory/test_kit/rspec/matchers/have_service_input_matchers/valid_with_matcher.rb +1 -1
  31. data/lib/servactory/tool_kit/dynamic_options/consists_of.rb +14 -13
  32. data/lib/servactory/tool_kit/dynamic_options/format.rb +11 -8
  33. data/lib/servactory/tool_kit/dynamic_options/max.rb +12 -9
  34. data/lib/servactory/tool_kit/dynamic_options/min.rb +12 -9
  35. data/lib/servactory/tool_kit/dynamic_options/multiple_of.rb +103 -0
  36. data/lib/servactory/tool_kit/dynamic_options/must.rb +16 -13
  37. data/lib/servactory/version.rb +2 -2
  38. metadata +5 -8
  39. data/lib/servactory/errors/failure.rb +0 -20
  40. data/lib/servactory/errors/input_error.rb +0 -20
  41. data/lib/servactory/errors/internal_error.rb +0 -20
  42. data/lib/servactory/errors/output_error.rb +0 -20
@@ -10,11 +10,11 @@ module Servactory
10
10
  def default_message
11
11
  lambda do |service:, attribute:, key_name:, expected_type:, given_type:, **|
12
12
  if attribute.hash_mode? && key_name.present?
13
- for_hash_mode_with(service: service, attribute: attribute, key_name: key_name,
14
- expected_type: expected_type, given_type: given_type)
13
+ for_hash_mode_with(service:, attribute:, key_name:,
14
+ expected_type:, given_type:)
15
15
  else
16
- for_others_with(service: service, attribute: attribute,
17
- expected_type: expected_type, given_type: given_type)
16
+ for_others_with(service:, attribute:,
17
+ expected_type:, given_type:)
18
18
  end
19
19
  end
20
20
  end
@@ -27,9 +27,9 @@ module Servactory
27
27
  if hash_message.is_a?(Proc)
28
28
  hash_message.call(
29
29
  **Servactory::Utils.fetch_hash_with_desired_attribute(attribute),
30
- key_name: key_name,
31
- expected_type: expected_type,
32
- given_type: given_type
30
+ key_name:,
31
+ expected_type:,
32
+ given_type:
33
33
  )
34
34
  elsif hash_message.is_a?(String) && hash_message.present?
35
35
  hash_message
@@ -37,9 +37,9 @@ module Servactory
37
37
  service.translate(
38
38
  "#{attribute.i18n_name}.validations.type.default_error.for_hash.wrong_element_type",
39
39
  "#{attribute.system_name}_name": attribute.name,
40
- key_name: key_name,
41
- expected_type: expected_type,
42
- given_type: given_type
40
+ key_name:,
41
+ expected_type:,
42
+ given_type:
43
43
  )
44
44
  end
45
45
  end
@@ -48,8 +48,8 @@ module Servactory
48
48
  service.translate(
49
49
  "#{attribute.i18n_name}.validations.type.default_error.default",
50
50
  "#{attribute.system_name}_name": attribute.name,
51
- expected_type: expected_type,
52
- given_type: given_type
51
+ expected_type:,
52
+ given_type:
53
53
  )
54
54
  end
55
55
  end
@@ -8,7 +8,7 @@ module Servactory
8
8
  def self.check(context:, attribute:, value:, check_key:, **)
9
9
  return unless should_be_checked_for?(attribute, value, check_key)
10
10
 
11
- new(context: context, attribute: attribute, value: value).check
11
+ new(context:, attribute:, value:).check
12
12
  end
13
13
 
14
14
  # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
@@ -8,7 +8,7 @@ module Servactory
8
8
  def self.check(context:, attribute:, value:, check_key:, check_options:)
9
9
  return unless should_be_checked_for?(attribute, check_key)
10
10
 
11
- new(context: context, attribute: attribute, value: value, check_options: check_options).check
11
+ new(context:, attribute:, value:, check_options:).check
12
12
  end
13
13
 
14
14
  def self.should_be_checked_for?(attribute, check_key)
@@ -64,23 +64,23 @@ module Servactory
64
64
 
65
65
  def add_error_with(message, code, reason)
66
66
  add_error(
67
- message: message,
67
+ message:,
68
68
  service: @context.send(:servactory_service_info),
69
69
  **Servactory::Utils.fetch_hash_with_desired_attribute(@attribute),
70
70
  value: @value,
71
- code: code,
72
- reason: reason
71
+ code:,
72
+ reason:
73
73
  )
74
74
  end
75
75
 
76
76
  def add_syntax_error_with(message, code, exception_message)
77
77
  add_error(
78
- message: message,
78
+ message:,
79
79
  service: @context.send(:servactory_service_info),
80
80
  **Servactory::Utils.fetch_hash_with_desired_attribute(@attribute),
81
81
  value: @value,
82
- code: code,
83
- exception_message: exception_message
82
+ code:,
83
+ exception_message:
84
84
  )
85
85
  end
86
86
  end
@@ -8,7 +8,7 @@ module Servactory
8
8
  def self.check(context:, attribute:, value:, check_key:, **)
9
9
  return unless should_be_checked_for?(attribute, value, check_key)
10
10
 
11
- new(context: context, attribute: attribute, value: value).check
11
+ new(context:, attribute:, value:).check
12
12
  end
13
13
 
14
14
  # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
@@ -49,10 +49,10 @@ module Servactory
49
49
  )
50
50
  else
51
51
  is_success = validate_with(
52
- object: object,
53
- schema_key: schema_key,
54
- schema_value: schema_value,
55
- attribute_type: attribute_type,
52
+ object:,
53
+ schema_key:,
54
+ schema_value:,
55
+ attribute_type:,
56
56
  attribute_required: schema_value.fetch(:required, true)
57
57
  )
58
58
 
@@ -69,16 +69,16 @@ module Servactory
69
69
 
70
70
  def validate_with(object:, schema_key:, schema_value:, attribute_type:, attribute_required:) # rubocop:disable Metrics/MethodLength
71
71
  unless should_be_checked_for?(
72
- object: object,
73
- schema_key: schema_key,
74
- schema_value: schema_value,
72
+ object:,
73
+ schema_key:,
74
+ schema_value:,
75
75
  required: attribute_required
76
76
  ) # do
77
77
  return true
78
78
  end
79
79
 
80
80
  value = object.fetch(schema_key, nil)
81
- prepared_value = prepare_value_from(schema_value: schema_value, value: value, required: attribute_required)
81
+ prepared_value = prepare_value_from(schema_value:, value:, required: attribute_required)
82
82
 
83
83
  Array(attribute_type).any? { |type| prepared_value.is_a?(type) }
84
84
  end
@@ -105,9 +105,9 @@ module Servactory
105
105
 
106
106
  def add_error(key_name:, expected_type:, given_type:)
107
107
  @errors << {
108
- key_name: key_name,
109
- expected_type: expected_type,
110
- given_type: given_type
108
+ key_name:,
109
+ expected_type:,
110
+ given_type:
111
111
  }
112
112
  end
113
113
  end
@@ -36,11 +36,11 @@ module Servactory
36
36
  @hash_mode_class_names = hash_mode_class_names
37
37
  @option_helpers = option_helpers
38
38
 
39
- register_options(helpers: helpers, options: options)
39
+ register_options(helpers:, options:)
40
40
  end
41
41
 
42
42
  def method_missing(name, *args, &block)
43
- option = @collection_of_options.find_by(name: name)
43
+ option = @collection_of_options.find_by(name:)
44
44
 
45
45
  return super if option.nil?
46
46
 
@@ -54,13 +54,13 @@ module Servactory
54
54
  def register_options(helpers:, options:) # rubocop:disable Metrics/MethodLength
55
55
  advanced_helpers = options.except(*Servactory::Maintenance::Attributes::Options::Registrar::RESERVED_OPTIONS)
56
56
 
57
- options = apply_helpers_for_options(helpers: helpers, options: options) if helpers.present?
58
- options = apply_helpers_for_options(helpers: advanced_helpers, options: options) if advanced_helpers.present?
57
+ options = apply_helpers_for_options(helpers:, options:) if helpers.present?
58
+ options = apply_helpers_for_options(helpers: advanced_helpers, options:) if advanced_helpers.present?
59
59
 
60
60
  options_registrar = Servactory::Maintenance::Attributes::Options::Registrar.register(
61
61
  attribute: self,
62
62
  hash_mode_class_names: @hash_mode_class_names,
63
- options: options,
63
+ options:,
64
64
  features: {
65
65
  types: true,
66
66
  hash: true,
@@ -27,12 +27,15 @@ module Servactory
27
27
 
28
28
  ############################################################################
29
29
 
30
+ STATE_PREDICATE_NAMES = %i[success? failure?].freeze
31
+ private_constant :STATE_PREDICATE_NAMES
32
+
30
33
  def self.success_for(context:)
31
- new(context: context).send(:as_success)
34
+ new(context:).send(:as_success)
32
35
  end
33
36
 
34
37
  def self.failure_for(context:, exception:)
35
- new(context: context, exception: exception).send(:as_failure)
38
+ new(context:, exception:).send(:as_failure)
36
39
  end
37
40
 
38
41
  def initialize(context:, exception: nil)
@@ -40,18 +43,26 @@ module Servactory
40
43
  @exception = exception
41
44
  end
42
45
 
46
+ def to_h
47
+ filtered = methods(false).filter do |key|
48
+ !key.in?(STATE_PREDICATE_NAMES) && !key.to_s.end_with?("?")
49
+ end
50
+
51
+ filtered.to_h { |key| [key, public_send(key)] }.compact
52
+ end
53
+
43
54
  def inspect
44
55
  "#<#{self.class.name} #{draw_result}>"
45
56
  end
46
57
 
47
58
  def on_success
48
- yield(outputs: outputs) if success?
59
+ yield(outputs:) if success?
49
60
 
50
61
  self
51
62
  end
52
63
 
53
64
  def on_failure(type = :all)
54
- yield(outputs: outputs, exception: @exception) if failure? && [:all, @exception&.type].include?(type)
65
+ yield(outputs:, exception: @exception) if failure? && [:all, @exception&.type].include?(type)
55
66
 
56
67
  self
57
68
  end
@@ -6,13 +6,13 @@ module Servactory
6
6
  def self.as_success(attributes = {})
7
7
  context = new(attributes)
8
8
 
9
- Servactory::Result.success_for(context: context)
9
+ Servactory::Result.success_for(context:)
10
10
  end
11
11
 
12
12
  def self.as_failure(attributes = {}, exception: nil)
13
13
  context = new(attributes)
14
14
 
15
- Servactory::Result.failure_for(context: context, exception: exception)
15
+ Servactory::Result.failure_for(context:, exception:)
16
16
  end
17
17
 
18
18
  def initialize(attributes = {})
@@ -148,7 +148,7 @@ module Servactory
148
148
  input_actor = attribute_data.fetch(:actor)
149
149
 
150
150
  input_required_message = input_required_message.call(
151
- service: service,
151
+ service:,
152
152
  input: input_actor,
153
153
  value: wrong_value
154
154
  )
@@ -15,15 +15,15 @@ module Servactory
15
15
  end
16
16
 
17
17
  def condition_for_input_with(input:, value:, option:)
18
- common_condition_with(attribute: input, value: value, option: option)
18
+ common_condition_with(attribute: input, value:, option:)
19
19
  end
20
20
 
21
21
  def condition_for_internal_with(internal:, value:, option:)
22
- common_condition_with(attribute: internal, value: value, option: option)
22
+ common_condition_with(attribute: internal, value:, option:)
23
23
  end
24
24
 
25
25
  def condition_for_output_with(output:, value:, option:)
26
- common_condition_with(attribute: output, value: value, option: option)
26
+ common_condition_with(attribute: output, value:, option:)
27
27
  end
28
28
 
29
29
  def common_condition_with(attribute:, value:, option:)
@@ -32,15 +32,13 @@ module Servactory
32
32
 
33
33
  values = value.respond_to?(:flatten) ? value&.flatten : value
34
34
 
35
- validate_for!(attribute: attribute, values: values, option: option)
35
+ validate_for!(attribute:, values:, option:)
36
36
  end
37
37
 
38
38
  def validate_for!(attribute:, values:, option:)
39
39
  consists_of_types = Array(option.value)
40
40
 
41
- if fails_presence_validation?(attribute: attribute, values: values, consists_of_types: consists_of_types)
42
- return [false, :required]
43
- end
41
+ return [false, :required] if fails_presence_validation?(attribute:, values:, consists_of_types:)
44
42
 
45
43
  return true if values.blank? && attribute.input? && attribute.optional?
46
44
 
@@ -65,7 +63,7 @@ module Servactory
65
63
 
66
64
  ########################################################################
67
65
 
68
- def message_for_input_with(service:, input:, value:, option_value:, reason:, **)
66
+ def message_for_input_with(service:, input:, value:, option_name:, option_value:, reason:, **)
69
67
  i18n_key = "inputs.validations.must.dynamic_options.consists_of"
70
68
  i18n_key += reason.present? ? ".#{reason}" : ".default"
71
69
 
@@ -73,12 +71,13 @@ module Servactory
73
71
  i18n_key,
74
72
  service_class_name: service.class_name,
75
73
  input_name: input.name,
74
+ option_name:,
76
75
  expected_type: Array(option_value).uniq.join(", "),
77
- given_type: given_type_for(values: value, option_value: option_value)
76
+ given_type: given_type_for(values: value, option_value:)
78
77
  )
79
78
  end
80
79
 
81
- def message_for_internal_with(service:, internal:, value:, option_value:, reason:, **)
80
+ def message_for_internal_with(service:, internal:, value:, option_name:, option_value:, reason:, **)
82
81
  i18n_key = "internals.validations.must.dynamic_options.consists_of"
83
82
  i18n_key += reason.present? ? ".#{reason}" : ".default"
84
83
 
@@ -86,12 +85,13 @@ module Servactory
86
85
  i18n_key,
87
86
  service_class_name: service.class_name,
88
87
  internal_name: internal.name,
88
+ option_name:,
89
89
  expected_type: Array(option_value).uniq.join(", "),
90
- given_type: given_type_for(values: value, option_value: option_value)
90
+ given_type: given_type_for(values: value, option_value:)
91
91
  )
92
92
  end
93
93
 
94
- def message_for_output_with(service:, output:, value:, option_value:, reason:, **)
94
+ def message_for_output_with(service:, output:, value:, option_name:, option_value:, reason:, **)
95
95
  i18n_key = "outputs.validations.must.dynamic_options.consists_of"
96
96
  i18n_key += reason.present? ? ".#{reason}" : ".default"
97
97
 
@@ -99,8 +99,9 @@ module Servactory
99
99
  i18n_key,
100
100
  service_class_name: service.class_name,
101
101
  output_name: output.name,
102
+ option_name:,
102
103
  expected_type: Array(option_value).uniq.join(", "),
103
- given_type: given_type_for(values: value, option_value: option_value)
104
+ given_type: given_type_for(values: value, option_value:)
104
105
  )
105
106
  end
106
107
 
@@ -88,7 +88,7 @@ module Servactory
88
88
 
89
89
  return [false, :unknown] unless @formats.key?(option_value)
90
90
 
91
- attribute = Utils.define_attribute_with(input: input, internal: internal, output: output)
91
+ attribute = Utils.define_attribute_with(input:, internal:, output:)
92
92
 
93
93
  if value.blank? &&
94
94
  (
@@ -107,44 +107,47 @@ module Servactory
107
107
 
108
108
  return [false, :wrong_pattern] if format_pattern.present? && !value.match?(Regexp.compile(format_pattern))
109
109
 
110
- option.properties.fetch(:validator, format_options.fetch(:validator)).call(value: value)
110
+ option.properties.fetch(:validator, format_options.fetch(:validator)).call(value:)
111
111
  end
112
112
  # rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
113
113
 
114
114
  ########################################################################
115
115
 
116
- def message_for_input_with(service:, input:, value:, option_value:, reason:, **)
116
+ def message_for_input_with(service:, input:, value:, option_name:, option_value:, reason:, **)
117
117
  i18n_key = "inputs.validations.must.dynamic_options.format"
118
118
  i18n_key += reason.present? ? ".#{reason}" : ".default"
119
119
 
120
120
  service.translate(
121
121
  i18n_key,
122
122
  input_name: input.name,
123
- value: value,
123
+ value:,
124
+ option_name:,
124
125
  format_name: option_value.present? ? option_value : option_value.inspect
125
126
  )
126
127
  end
127
128
 
128
- def message_for_internal_with(service:, internal:, value:, option_value:, reason:, **)
129
+ def message_for_internal_with(service:, internal:, value:, option_name:, option_value:, reason:, **)
129
130
  i18n_key = "internals.validations.must.dynamic_options.format"
130
131
  i18n_key += reason.present? ? ".#{reason}" : ".default"
131
132
 
132
133
  service.translate(
133
134
  i18n_key,
134
135
  internal_name: internal.name,
135
- value: value,
136
+ value:,
137
+ option_name:,
136
138
  format_name: option_value.present? ? option_value : option_value.inspect
137
139
  )
138
140
  end
139
141
 
140
- def message_for_output_with(service:, output:, value:, option_value:, reason:, **)
142
+ def message_for_output_with(service:, output:, value:, option_name:, option_value:, reason:, **)
141
143
  i18n_key = "outputs.validations.must.dynamic_options.format"
142
144
  i18n_key += reason.present? ? ".#{reason}" : ".default"
143
145
 
144
146
  service.translate(
145
147
  i18n_key,
146
148
  output_name: output.name,
147
- value: value,
149
+ value:,
150
+ option_name:,
148
151
  format_name: option_value.present? ? option_value : option_value.inspect
149
152
  )
150
153
  end
@@ -33,30 +33,33 @@ module Servactory
33
33
 
34
34
  ########################################################################
35
35
 
36
- def message_for_input_with(service:, input:, value:, option_value:, **)
36
+ def message_for_input_with(service:, input:, value:, option_name:, option_value:, **)
37
37
  service.translate(
38
38
  "inputs.validations.must.dynamic_options.max.default",
39
39
  input_name: input.name,
40
- value: value,
41
- option_value: option_value
40
+ value:,
41
+ option_name:,
42
+ option_value:
42
43
  )
43
44
  end
44
45
 
45
- def message_for_internal_with(service:, internal:, value:, option_value:, **)
46
+ def message_for_internal_with(service:, internal:, value:, option_name:, option_value:, **)
46
47
  service.translate(
47
48
  "internals.validations.must.dynamic_options.max.default",
48
49
  internal_name: internal.name,
49
- value: value,
50
- option_value: option_value
50
+ value:,
51
+ option_name:,
52
+ option_value:
51
53
  )
52
54
  end
53
55
 
54
- def message_for_output_with(service:, output:, value:, option_value:, **)
56
+ def message_for_output_with(service:, output:, value:, option_name:, option_value:, **)
55
57
  service.translate(
56
58
  "outputs.validations.must.dynamic_options.max.default",
57
59
  output_name: output.name,
58
- value: value,
59
- option_value: option_value
60
+ value:,
61
+ option_name:,
62
+ option_value:
60
63
  )
61
64
  end
62
65
  end
@@ -33,30 +33,33 @@ module Servactory
33
33
 
34
34
  ########################################################################
35
35
 
36
- def message_for_input_with(service:, input:, value:, option_value:, **)
36
+ def message_for_input_with(service:, input:, value:, option_name:, option_value:, **)
37
37
  service.translate(
38
38
  "inputs.validations.must.dynamic_options.min.default",
39
39
  input_name: input.name,
40
- value: value,
41
- option_value: option_value
40
+ value:,
41
+ option_name:,
42
+ option_value:
42
43
  )
43
44
  end
44
45
 
45
- def message_for_internal_with(service:, internal:, value:, option_value:, **)
46
+ def message_for_internal_with(service:, internal:, value:, option_name:, option_value:, **)
46
47
  service.translate(
47
48
  "internals.validations.must.dynamic_options.min.default",
48
49
  internal_name: internal.name,
49
- value: value,
50
- option_value: option_value
50
+ value:,
51
+ option_name:,
52
+ option_value:
51
53
  )
52
54
  end
53
55
 
54
- def message_for_output_with(service:, output:, value:, option_value:, **)
56
+ def message_for_output_with(service:, output:, value:, option_name:, option_value:, **)
55
57
  service.translate(
56
58
  "outputs.validations.must.dynamic_options.min.default",
57
59
  output_name: output.name,
58
- value: value,
59
- option_value: option_value
60
+ value:,
61
+ option_name:,
62
+ option_value:
60
63
  )
61
64
  end
62
65
  end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module ToolKit
5
+ module DynamicOptions
6
+ class MultipleOf < Must
7
+ def self.use(option_name = :multiple_of)
8
+ new(option_name).must(:be_multiple_of)
9
+ end
10
+
11
+ def condition_for_input_with(...)
12
+ common_condition_with(...)
13
+ end
14
+
15
+ def condition_for_internal_with(...)
16
+ common_condition_with(...)
17
+ end
18
+
19
+ def condition_for_output_with(...)
20
+ common_condition_with(...)
21
+ end
22
+
23
+ def common_condition_with(value:, option:, **)
24
+ case value
25
+ when Integer, Float, Rational, BigDecimal
26
+ return false if option.value.blank?
27
+ return false unless [Numeric, Float, Rational, BigDecimal].any? { |c| option.value.is_a?(c) }
28
+ return false if option.value.zero?
29
+
30
+ (value % option.value).zero?
31
+ else
32
+ false
33
+ end
34
+ end
35
+
36
+ ########################################################################
37
+
38
+ def message_for_input_with(service:, input:, value:, option_name:, option_value:, **) # rubocop:disable Metrics/MethodLength
39
+ i18n_key = "inputs.validations.must.dynamic_options.multiple_of"
40
+
41
+ i18n_key += if option_value.blank?
42
+ ".blank"
43
+ elsif [Numeric, Float, Rational, BigDecimal].any? { |c| option_value.is_a?(c) } &&
44
+ option_value.zero?
45
+ ".divided_by_0"
46
+ else
47
+ ".default"
48
+ end
49
+
50
+ service.translate(
51
+ i18n_key,
52
+ input_name: input.name,
53
+ value:,
54
+ option_name:,
55
+ option_value: option_value.inspect
56
+ )
57
+ end
58
+
59
+ def message_for_internal_with(service:, internal:, value:, option_name:, option_value:, **) # rubocop:disable Metrics/MethodLength
60
+ i18n_key = "internals.validations.must.dynamic_options.multiple_of"
61
+
62
+ i18n_key += if option_value.blank?
63
+ ".blank"
64
+ elsif [Numeric, Float, Rational, BigDecimal].any? { |c| option_value.is_a?(c) } &&
65
+ option_value.zero?
66
+ ".divided_by_0"
67
+ else
68
+ ".default"
69
+ end
70
+
71
+ service.translate(
72
+ i18n_key,
73
+ internal_name: internal.name,
74
+ value:,
75
+ option_name:,
76
+ option_value: option_value.inspect
77
+ )
78
+ end
79
+
80
+ def message_for_output_with(service:, output:, value:, option_name:, option_value:, **) # rubocop:disable Metrics/MethodLength
81
+ i18n_key = "outputs.validations.must.dynamic_options.multiple_of"
82
+
83
+ i18n_key += if option_value.blank?
84
+ ".blank"
85
+ elsif [Numeric, Float, Rational, BigDecimal].any? { |c| option_value.is_a?(c) } &&
86
+ option_value.zero?
87
+ ".divided_by_0"
88
+ else
89
+ ".default"
90
+ end
91
+
92
+ service.translate(
93
+ i18n_key,
94
+ output_name: output.name,
95
+ value:,
96
+ option_name:,
97
+ option_value: option_value.inspect
98
+ )
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end