Releases: dry-rb/dry-types
v1.4.0
1.4.0 2020-03-09
Fixed
json.nil
no longer coerces empty strings tonil
. It was a long-standing
bug that for some reason remained unnoticed for years. Technically,
this may be a breaking change for JSON schemas described with dry-schema (@flash-gordon)
v1.3.1
1.3.1 2020-02-17
Changed
- Predicate inferrer now returns
hash?
for hash schemas. Note, it doesn't spit more complex preds because we have different plans for dry-schema (@flash-gordon)
v1.3.0
Added
Schema#merge
for merging two hash schemas (@waiting-for-dev)- Aliases for
.constructor
to non-constructor types. Now you can call.prepend
/.append
without silly checks for the type being a constructor (flash-gordon)(Dry::Types['integer'].prepend(-> { _1 + 1 })).(1) # => 2 (Dry::Types['coercible.integer'] >> -> { _1 * 2 }).('99') # => 198
Hash::Schema#clear
returns a schema with the same options but without keys- Optional namespace now includes strict types by default (@flash-gordon)
Fixed
Schema::Key#optional
returns an instance ofSchema::Key
as it should have done- Composition with function handling exceptions. This could occasionally lead to unexpected exceptions (@flash-gordon)
v1.2.2
1.2.2 2019-12-14
Fixed
Types.Contructor
doesn't re-wrap class instances implementing type interface, this fixes some quirks in dry-struct (flash-gordon)
Changed
- Types now use immutable equalizers. This should improve performance in certain cases e.g. in ROM (flash-gordon)
- Attempting to use non-symbol keys in hash schemas raises an error. We always supported only symbols as keys, but there was no check, now it'll throw an argument error. If you want to convert strings to symbols, use
Hash#with_key_transform
(flash-gordon) - Params and JSON types accept Time/Date/Datetime instances and boolean values. This can be useful in tests, but we discourage you from relying on this behavior in production code. For example, building structs with
Params
types is considered a smell. There are dedicated tools for coercion, namely dry-schema and dry-validation. Be a responsible user of dry-types! ❤ (flash-gordon)
v1.2.1
1.2.1 2019-11-07
Fixed
- Fix keyword warnings reported by Ruby 2.7 (flash-gordon)
- Error type in failing case in
Array::Member
(esparta)
v1.2.0
1.2.0 2019-10-06
Changed
Dry::Types.[]
used to work with classes, now it's deprecated (flash-gordon)
Fixed
- Bug with using a
Bool
-named struct as a schema key (flash-gordon) - A bunch of issues related to using
meta
on complex types (flash-gordon) Types.Constructor(...)
returns aTypes::Array
as it should (flash-gordon)
Added
-
Optional::Params
types that coerce empty strings tonil
(flash-gordon)Dry::Types['optional.params.integer'].('') # => nil Dry::Types['optional.params.integer'].('140') # => 140 Dry::Types['optional.params.integer'].('asd') # => exception!
Keep in mind, Dry::Types['optional.params.integer'] and Dry::Types['params.integer'].optional are not the same, the latter doesn't handle empty strings.
-
Predicate inferrer was ported from dry-schema (authored by solnic)
require 'dry/types/predicate_inferrer' Dry::Types::PredicateInferrer.new[Types::String] # => [:str?] Dry::Types::PredicateInferrer.new[Types::String | Types::Integer] # => [[[:str?], [:int?]]]
Note that the API of the predicate inferrer can change in the stable version, it's dictated by the needs of dry-schema so it should be considered as semi-stable. If you depend on it, write specs covering the desired behavior. Another option is copy-and-paste the whole thing to your project.
-
Primitive inferrer was ported from dry-schema (authored by solnic)
require 'dry/types/primitive_inferrer' Dry::Types::PrimitiveInferrer.new[Types::String] # => [String] Dry::Types::PrimitiveInferrer.new[Types::String | Types::Integer] # => [String, Integer] Dry::Types::PrimitiveInferrer.new[Types::String.optional] # => [NilClass, String]
The primitive inferrer should be stable by now, you can rely on it.
-
The
monads
extension addsDry::Types::Result#to_monad
. This makes it compatible with do notation from dry-monads. Load it withDry::Types.load_extensions(:monads)
(skryukov)Types = Dry.Types Dry::Types.load_extensions(:monads) class AddTen include Dry::Monads[:result, :do] def call(input) integer = yield Types::Coercible::Integer.try(input) Success(integer + 10) end end
v1.1.1
1.1.1 2019-07-26
Fixed
- A bug where meta was lost for lax array types (flash-gordon)
v1.1.0
1.1.0 2019-07-02
Added
- New builder method
Interface
constructs a type which accepts objects that respond to the given methods (waiting-for-dev)Types = Dry.Types() Types::Callable = Types.Interface(:call) Types::Callable.valid?(Object.new) # => false Types::Callable.valid?(proc {}) # => true
- New types:
coercible.symbol
,params.symbol
, andjson.symbol
, all use.to_sym
for coercion (waiting-for-dev)
Fixed
- Converting schema keys to maybe types (flash-gordon)
- Using
Schema#key
andArray#member
on constuctors (flash-gordon) - Using
meta(omittable: true)
withintransform_types
works again but produces a warning, please migrate to.omittable
or.required(false)
(flash-gordon) - Bug with a constructor defined on top of enum (flash-gordon)
v1.0.1
1.0.1 2019-06-04
Added
- In a case of failure the constructor block can now pass a different value (flash-gordon)
not_empty_string = Types::String.constructor do |value, &failure| value.strip.empty? ? failure.(nil) : value.strip end not_empty_string.(' ') { |v| v } # => nil not_empty_string.lax.(' ') # => nil not_empty_string.lax.(' foo ') # => "foo"
Schema#strict
now accepts an boolean argument. Iffales
is passed this will turn a strict schema into a non-strict one (flash-gordon)
v1.0.0
1.0.0 2019-04-23
Changed
-
[BREAKING] Behavior of built-in constructor types was changed to be more strict. They will always raise an error on failed coercion (flash-gordon)
Compare:# 0.15.0 Types::Params::Integer.('foo') # => "foo" # 1.0.0 Types::Params::Integer.('foo') # => Dry::Types::CoercionError: invalid value for Integer(): "foo"
To handle coercion errors
Type#call
now yields a block:Types::Params::Integer.('foo') { :invalid } # => :invalid
This makes work with coercions more straightforward and way faster.
-
[BREAKING] Safe types were renamed to Lax, this name better serves their purpose. The previous name is available but prints a warning (flash-gordon)
-
[BREAKING] Metadata is now pushed down to the decorated type. It is not likely you will notice a difference but this a breaking change that enables some use cases in rom related to the usage of default types in relations (flash-gordon)
-
Nominal types are now completely unconstrained. This fixes some inconsistencies when using them with constraints.
Nominal#try
will always return a successful result, for the previous behavior useNominal#try_coerce
or switch to strict types with passing a block to#call
(flash-gordon)
Performance improvements
- During the work on this release, a lot of performance improvements were made. dry-types 1.0 combined with dry-logic 1.0 are multiple times faster than dry-types 0.15 and dry-logic 0.5 for common cases including constraints checking and coercion (flash-gordon)
Added
- API for custom constructor types was enhanced. If you pass your own callable to
.constructor
it can have a block in its signature. If a block is passed, you must call it on failed coercion, otherwise raise a type coercion error (flash-gordon)
Example:This makes the exception handling your job so that dry-types won't have to catch and re-wrap all possible errors (this is not safe, generally speaking).proc do |input, &block| if input.is_a? String Integer(input, 10) else Integer(input) end rescue ArgumentError, TypeError => error if block block.call else raise Dry::Types::CoercionError.new( error.message, backtrace: error.backtrace ) end end
- Types now can be converted to procs thus you can pass them as blocks (flash-gordon)
%w(1 2 3).map(&Types::Coercible::Integer) # => [1, 2, 3]