Class: CMDx::Validators

Inherits:
Object
  • Object
show all
Defined in:
lib/cmdx/validators.rb,
lib/cmdx/validators/format.rb,
lib/cmdx/validators/length.rb,
lib/cmdx/validators/absence.rb,
lib/cmdx/validators/numeric.rb,
lib/cmdx/validators/presence.rb,
lib/cmdx/validators/validate.rb,
lib/cmdx/validators/exclusion.rb,
lib/cmdx/validators/inclusion.rb

Overview

Registry of named validators applied to resolved input/output values. Ships with built-ins for ‘:absence`, `:exclusion`, `:format`, `:inclusion`, `:length`, `:numeric`, `:presence`. Validators return a Failure on invalid input (recorded on `task.errors`) or `nil` on success. The `:validate` key supports inline callables.

Defined Under Namespace

Modules: Absence, Exclusion, Format, Inclusion, Length, Numeric, Presence, Validate Classes: Failure

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeValidators

Returns a new instance of Validators.



17
18
19
20
21
22
23
24
25
26
27
# File 'lib/cmdx/validators.rb', line 17

def initialize
  @registry = {
    absence: Validators::Absence,
    exclusion: Validators::Exclusion,
    format: Validators::Format,
    inclusion: Validators::Inclusion,
    length: Validators::Length,
    numeric: Validators::Numeric,
    presence: Validators::Presence
  }
end

Instance Attribute Details

#registryObject (readonly)

Returns the value of attribute registry.



15
16
17
# File 'lib/cmdx/validators.rb', line 15

def registry
  @registry
end

Instance Method Details

#deregister(name) ⇒ Validators

Returns self for chaining.

Parameters:

  • name (Symbol)

Returns:



59
60
61
62
# File 'lib/cmdx/validators.rb', line 59

def deregister(name)
  registry.delete(name.to_sym)
  self
end

#empty?Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/cmdx/validators.rb', line 95

def empty?
  registry.empty?
end

#extract(options) ⇒ Hash{Symbol => Object}

Picks registered-validator keys out of a declaration’s options and appends ‘:validate` (inline callable(s)) when present.

Parameters:

  • options (Hash{Symbol => Object})

    declaration options

Options Hash (options):

  • :presence (Object)

    payload for the presence validator (‘call`)

  • :absence (Object)

    payload for the absence validator (‘call`)

  • :format (Object)

    payload for the format validator (‘call`)

  • :inclusion (Object)

    payload for the inclusion validator (‘call`)

  • :exclusion (Object)

    payload for the exclusion validator (‘call`)

  • :length (Object)

    payload for the length validator (‘call`)

  • :numeric (Object)

    payload for the numeric validator (‘call`)

  • :validate (Object, Array<Object>)

    inline callable(s) (‘Validators::Validate`)

Returns:

  • (Hash{Symbol => Object})

    validator rules to run



86
87
88
89
90
91
92
# File 'lib/cmdx/validators.rb', line 86

def extract(options)
  return EMPTY_HASH if options.empty?

  rules = options.slice(*registry.keys)
  rules = rules.merge(validate: options[:validate]) if options.key?(:validate)
  rules
end

#initialize_copy(source) ⇒ void

This method returns an undefined value.

Parameters:



31
32
33
# File 'lib/cmdx/validators.rb', line 31

def initialize_copy(source)
  @registry = source.registry.dup
end

#lookup(name) ⇒ #call

Parameters:

  • name (Symbol)

Returns:

  • (#call)

Raises:

  • (ArgumentError)

    when ‘name` isn’t registered



67
68
69
70
71
# File 'lib/cmdx/validators.rb', line 67

def lookup(name)
  registry[name] || begin
    raise ArgumentError, "unknown validator: #{name}"
  end
end

#register(name, callable = nil, &block) { ... } ⇒ Validators

Registers a named validator, overwriting any existing entry.

Parameters:

  • name (Symbol)
  • callable (#call, nil) (defaults to: nil)

    pass either this or a block

  • block (#call, nil)

    validator callable when ‘callable` is omitted

Yields:

  • validator body — ‘call(value, options = {})`

Returns:

Raises:

  • (ArgumentError)

    when both ‘callable` and a block are given, or when the resolved validator isn’t callable



44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/cmdx/validators.rb', line 44

def register(name, callable = nil, &block)
  validator = callable || block

  if callable && block
    raise ArgumentError, "provide either a callable or a block, not both"
  elsif !validator.respond_to?(:call)
    raise ArgumentError, "validator must respond to #call"
  end

  registry[name.to_sym] = validator
  self
end

#sizeInteger

Returns:

  • (Integer)


100
101
102
# File 'lib/cmdx/validators.rb', line 100

def size
  registry.size
end

#validate(task, name, value, rules) ⇒ void

This method returns an undefined value.

Runs every rule against ‘value`, recording a failure message on `task.errors` under `name` for each failure. Respects `:allow_nil` and `:if`/`:unless` per-rule.

Parameters:

  • task (Task)
  • name (Symbol)

    attribute name for error reporting

  • value (Object)

    value being validated

  • rules (Hash{Symbol => Object})

    from #extract



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/cmdx/validators.rb', line 113

def validate(task, name, value, rules)
  return if rules.empty?

  rules.each do |type, raw_options|
    if type == :validate
      Array(raw_options).each do |handler|
        result = Validators::Validate.call(task, value, handler)
        task.errors.add(name, result.message) if result.is_a?(Failure)
      end
      next
    end

    options = normalize_options(raw_options)
    next if options.nil?

    next if options[:allow_nil] && value.nil?
    next unless Util.satisfied?(options[:if], options[:unless], task, value)

    result = lookup(type).call(value, options)
    next unless result.is_a?(Failure)

    task.errors.add(name, result.message)
  end
end