v0.13.0 2018-05-03
Changed
- [BREAKING] Renamed
Types::Form
toTypes::Params
. You can opt-in the former name withrequire 'dry/types/compat/form_types'
. It will be dropped in the next release (ndrluis) - [BREAKING] The
Int
types was renamed toInteger
, this was the only type named differently from the standard Ruby classes so it has been made consistent. The former name is available withrequire 'dry/types/compat/int'
(GustavoCaso + flash-gordon) - [BREAKING] Default types are not evaluated on
nil
. Default values are evaluated only if no value were given.This change allowed to greatly simplify hash schemas, make them a lot more flexible yet predictable (see below).type = Types::Strict::String.default("hello") type[nil] # => constraint error type[] # => "hello"
- [BREAKING]
Dry::Types.register_class
was removed,Dry::Types.register
was made private API, do not register your types in the globaldry-types
container, use a module instead, e.g.Types
(flash-gordon) - [BREAKING] Enum types don't accept value index anymore. Instead, explicit mapping is supported, see below (flash-gordon)
Added
-
Hash schemas were rewritten. The old API is still around but is going to be deprecated and removed before 1.0. The new API is simpler and more flexible. Instead of having a bunch of predefined schemas you can build your own by combining the following methods:
Schema#with_key_transform
—transforms keys of input hashes, for things like symbolizing etc.Schema#strict
—makes a schema intolerant to unknown keys.Hash#with_type_transform
—transforms member types with an arbitrary block. For instance,
optional_keys = Types::Hash.with_type_transform { |t, _key| t.optional } schema = optional_keys.schema(name: 'strict.string', age: 'strict.int') schema.(name: "Jane", age: nil) # => {name: "Jane", age: nil}
Note that by default all keys are required, if a key is expected to absent, add to the corresponding type's meta
omittable: true
:intolerant = Types::Hash.schema(name: Types::Strict::String) intolerant[{}] # => Dry::Types::MissingKeyError tolerant = Types::Hash.schema(name: Types::Strict::String.meta(omittable: true)) tolerant[{}] # => {} tolerant_with_default = Types::Hash.schema(name: Types::Strict::String.meta(omittable: true).default("John")) tolerant[{}] # => {name: "John"}
The new API is composable in a natural way:
TOLERANT = Types::Hash.with_type_transform { |t| t.meta(omittable: true) }.freeze user = TOLERANT.schema(name: 'strict.string', age: 'strict.int') user.(name: "Jane") # => {name: "Jane"} TOLERANT_SYMBOLIZED = TOLERANT.with_key_transform(&:to_sym) user_sym = TOLERANT_SYMBOLIZED.schema(name: 'strict.string', age: 'strict.int') user_sym.("name" => "Jane") # => {name: "Jane"}
(flash-gordon)
-
Types.Strict
is an alias forTypes.Instance
(flash-gordon)strict_range = Types.Strict(Range) strict_range == Types.Instance(Range) # => true
-
Enum#include?
is an alias toEnum#valud?
(d-Pixie + flash-gordon) -
Range
was added (GustavoCaso) -
Array
types filter outUndefined
values, if you have an array type with a constructor type as its member, the constructor now can returnDry::Types::Undefined
to indicate empty value:filter_empty_strings = Types::Strict::Array.of( Types::Strict::String.constructor { |input| input.to_s.yield_self { |s| s.empty? ? Dry::Types::Undefined : s } } ) filter_empty_strings.(["John", nil, "", "Jane"]) # => ["John", "Jane"]
-
Types::Map
was added for homogeneous hashes, when only types of keys and values are known in advance, not specific key names (fledman + flash-gordon)int_to_string = Types::Hash.map('strict.integer', 'strict.string') int_to_string[0 => 'foo'] # => { 0 => "foo" } int_to_string[0 => 1] # Dry::Types::MapError: input value 1 for key 0 is invalid: type?(String, 1)
-
Enum supports mappings (bolshakov + flash-gordon)
dict = Types::Strict::String.enum('draft' => 0, 'published' => 10, 'archived' => 20) dict['published'] # => 'published' dict[10] # => 'published'
Fixed
- Fixed applying constraints to optional type, i.e.
.optional.constrained
works correctly (flash-gordon) - Fixed enum working with optionals (flash-gordon)
Internal
- Dropped the
dry-configurable
dependency (GustavoCaso) - The gem now uses
dry-inflector
for inflections instead ofinflecto
(GustavoCaso)