Module: Grape::Validations::Types
- Defined in:
- lib/grape/validations/types.rb,
lib/grape/validations/types/file.rb,
lib/grape/validations/types/json.rb,
lib/grape/validations/types/set_coercer.rb,
lib/grape/validations/types/array_coercer.rb,
lib/grape/validations/types/build_coercer.rb,
lib/grape/validations/types/invalid_value.rb,
lib/grape/validations/types/dry_type_coercer.rb,
lib/grape/validations/types/primitive_coercer.rb,
lib/grape/validations/types/custom_type_coercer.rb,
lib/grape/validations/types/multiple_type_coercer.rb,
lib/grape/validations/types/variant_collection_coercer.rb,
lib/grape/validations/types/custom_type_collection_coercer.rb
Overview
Module for code related to grape’s system for coercion and type validation of incoming request parameters.
Grape uses a number of tests and assertions to work out exactly how a parameter should be handled, based on the type
and coerce_with
options that may be supplied to Dsl::Parameters#requires and Dsl::Parameters#optional. The main entry point for this process is Types.build_coercer.
Defined Under Namespace
Classes: ArrayCoercer, CustomTypeCoercer, CustomTypeCollectionCoercer, DryTypeCoercer, File, InvalidValue, Json, JsonArray, MultipleTypeCoercer, PrimitiveCoercer, SetCoercer, VariantCollectionCoercer
Constant Summary collapse
- PRIMITIVES =
Types representing a single value, which are coerced.
[ # Numerical Integer, Float, BigDecimal, Numeric, # Date/time Date, DateTime, Time, # Misc Grape::API::Boolean, String, Symbol, TrueClass, FalseClass ].freeze
- STRUCTURES =
Types representing data structures.
[ Hash, Array, Set ].freeze
- SPECIAL =
Special custom types provided by Grape.
{ JSON => Json, Array[JSON] => JsonArray, ::File => File, Rack::Multipart::UploadedFile => File }.freeze
- GROUPS =
[ Array, Hash, JSON, Array[JSON] ].freeze
Class Method Summary collapse
-
.build_coercer(type, method: nil, strict: false) ⇒ Object
Chooses the best coercer for the given type.
- .cache_instance(type, method, strict, &_block) ⇒ Object
- .cache_key(type, method, strict) ⇒ Object
-
.collection_of_custom?(type) ⇒ Boolean
Is the declared type an
Array
orSet
of a #custom? type?. - .create_coercer_instance(type, method, strict) ⇒ Object
-
.custom?(type) ⇒ Boolean
A valid custom type must implement a class-level ‘parse` method, taking one String argument and returning the parsed value in its correct type.
-
.group?(type) ⇒ Boolean
Is the declared type a supported group type? Currently supported group types are Array, Hash, JSON, and Array.
- .map_special(type) ⇒ Object
-
.multiple?(type) ⇒ Boolean
Is the declared type in fact an array of multiple allowed types? For example the declaration types: [Integer,String] will attempt first to coerce given values to integer, but will also accept any other string.
-
.primitive?(type) ⇒ Boolean
Is the given class a primitive type as recognized by Grape?.
-
.special?(type) ⇒ Boolean
Does Grape provide special coercion and validation routines for the given class? This does not include automatic handling for primitives, structures and otherwise recognized types.
-
.structure?(type) ⇒ Boolean
Is the given class a standard data structure (collection or map) as recognized by Grape?.
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.
38 39 40 41 42 |
# File 'lib/grape/validations/types/build_coercer.rb', line 38 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
68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/grape/validations/types/build_coercer.rb', line 68 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
82 83 84 85 86 87 88 |
# File 'lib/grape/validations/types/build_coercer.rb', line 82 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 |
.collection_of_custom?(type) ⇒ Boolean
Is the declared type an Array
or Set
of a #custom? type?
137 138 139 140 141 |
# File 'lib/grape/validations/types.rb', line 137 def self.collection_of_custom?(type) (type.is_a?(Array) || type.is_a?(Set)) && type.length == 1 && (custom?(type.first) || special?(type.first)) end |
.create_coercer_instance(type, method, strict) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/grape/validations/types/build_coercer.rb', line 44 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 |
.custom?(type) ⇒ Boolean
A valid custom type must implement a class-level ‘parse` method, taking one String argument and returning the parsed value in its correct type.
124 125 126 127 128 129 130 |
# File 'lib/grape/validations/types.rb', line 124 def self.custom?(type) !primitive?(type) && !structure?(type) && !multiple?(type) && type.respond_to?(:parse) && type.method(:parse).arity == 1 end |
.group?(type) ⇒ Boolean
Is the declared type a supported group type? Currently supported group types are Array, Hash, JSON, and Array
115 116 117 |
# File 'lib/grape/validations/types.rb', line 115 def self.group?(type) GROUPS.include? type end |
.map_special(type) ⇒ Object
143 144 145 |
# File 'lib/grape/validations/types.rb', line 143 def self.map_special(type) SPECIAL.fetch(type, type) end |
.multiple?(type) ⇒ Boolean
Is the declared type in fact an array of multiple allowed types? For example the declaration types: [Integer,String] will attempt first to coerce given values to integer, but will also accept any other string.
95 96 97 |
# File 'lib/grape/validations/types.rb', line 95 def self.multiple?(type) (type.is_a?(Array) || type.is_a?(Set)) && type.size > 1 end |
.primitive?(type) ⇒ Boolean
Is the given class a primitive type as recognized by Grape?
73 74 75 |
# File 'lib/grape/validations/types.rb', line 73 def self.primitive?(type) PRIMITIVES.include?(type) end |
.special?(type) ⇒ Boolean
Does Grape provide special coercion and validation routines for the given class? This does not include automatic handling for primitives, structures and otherwise recognized types. See SPECIAL.
106 107 108 |
# File 'lib/grape/validations/types.rb', line 106 def self.special?(type) SPECIAL.key? type end |
.structure?(type) ⇒ Boolean
Is the given class a standard data structure (collection or map) as recognized by Grape?
83 84 85 |
# File 'lib/grape/validations/types.rb', line 83 def self.structure?(type) STRUCTURES.include?(type) end |