class ServiceOperation::Params::Attribute

Represents a single attribute of a value class

Constants

COERCIONS
EXPANDABLE_VALIDATORS

Types of validation classes that can be expanded

OPTIONS
PARAM_COERCIONS

Typical coercions from web/string parameters

Attributes

coercer[R]

Instance Methods

default[R]

Instance Methods

log[R]

Instance Methods

name[R]

Instance Methods

optional[R]

Instance Methods

options[R]

Instance Methods

validator[R]

Instance Methods

Public Class Methods

define(*args) click to toggle source
# File lib/service_operation/params/attribute.rb, line 45
def define(*args)
  options = extract_options(args)
  name, validator = args
  validator ||= Anything

  raise "#{name.inspect} is a keyword" if KEYWORDS.include?(name)

  if EXPANDABLE_VALIDATORS.include?(validator.class.name)
    validator = expand_validator(validator)
    options[:coerce] = COERCIONS[validator.name] || true if options[:coerce].nil?
  end

  # options[:coerce] = COERCIONS[validator.name] || options[:coerce]
  options[:coercer] = options.delete(:coerce)

  new options.merge(name: name, validator: validator)
end
new(options = {}) click to toggle source
# File lib/service_operation/params/attribute.rb, line 100
def initialize(options = {})
  @name = options[:name].to_sym
  @validator  = options[:validator]
  @coercer    = options[:coercer]
  @default    = options[:default]
  @log        = options.fetch(:log) { true }
  @optional   = options.fetch(:optional) { false }
  @options    = options.reject { |k, _v| OPTIONS.include?(k) }

  freeze
end

Private Class Methods

camelize(string, uppercase_first_letter = true) click to toggle source

activesupport/lib/active_support/inflector/methods.rb rubocop:disable all

# File lib/service_operation/params/attribute.rb, line 67
def camelize(string, uppercase_first_letter = true)
  if uppercase_first_letter
    string = string.sub(/^[a-z\d]*/) { $&.capitalize }
  else
    string = string.sub(/^(?:(?=\b|[A-Z_])|\w)/) { $&.downcase }
  end
  string.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }.gsub('/', '::')
end
expand_validator(validator) click to toggle source

rubocop:enable all

# File lib/service_operation/params/attribute.rb, line 77
def expand_validator(validator)
  case validator
  when Array
    EnumerableOf.new(*validator.map { |v| expand_validator(v) })
  when Symbol, String
    validator = 'bool' if validator.to_s == 'boolean'
    Params.const_get camelize(validator.to_s)
  else
    validator
  end
end
extract_options(args) click to toggle source
# File lib/service_operation/params/attribute.rb, line 89
def extract_options(args)
  args.last.is_a?(Hash) ? args.pop : {}
end

Public Instance Methods

==(other) click to toggle source
# File lib/service_operation/params/attribute.rb, line 112
def ==(other)
  name == other.name
end
error(value) click to toggle source
# File lib/service_operation/params/attribute.rb, line 121
def error(value)
  return if validate?(value)

  if required? && value.nil?
    "can't be blank"
  else
    "must be typecast '#{validator.name}'"
  end
end
from(raw_value, klass = nil) click to toggle source
# File lib/service_operation/params/attribute.rb, line 116
def from(raw_value, klass = nil)
  raw_value = (default.respond_to?(:call) ? default.call : default) if raw_value.nil?
  coerce(raw_value, klass)
end
optional?() click to toggle source
# File lib/service_operation/params/attribute.rb, line 131
def optional?
  optional == true
end
required?() click to toggle source
# File lib/service_operation/params/attribute.rb, line 135
def required?
  !optional
end
validate?(value) click to toggle source
# File lib/service_operation/params/attribute.rb, line 139
def validate?(value)
  # special exception to prevent Object === nil from validating
  return false if value.nil? && !optional

  optional || validator === value # rubocop:disable Style/CaseEquality
end

Private Instance Methods

coerce(value, klass) click to toggle source
# File lib/service_operation/params/attribute.rb, line 148
def coerce(value, klass)
  return value unless coercer && !value.nil? # coercion not enabled or value was nil
  return klass.public_send(coercion_method, value) if klass.respond_to?(coercion_method)

  if coercer.respond_to?(:call)
    coercer.call value
  else
    value
  end
end
coercion_method() click to toggle source
# File lib/service_operation/params/attribute.rb, line 159
def coercion_method
  "coerce_#{name}"
end