gems dry-types 0.15.0

latest releases: 1.8.3, 1.8.2, 1.8.1...
6 years ago

0.15.0 2019-03-22

Changed

  • [BREAKING] Internal representation of hash schemas was changed to be a simple list of key types (flash-gordon)
    Dry::Types::Hash#with_type_transform now yields a key type instead of type + name:
    Dry::Types['strict.hash'].with_type_transform { |key| key.name == :age ? key.required(false) : key }
  • [BREAKING] Definition types were renamed to nominal (flash-gordon)
  • [BREAKING] Top-level types returned by Dry::Types.[] are now strict (flash-gordon)
    # before
    Dry::Types['integer']
    # => #<Dry::Types[Nominal<Integer>]>
    # now
    Dry::Types['integer']
    # => <Dry::Types[Constrained<Nominal<Integer> rule=[type?(Integer)]>]>
    # you can still access nominal types using namespace
    Dry::Types['nominal.integer']
    # => #<Dry::Types[Nominal<Integer>]>
  • [BREAKING] Default values are not evaluated if the decorated type returns nil. They are triggered on Undefined instead (GustavoCaso + flash-gordon)
  • [BREAKING] Support for old hash schemas was fully removed. This makes dry-types not compatible with dry-validation < 1.0 (flash-gordon)
  • Dry::Types.module is deprecated in favor of Dry.Types (flash-gordon)
    Keep in mind Dry.Types uses strict types for top-level names, that is after
    module Types
      include Dry.Types
    end
    Types::Integer is a strict type. If you want it to be nominal, use include Dry.Types(default: :nominal). See other options below.
  • params.integer now always converts strings to decimal numbers, this means 09 will be coerced to 9 (threw an error before) (skryukov)
  • Ruby 2.3 is EOL and not officially supported. It may work but we don't test it.

Added

  • Improved string representation of types (flash-gordon)
    Dry::Types['nominal.integer']
    # => #<Dry::Types[Nominal<Integer>]>
    Dry::Types['params.integer']
    # => #<Dry::Types[Constructor<Nominal<Integer> fn=Dry::Types::Coercions::Params.to_int>]>
    Dry::Types['hash'].schema(age?: 'integer')
    # => #<Dry::Types[Constrained<Schema<keys={age?: Constrained<Nominal<Integer> rule=[type?(Integer)]>}> rule=[type?(Hash)]>]>
    Dry::Types['array<integer>']
    # => #<Dry::Types[Constrained<Array<Constrained<Nominal<Integer> rule=[type?(Integer)]>> rule=[type?(Array)]>]>
  • Options for the list of types you want to import with Dry.Types (flash-gordon)
    Cherry-pick only certain types:
    module Types
      include Dry.Types(:strict, :nominal, :coercible)
    end
    Types.constants
    # => [:Strict, :Nominal, :Coercible]
    Change default top-level types:
    module Types
      include Dry.Types(default: :coercible)
    end
    # => #<Dry::Types[Constructor<Nominal<Integer> fn=Kernel.Integer>]>
    Rename type namespaces:
    module Types
      include Dry.Types(strict: :Strong, coercible: :Kernel)
    end
  • Optional keys for schemas can be provided with ?-ending symbols (flash-gordon)
    Dry::Types['hash'].schema(name: 'string', age?: 'integer')
  • Another way of making keys optional is setting required: false to meta. In fact, it is the preferable
    way if you have to store this information in meta, otherwise use the Key's API (see below) (flash-gordon)
    Dry::Types['hash'].schema(
      name: Dry::Types['string'],
      age: Dry::Types['integer'].meta(required: false)
    )
  • Key types have API for making keys omittable and back (flash-gordon)
    # defining a base schema with optional keys
    lax_hash = Dry::Types['hash'].with_type_transform { |key| key.required(false) }
    # same as
    lax_hash = Dry::Types['hash'].with_type_transform(&:omittable)
    
    # keys in user_schema are not required
    user_schema = lax_hash.schema(name: 'string', age: 'integer')
  • Type#optional? now recognizes more cases where nil is an allowed value (flash-gordon)
  • Constructor#{prepend,append} with << and >> as aliases. Constructor#append works the same way Constructor#constrcutor does. Constuctor#prepend chains functions in the reverse order, see examples (flash-gordon)
    to_int = Types::Coercible::Integer
    inc = to_int.append { |x| x + 2 }
    inc.("1") # => "1" -> 1 -> 3
    
    inc = to_int.prepend { |x| x + "2" }
    inc.("1") # => "1" -> "12" -> 12
  • Partial schema application for cases when you want to validate only a subset of keys (flash-gordon)
    This is useful when you want to update a key or two in an already-validated hash. A perfect example is Dry::Struct#new where this feature is now used.
    schema = Dry::Types['hash'].schema(name: 'string', age: 'integer')
    value = schema.(name: 'John', age: 20)
    update = schema.apply({ age: 21 }, skip_missing: true)
    value.merge(update)

Fixed

  • Hash::Map now behaves as a constrained type if its values are constrained (flash-gordon)
  • coercible.integer now doesn't blow up on invalid strings (exterm)

Compare v0.14.0...v0.15.0

Don't miss a new dry-types release

NewReleases is sending notifications on new releases.