Class: Rack::Params::Context Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/params/context.rb

Overview

This class is abstract.

To subclass, provide a Result constant, and methods to do coercion/validation.

the context in which to run validation. it contains the #params and #result, and provides methods to use in coercion.

Direct Known Subclasses

ArrayContext, HashContext

Constant Summary

Result =

the structure of the result - eg. {} or []. the actual #result will be this type extended by Result

nil

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params, options = {}) ⇒ Context

create a context with a parameter hash and options.



19
20
21
22
23
24
25
26
27
28
# File 'lib/rack/params/context.rb', line 19

def initialize(params, options = {})
  @options = options
  @path    = options[:path]

  @params  = params

  @result = self.class::Result.new
  @result.extend ::Rack::Params::Result
  @result.errors = Hash.new { |h, k| h[k] = [] }
end

Instance Attribute Details

#optionsObject (readonly)

Returns the value of attribute options



10
11
12
# File 'lib/rack/params/context.rb', line 10

def options
  @options
end

#paramsObject (readonly)

Returns the value of attribute params



11
12
13
# File 'lib/rack/params/context.rb', line 11

def params
  @params
end

#resultObject (readonly)

Returns the value of attribute result



12
13
14
# File 'lib/rack/params/context.rb', line 12

def result
  @result
end

Instance Method Details

#_coerce(value, type, options) ⇒ Object (protected)

return a correctly typed value, given a string and a type.

valid types

:symbol

convert value as a symbol

:boolean

parse the following strings: “0, 1, false, f, true, t, no, n, yes, y”

Symbol
Int
Float
Date
Time
DateTime

parse as the given type.

Array

parse value as an array. default options { sep: ' ' }

Hash

parse value as a Hash, default options { esep: ',', fsep: ':' }

Parameters:

  • value

    the value to coerce, likely a string, hash or array

  • type

    the type to coerce into

  • options (Hash)

Returns:

  • value the coerced value

Raises:

  • (ArgumentError)

    if coercion fails



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/rack/params/context.rb', line 59

def _coerce(value, type, options)
  return nil   if value.nil?
  return value if value.is_a?(type) rescue false

  return value.to_sym if type == :symbol || type == Symbol

  return Integer(value, options[:base] || 0) if type == ::Integer
  return Float(value)                        if type == ::Float

  [::Date, ::Time, ::DateTime].each do |klass|
    return klass.parse(value) if type == klass
  end

  if type == ::Array
    sep    = options.fetch(:sep, ',')

    values = value.split(sep)
    return Array(values)
  end

  if type == ::Hash
    esep   = options.fetch(:esep, ',')
    fsep   = options.fetch(:fsep, ':')

    values = value.split(esep).map { |p| p.split(fsep) }
    return ::Hash[values]
  end

  if type == ::TrueClass || type == ::FalseClass || type == :boolean
    return false if /^(false|f|no|n|0)$/i === value
    return true  if /^(true|t|yes|y|1)$/i === value
    raise ArgumentError # otherwise
  end

  # default failure
  raise ArgumentError, "unknown type #{type}"
end

#_recurse(path, type, value, &block) ⇒ Result (protected)

recursively process parameters, so we can support validating nested parameter hashes and arrays.

Parameters:

  • path (String)

    the current path to the recursing object, used to provide error keys

  • type

    must be Array or Hash

Returns:

  • (Result)

    with validation results and errors



108
109
110
111
112
113
114
115
116
117
118
# File 'lib/rack/params/context.rb', line 108

def _recurse(path, type, value, &block)
  path = [@path, path].reject(&:nil?).join(".")

  if type == Array
    ArrayContext.new(value, path: path).exec(&block)
  elsif type == Hash
    HashContext.new(value, path: path).exec(&block)
  else
    fail "can not recurse into #{type}"
  end
end

#exec { ... } ⇒ Result

execute the given block, in this context

Yields:

  • in the block, self's methods are available.

Returns:

  • (Result)

    the result of this context's validation.



33
34
35
36
# File 'lib/rack/params/context.rb', line 33

def exec(&block)
  instance_exec(&block)
  @result
end