Class: Grape::Validations::Types::CustomTypeCoercer

Inherits:
Object
  • Object
show all
Defined in:
lib/grape/validations/types/custom_type_coercer.rb

Overview

Instances of this class may be passed to +Virtus::Attribute.build+ as the +:coercer+ option for custom types that do not otherwise satisfy the requirements for +Virtus::Attribute::coerce+ and +Virtus::Attribute::value_coerced?+ to work as expected.

Subclasses of +Virtus::Attribute+ or +Axiom::Types::Type+ (or for which an axiom type can be inferred, i.e. the primitives, +Date+, +Time+, etc.) do not need any such coercer to be passed with them.

Coercion

This class will detect type classes that implement a class-level +parse+ method. The method should accept one +String+ argument and should return the value coerced to the appropriate type. The method may raise an exception if there are any problems parsing the string.

Alternately an optional +method+ may be supplied (see the +coerce_with+ option of Dsl::Parameters#requires). This may be any class or object implementing +parse+ or +call+, with the same contract as described above.

Type Checking

Calls to +value_coerced?+ will consult this class to check that the coerced value produced above is in fact of the expected type. By default this class performs a basic check against the type supplied, but this behaviour will be overridden if the class implements a class-level +coerced?+ or +parsed?+ method. This method will receive a single parameter that is the coerced value and should return +true+ iff the value meets type expectations. Arbitrary assertions may be made here but the grape validation system should be preferred.

Alternately a proc or other object responding to +call+ may be supplied in place of a type. This should implement the same contract as +coerced?+, and must be supplied with a coercion +method+.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(type, method = nil) ⇒ CustomTypeCoercer

A new coercer for the given type specification and coercion method.

Parameters:

  • type (Class, #coerced?, #parsed?, #call?)

    specifier for the target type. See class docs.

  • method (#parse, #call) (defaults to: nil)

    optional coercion method. See class docs.


65
66
67
68
69
70
71
# File 'lib/grape/validations/types/custom_type_coercer.rb', line 65

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

Class Method Details

.build(type, method = nil) ⇒ Virtus::Attribute

Uses +Virtus::Attribute.build+ to build a new attribute that makes use of this class for coercion and type validation logic.

Returns:

  • (Virtus::Attribute)

54
55
56
# File 'lib/grape/validations/types/custom_type_coercer.rb', line 54

def self.build(type, method = nil)
  Virtus::Attribute.build(type, coercer: new(type, method))
end

Instance Method Details

#call(value) ⇒ Object

This method is called from somewhere within +Virtus::Attribute::coerce+ in order to coerce the given value.

Parameters:

  • value (String)

    value to be coerced, in grape this should always be a string.

Returns:

  • (Object)

    the coerced result


80
81
82
# File 'lib/grape/validations/types/custom_type_coercer.rb', line 80

def call(value)
  @method.call value
end

#success?(_primitive, value) ⇒ true, false

This method is called from somewhere within +Virtus::Attribute::value_coerced?+ in order to assert that the value has been coerced successfully.

Parameters:

  • _primitive (Axiom::Types::Type)

    primitive type for the coercion as detected by axiom-types' inference system. For custom types this is typically not much use (i.e. it is +Axiom::Types::Object+) unless special inference rules have been declared for the type.

  • value (Object)

    a coerced result returned from #call

Returns:

  • (true, false)

    whether or not the coerced value satisfies type requirements.


96
97
98
# File 'lib/grape/validations/types/custom_type_coercer.rb', line 96

def success?(_primitive, value)
  @type_check.call value
end