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.

Direct Known Subclasses

CustomTypeCollectionCoercer

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