class Grape::Validations::Types::CustomTypeCoercer
method
.
contract as coerced?
, and must be supplied with a coercion
supplied in place of a type. This should implement the same
Alternately a proc or other object responding to call
may be
system should be preferred.
Arbitrary assertions may be made here but the grape validation
and should return true
if the value meets type expectations.
will receive a single parameter that is the coerced valuecoerced?
or parsed?
method. This method
overridden if the class implements a class-level
against the type supplied, but this behaviour will be
expected type. By default this class performs a basic check
that the coerced value produced above is in fact of the
Calls to coerced?
will consult this class to check
————-
Type Checking
with the same contract as described above.
This may be any class or object implementing parse
or call
,coerce_with
option of {Grape::Dsl::Parameters#requires}).
Alternately an optional method
may be supplied (see the
there are any problems parsing the string.
the appropriate type. The method may raise an exception ifString
argument and should return the value coerced to
a class-level parse
method. The method should accept one
This class will detect type classes that implement
def call(val)
-
(Object)
- the coerced result
Parameters:
-
value
(String
) -- value to be coerced, in grape
def call(val) coerced_val = @method.call(val) return coerced_val if coerced_val.is_a?(InvalidValue) return InvalidValue.new unless coerced?(coerced_val) coerced_val end
def coerced?(val)
def coerced?(val) val.nil? || @type_check.call(val) end
def enforce_symbolized_keys(type, method)
-
(#call)
- +method+ wrapped in an additional
Parameters:
-
method
() -- see #infer_coercion_method
-
type
() -- see #new
def enforce_symbolized_keys(type, method) # Collections have all values processed individually if [Array, Set].include?(type) lambda do |val| method.call(val).tap do |new_val| new_val.map do |item| item.is_a?(Hash) ? item.deep_symbolize_keys : item end end end # Hash objects are processed directly elsif type == Hash lambda do |val| method.call(val).deep_symbolize_keys end # Simple types are not processed. # This includes Array<primitive> types. else method end end
def infer_coercion_method(type, method)
-
(#call)
- coercion method
Parameters:
-
method
() -- see #new
-
type
() -- see #new
def infer_coercion_method(type, method) if method if method.respond_to? :parse method.method :parse else method end else # Try to use parse() declared on the target type. # This may raise an exception, but we are out of ideas anyway. type.method :parse end end
def infer_type_check(type)
-
(#call)
- a procedure which accepts a single parameter
Parameters:
-
type
() -- see #new
def infer_type_check(type) # First check for special class methods if type.respond_to? :coerced? type.method :coerced? elsif type.respond_to? :parsed? type.method :parsed? elsif type.respond_to? :call # Arbitrary proc passed for type validation. # Note that this will fail unless a method is also # passed, or if the type also implements a parse() method. type elsif type.is_a?(Enumerable) lambda do |value| value.is_a?(Enumerable) && value.all? do |val| recursive_type_check(type.first, val) end end else # By default, do a simple type check ->(value) { value.is_a? type } end end
def initialize(type, method = nil)
-
method
(#parse, #call
) -- -
type
(Class, #coerced?, #parsed?, #call?
) --
def initialize(type, method = nil) coercion_method = infer_coercion_method type, method @method = enforce_symbolized_keys type, coercion_method @type_check = infer_type_check(type) end
def recursive_type_check(type, value)
def recursive_type_check(type, value) if type.is_a?(Enumerable) && value.is_a?(Enumerable) value.all? { |val| recursive_type_check(type.first, val) } else !type.is_a?(Enumerable) && value.is_a?(type) end end