Module: Grape::Validations::Types::BuildCoercer

Defined in:
lib/grape/validations/types/build_coercer.rb

Class Method Summary collapse

Class Method Details

.build_coercer(type, method: nil, strict: false) ⇒ Object

Chooses the best coercer for the given type. For example, if the type is Integer, it will return a coercer which will be able to coerce a value to the integer.

There are a few very special coercers which might be returned.

Grape::Types::MultipleTypeCoercer is a coercer which is returned when the given type implies values in an array with different types. For example, [Integer, String] allows integer and string values in an array.

Grape::Types::CustomTypeCoercer is a coercer which is returned when a method is specified by a user with coerce_with option or the user specifies a custom type which implements requirments of Grape::Types::CustomTypeCoercer.

Grape::Types::CustomTypeCollectionCoercer is a very similar to the previous one, but it expects an array or set of values having a custom type implemented by the user.

There is also a group of custom types implemented by Grape, check Grape::Validations::Types::SPECIAL to get the full list.

Parameters:

  • type (Class)

    the type to which input strings should be coerced

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

    the coercion method to use

Returns:

  • (Object)

    object to be used for coercion and type validation



35
36
37
38
39
# File 'lib/grape/validations/types/build_coercer.rb', line 35

def self.build_coercer(type, method: nil, strict: false)
  cache_instance(type, method, strict) do
    create_coercer_instance(type, method, strict)
  end
end

.cache_instance(type, method, strict, &_block) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/grape/validations/types/build_coercer.rb', line 65

def self.cache_instance(type, method, strict, &_block)
  key = cache_key(type, method, strict)

  return @__cache[key] if @__cache.key?(key)

  instance = yield

  @__cache_write_lock.synchronize do
    @__cache[key] = instance
  end

  instance
end

.cache_key(type, method, strict) ⇒ Object



79
80
81
82
83
84
85
# File 'lib/grape/validations/types/build_coercer.rb', line 79

def self.cache_key(type, method, strict)
  [type, method, strict].each_with_object(+'_') do |val, memo|
    next if val.nil?

    memo << '_' << val.to_s
  end
end

.create_coercer_instance(type, method, strict) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/grape/validations/types/build_coercer.rb', line 41

def self.create_coercer_instance(type, method, strict)
  # Maps a custom type provided by Grape, it doesn't map types wrapped by collections!!!
  type = Types.map_special(type)

  # Use a special coercer for multiply-typed parameters.
  if Types.multiple?(type)
    MultipleTypeCoercer.new(type, method)

    # Use a special coercer for custom types and coercion methods.
  elsif method || Types.custom?(type)
    CustomTypeCoercer.new(type, method)

    # Special coercer for collections of types that implement a parse method.
    # CustomTypeCoercer (above) already handles such types when an explicit coercion
    # method is supplied.
  elsif Types.collection_of_custom?(type)
    Types::CustomTypeCollectionCoercer.new(
      Types.map_special(type.first), type.is_a?(Set)
    )
  else
    DryTypeCoercer.coercer_instance_for(type, strict)
  end
end