Class: Servactory::ToolKit::DynamicOptions::Format
- Defined in:
- lib/servactory/tool_kit/dynamic_options/format.rb
Overview
Validates string values against predefined or custom format patterns.
## Purpose
Format provides pattern-based validation for string attributes using regular expressions and custom validators. It includes built-in formats for common use cases (UUID, email, date, etc.) and supports custom format definitions.
## Usage
This option is **NOT included by default**. Register it for each attribute type where you want to use it:
“‘ruby configuration do
input_option_helpers([
Servactory::ToolKit::DynamicOptions::Format.use
])
internal_option_helpers([
Servactory::ToolKit::DynamicOptions::Format.use
])
output_option_helpers([
Servactory::ToolKit::DynamicOptions::Format.use
])
end “‘
Use built-in formats in your service:
“‘ruby class MyService < ApplicationService::Base
input :user_id, type: String, format: :uuid
input :email, type: String, format: :email
input :birth_date, type: String, format: :date
end “‘
Add custom formats:
“‘ruby Format.use(formats:
phone: {
pattern: /\A\+?[1-9]\d{6,14\z/,
validator: ->(value:) { value.present? }
}
}) “‘
## Supported Formats
| Format | Description | |——–|————-| | ‘:uuid` | Standard UUID format (8-4-4-4-12 hex digits) | | `:email` | Email address per RFC 2822 | | `:password` | 8-16 chars with digit, lowercase, uppercase | | `:duration` | ISO 8601 duration (e.g., “PT1H30M”) | | `:date` | Parseable date string | | `:datetime` | Parseable datetime string | | `:time` | Parseable time string | | `:boolean` | Truthy boolean string (“true” or “1”) |
## Simple Mode
Specify format directly as the option value:
“‘ruby class ValidateUserService < ApplicationService::Base
input :uuid, type: String, format: :uuid
input :email, type: String, format: :email
input :password, type: String, format: :password
end “‘
## Advanced Mode
Specify format with custom error message using a hash:
With static message:
“‘ruby input :email, type: String, format: {
is: :email,
message: "Input `email` must be a valid email address"
} “‘
With dynamic lambda message:
“‘ruby input :email, type: String, format: {
is: :email,
message: lambda do |input:, value:, option_value:, **|
"Input `#{input.name}` with value `#{value}` does not match `#{option_value}` format"
end
} “‘
Lambda receives the following parameters:
-
For inputs: ‘input:, value:, option_value:, reason:, **`
-
For internals: ‘internal:, value:, option_value:, reason:, **`
-
For outputs: ‘output:, value:, option_value:, reason:, **`
## Important Notes
-
Optional inputs with blank values skip validation
-
Custom patterns can be strings or Regexp objects
-
Validators receive ‘value:` keyword argument
-
Unknown format names return ‘:unknown` error
-
Format validation is two-phase: pattern check (if defined), then validator callback
-
The ‘:boolean` format pattern matches “true”, “false”, “0”, “1”, but validator only passes for truthy values (“true”, “1”); “false” and “0” will fail validation
Class Method Summary collapse
-
.use(option_name = :format, formats: {}) ⇒ Servactory::Maintenance::Attributes::OptionHelper
Creates a Format validator instance.
Instance Method Summary collapse
-
#assign(formats = {}) ⇒ void
Assigns format definitions, merging with defaults.
-
#common_condition_with(value:, option:, input: nil, internal: nil, output: nil) ⇒ Boolean, Array
Common format validation logic.
-
#condition_for_input_with ⇒ Boolean, Array
Validates format condition for input attribute.
-
#condition_for_internal_with ⇒ Boolean, Array
Validates format condition for internal attribute.
-
#condition_for_output_with ⇒ Boolean, Array
Validates format condition for output attribute.
-
#message_for_input_with(service:, input:, value:, option_name:, option_value:, reason:) ⇒ String
Generates error message for input validation failure.
-
#message_for_internal_with(service:, internal:, value:, option_name:, option_value:, reason:) ⇒ String
Generates error message for internal validation failure.
-
#message_for_output_with(service:, output:, value:, option_name:, option_value:, reason:) ⇒ String
Generates error message for output validation failure.
Methods inherited from Must
#equivalent_with, #initialize, #must, #must_content_message_with, #must_content_value_with, #must_content_with
Constructor Details
This class inherits a constructor from Servactory::ToolKit::DynamicOptions::Must
Class Method Details
.use(option_name = :format, formats: {}) ⇒ Servactory::Maintenance::Attributes::OptionHelper
Creates a Format validator instance.
183 184 185 186 187 |
# File 'lib/servactory/tool_kit/dynamic_options/format.rb', line 183 def self.use(option_name = :format, formats: {}) instance = new(option_name) instance.assign(formats) instance.must(:be_in_format) end |
Instance Method Details
#assign(formats = {}) ⇒ void
This method returns an undefined value.
Assigns format definitions, merging with defaults.
193 194 195 |
# File 'lib/servactory/tool_kit/dynamic_options/format.rb', line 193 def assign(formats = {}) @formats = formats.is_a?(Hash) ? DEFAULT_FORMATS.merge(formats) : DEFAULT_FORMATS end |
#common_condition_with(value:, option:, input: nil, internal: nil, output: nil) ⇒ Boolean, Array
Common format validation logic.
rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
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 |
# File 'lib/servactory/tool_kit/dynamic_options/format.rb', line 236 def common_condition_with(value:, option:, input: nil, internal: nil, output: nil) option_value = option.value&.to_sym # Check if format exists. return [false, :unknown] unless @formats.key?(option_value) attribute = Utils.define_attribute_with(input:, internal:, output:) # Skip validation for blank optional values. if value.blank? && ( (attribute.input? && attribute.optional?) || ( (attribute.internal? || attribute.output?) && attribute.types.include?(NilClass) ) ) return true end = @formats.fetch(option_value) # Get pattern from option properties or format definition. format_pattern = option.properties.fetch(:pattern, .fetch(:pattern)) # Validate against pattern if defined. if format_pattern.present? return [false, :wrong_type] unless value.respond_to?(:match?) compiled_pattern = format_pattern.is_a?(Regexp) ? format_pattern : Regexp.compile(format_pattern) return [false, :wrong_pattern] unless value.match?(compiled_pattern) end # Run validator callback. option.properties.fetch(:validator, .fetch(:validator)).call(value:) end |
#condition_for_input_with ⇒ Boolean, Array
Validates format condition for input attribute.
203 204 205 |
# File 'lib/servactory/tool_kit/dynamic_options/format.rb', line 203 def condition_for_input_with(...) common_condition_with(...) end |
#condition_for_internal_with ⇒ Boolean, Array
Validates format condition for internal attribute.
213 214 215 |
# File 'lib/servactory/tool_kit/dynamic_options/format.rb', line 213 def condition_for_internal_with(...) common_condition_with(...) end |
#condition_for_output_with ⇒ Boolean, Array
Validates format condition for output attribute.
223 224 225 |
# File 'lib/servactory/tool_kit/dynamic_options/format.rb', line 223 def condition_for_output_with(...) common_condition_with(...) end |
#message_for_input_with(service:, input:, value:, option_name:, option_value:, reason:) ⇒ String
Generates error message for input validation failure.
285 286 287 288 289 290 291 292 293 294 295 296 |
# File 'lib/servactory/tool_kit/dynamic_options/format.rb', line 285 def (service:, input:, value:, option_name:, option_value:, reason:, **) i18n_key = "inputs.validations.must.dynamic_options.format" i18n_key += reason.present? ? ".#{reason}" : ".default" service.translate( i18n_key, input_name: input.name, value:, option_name:, format_name: option_value.presence || option_value.inspect ) end |
#message_for_internal_with(service:, internal:, value:, option_name:, option_value:, reason:) ⇒ String
Generates error message for internal validation failure.
307 308 309 310 311 312 313 314 315 316 317 318 |
# File 'lib/servactory/tool_kit/dynamic_options/format.rb', line 307 def (service:, internal:, value:, option_name:, option_value:, reason:, **) i18n_key = "internals.validations.must.dynamic_options.format" i18n_key += reason.present? ? ".#{reason}" : ".default" service.translate( i18n_key, internal_name: internal.name, value:, option_name:, format_name: option_value.presence || option_value.inspect ) end |
#message_for_output_with(service:, output:, value:, option_name:, option_value:, reason:) ⇒ String
Generates error message for output validation failure.
329 330 331 332 333 334 335 336 337 338 339 340 |
# File 'lib/servactory/tool_kit/dynamic_options/format.rb', line 329 def (service:, output:, value:, option_name:, option_value:, reason:, **) i18n_key = "outputs.validations.must.dynamic_options.format" i18n_key += reason.present? ? ".#{reason}" : ".default" service.translate( i18n_key, output_name: output.name, value:, option_name:, format_name: option_value.presence || option_value.inspect ) end |