Class: Servactory::ToolKit::DynamicOptions::Must
- Inherits:
-
Object
- Object
- Servactory::ToolKit::DynamicOptions::Must
- Defined in:
- lib/servactory/tool_kit/dynamic_options/must.rb
Overview
Base class for creating custom dynamic validation options.
## Purpose
Must provides a foundation for implementing custom validation rules that can be applied to service inputs, internals, and outputs. It handles the complexity of option parsing, condition evaluation, and error message generation, allowing subclasses to focus on validation logic.
## Usage
Create a custom validator by inheriting from Must:
“‘ruby class MyValidator < Servactory::ToolKit::DynamicOptions::Must
def self.use(option_name = :my_option)
new(option_name).must(:my_validation)
end
def condition_for_input_with(input:, value:, option:)
# Return true if valid, false otherwise
value.meets_criteria?(option.value)
end
def (input:, value:, option_name:, option_value:, **)
"Input `#{input.name}` must satisfy #{option_name}"
end
# Implement similar methods for internal and output...
end “‘
Register in service configuration:
“‘ruby configuration do
input_option_helpers([
MyValidator.use
])
end “‘
## Simple Mode
Custom validators support simple mode with direct value:
“‘ruby input :value, type: Integer, my_option: 10 “`
## Advanced Mode
Custom validators support advanced mode with custom messages:
With static message:
“‘ruby input :value, type: Integer, my_option:
is: 10,
message: "Custom validation failed"
“‘
With dynamic lambda message:
“‘ruby input :value, type: Integer, my_option:
is: 10,
message: lambda do |input:, value:, option_value:, **|
"Input `#{input.name` failed validation with value `#value`"
end
} “‘
Lambda receives the following parameters:
-
For inputs: ‘input:, option_value:, value:, **`
-
For internals: ‘internal:, option_value:, value:, **`
-
For outputs: ‘output:, option_value:, value:, **`
## Architecture
The class uses a two-phase validation approach:
-
**Condition phase**: ‘condition_for_*` methods return boolean
-
**Message phase**: ‘message_for_*` methods generate error text
## Important Notes
-
Subclasses must implement all six abstract methods
-
Option values support both simple mode (‘option: value`) and advanced mode (`option: { is: value, message: “…” }`)
-
Custom messages can be strings or Procs for dynamic generation
Direct Known Subclasses
ConsistsOf, Format, Inclusion, Max, Min, MultipleOf, Schema, Target
Defined Under Namespace
Classes: WorkOption
Instance Method Summary collapse
-
#condition_for_input_with ⇒ Boolean
abstract
Validates condition for input attribute.
-
#condition_for_internal_with ⇒ Boolean
abstract
Validates condition for internal attribute.
-
#condition_for_output_with ⇒ Boolean
abstract
Validates condition for output attribute.
-
#equivalent_with(name) ⇒ Proc
Builds the equivalence lambda for option transformation.
-
#initialize(option_name, body_key = :is, body_fallback = nil) ⇒ Must
constructor
Creates a new Must instance.
-
#message_for_input_with ⇒ String
abstract
Generates error message for input validation failure.
-
#message_for_internal_with ⇒ String
abstract
Generates error message for internal validation failure.
-
#message_for_output_with ⇒ String
abstract
Generates error message for output validation failure.
-
#must(name) ⇒ Servactory::Maintenance::Attributes::OptionHelper
Creates an OptionHelper for registration with Servactory.
-
#must_content_message_with(option) ⇒ Proc
Builds the error message lambda.
-
#must_content_value_with(option) ⇒ Proc
Builds the validation condition lambda.
-
#must_content_with(option) ⇒ Hash
Constructs the must content hash with value and message lambdas.
Constructor Details
#initialize(option_name, body_key = :is, body_fallback = nil) ⇒ Must
Creates a new Must instance.
149 150 151 152 153 |
# File 'lib/servactory/tool_kit/dynamic_options/must.rb', line 149 def initialize(option_name, body_key = :is, body_fallback = nil) @option_name = option_name @body_key = body_key @body_fallback = body_fallback end |
Instance Method Details
#condition_for_input_with ⇒ Boolean
Subclasses must implement this method
Validates condition for input attribute.
289 290 291 |
# File 'lib/servactory/tool_kit/dynamic_options/must.rb', line 289 def condition_for_input_with(**) raise "Need to implement `condition_for_input_with(**attributes)` method" end |
#condition_for_internal_with ⇒ Boolean
Subclasses must implement this method
Validates condition for internal attribute.
301 302 303 |
# File 'lib/servactory/tool_kit/dynamic_options/must.rb', line 301 def condition_for_internal_with(**) raise "Need to implement `condition_for_internal_with(**attributes)` method" end |
#condition_for_output_with ⇒ Boolean
Subclasses must implement this method
Validates condition for output attribute.
313 314 315 |
# File 'lib/servactory/tool_kit/dynamic_options/must.rb', line 313 def condition_for_output_with(**) raise "Need to implement `condition_for_output_with(**attributes)` method" end |
#equivalent_with(name) ⇒ Proc
Builds the equivalence lambda for option transformation.
174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/servactory/tool_kit/dynamic_options/must.rb', line 174 def equivalent_with(name) lambda do |data| option = WorkOption.new(@option_name, data, body_key: @body_key, body_fallback: @body_fallback) { must: { name => must_content_with(option) } } end end |
#message_for_input_with ⇒ String
Subclasses must implement this method
Generates error message for input validation failure.
325 326 327 |
# File 'lib/servactory/tool_kit/dynamic_options/must.rb', line 325 def (**) raise "Need to implement `message_for_input_with(**attributes)` method" end |
#message_for_internal_with ⇒ String
Subclasses must implement this method
Generates error message for internal validation failure.
337 338 339 |
# File 'lib/servactory/tool_kit/dynamic_options/must.rb', line 337 def (**) raise "Need to implement `message_for_internal_with(**attributes)` method" end |
#message_for_output_with ⇒ String
Subclasses must implement this method
Generates error message for output validation failure.
349 350 351 |
# File 'lib/servactory/tool_kit/dynamic_options/must.rb', line 349 def (**) raise "Need to implement `message_for_output_with(**attributes)` method" end |
#must(name) ⇒ Servactory::Maintenance::Attributes::OptionHelper
Creates an OptionHelper for registration with Servactory.
159 160 161 162 163 164 165 166 167 168 |
# File 'lib/servactory/tool_kit/dynamic_options/must.rb', line 159 def must(name) Servactory::Maintenance::Attributes::OptionHelper.new( name: @option_name, equivalent: equivalent_with(name), meta: { type: :dynamic_option, body_key: @body_key } ) end |
#must_content_message_with(option) ⇒ Proc
Builds the error message lambda.
Handles three message sources:
-
Custom Proc message (called with context)
-
Custom String message (returned as-is)
-
Default message from subclass implementation
rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'lib/servactory/tool_kit/dynamic_options/must.rb', line 225 def (option) = option..present? = option..is_a?(Proc) if lambda do |input: nil, internal: nil, output: nil, **attributes| # rubocop:disable Metrics/BlockLength default_attributes = { **attributes, option_name: option.name, option_value: option.value } if Servactory::Utils.really_input?(input) if if option..call( input:, **default_attributes.delete(:meta) || {}, **default_attributes ) else option. end else (**default_attributes, input:) end elsif Servactory::Utils.really_internal?(internal) if if option..call( internal:, **default_attributes.delete(:meta) || {}, **default_attributes ) else option. end else (**default_attributes, internal:) end elsif Servactory::Utils.really_output?(output) if if option..call( output:, **default_attributes.delete(:meta) || {}, **default_attributes ) else option. end else (**default_attributes, output:) end end end end |
#must_content_value_with(option) ⇒ Proc
Builds the validation condition lambda.
203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/servactory/tool_kit/dynamic_options/must.rb', line 203 def must_content_value_with(option) lambda do |value:, input: nil, internal: nil, output: nil| if input.present? && input.input? condition_for_input_with(input:, value:, option:) elsif internal.present? && internal.internal? condition_for_internal_with(internal:, value:, option:) elsif output.present? && output.output? condition_for_output_with(output:, value:, option:) end end end |
#must_content_with(option) ⇒ Hash
Constructs the must content hash with value and message lambdas.
190 191 192 193 194 195 |
# File 'lib/servactory/tool_kit/dynamic_options/must.rb', line 190 def must_content_with(option) { is: must_content_value_with(option), message: (option) } end |