Releases: dry-rb/dry-struct
v1.1.1
1.1.1 2019-10-13
Changed
-
Pattern matching syntax is simplified with
deconstruct_keys
(k-tsj)User = Dry.Struct(name: 'string', email: 'string') user = User.new(name: 'John Doe', email: '[email protected]') case user in User(name: 'John Doe', email:) puts email else puts 'Not John' end
See more examples in the specs.
v1.1.0
1.1.0 2019-10-07
Added
-
Experimental support for pattern matching 🎉 (flash-gordon)
User = Dry.Struct(name: 'string', email: 'string') user = User.new(name: 'John Doe', email: '[email protected]') case user in User({ name: 'John Doe', email: }) puts email else puts 'Not John' end
See more examples in the specs.
v1.0.0
1.0.0 2019-04-23
Changed
valid?
and===
behave differently,===
works the same wayClass#===
does andvalid?
checks if the value can be coerced to the struct (flash-gordon)
Added
Struct.call
now accepts an optional block that will be called on failed coercion. This behavior is consistent with dry-types 1.0. Note that.new
doesn't take a block (flash-gordon)User = Dry::Struct(name: 'string') User.(1) { :oh_no } # => :oh_no
v0.7.0
0.7.0 2019-03-22
Changed
- [BREAKING]
Struct.input
was renamedStruct.schema
, henceStruct.schema
returns an instance ofDry::Types::Hash::Schema
rather than aHash
. Schemas are also implementingEnumerable
but they iterate over key types.
New API:To get a type by its name useUser.schema.each do |key| puts "Key name: #{ key.name }" puts "Key type: #{ key.type }" end
.key
:User.schema.key(:id) # => #<Dry::Types::Hash::Key ...>
- [BREAKING]
transform_types
now passes one argument to the block, an instance of theKey
type. Combined with the new API from dry-types it simplifies declaring omittable keys:class StructWithOptionalKeys < Dry::Struct transform_types { |key| key.required(false) } # or simply transform_types(&:omittable) end
Dry::Stuct#new
is now more efficient for partial updates (flash-gordon)- Ruby 2.3 is EOL and not officially supported. It may work but we don't test it.
v0.6.0
v0.6.0 2018-10-24
Changed
- [BREAKING]
Struct.attribute?
in the old sense is deprecated, usehas_attribute?
as a replacement
Added
-
Struct.attribute?
is an easy way to define omittable attributes (flash-gordon):class User < Dry::Struct attribute :name, Types::Strict::String attribute? :email, Types::Strict::String end # User.new(name: 'John') # => #<User name="John">
Fixed
Struct#to_h
recursively converts hash values to hashes, this was done to be consistent with current behavior for arrays (oeoeaio + ZimbiX)
v0.5.1
v0.5.1 2018-08-11
Fixed
- Constant resolution is now restricted to the current module when structs are automatically defined using the block syntax. This shouldn't break any existing code (piktur)
Added
- Pretty print extension (ojab)
Dry::Struct.load_extensions(:pretty_print) PP.pp(user) #<Test::User name="Jane", age=21, address=#<Test::Address city="NYC", zipcode="123">>
v0.5.0
v0.5.0 2018-05-03
BREAKING CHANGES
constructor_type
was removed, usetransform_types
andtransform_keys
as a replacement (see below)- Default types are evaluated only on missing values. Again, use
tranform_types
as a work around fornil
s - Values are now stored within a single instance variable names
@attributes
, this sped up struct creation and improved support for reserved attribute names such ashash
, they don't get a getter but still can be read via#[]
- Ruby 2.3 is a minimal supported version
Added
-
Dry::Struct.transform_types
accepts a block which is yielded on every type to add. Since types aredry-types
' objects that come with a robust DSL it's rather simple to restore the behavior ofconstructor_type
. See #64 for details (flash-gordon)Example: evaluate defaults on
nil
valuesclass User < Dry::Struct transform_types do |type| type.constructor { |value| value.nil? ? Undefined : value } end end
-
Data::Struct.transform_keys
accepts a block/proc that transforms keys of input hashes. The most obvious usage is simbolization but arbitrary transformations are allowed (flash-gordon) -
Dry.Struct
builds a struct by a hash of attribute names and types (citizen428)User = Dry::Struct(name: 'strict.string') do attribute :email, 'strict.string' end
-
Support for
Struct.meta
, note that.meta
returns a new class (flash-gordon)class User < Dry::Struct attribute :name, Dry::Types['strict.string'] end UserWithMeta = User.meta(foo: :bar) User.new(name: 'Jade').class == UserWithMeta.new(name: 'Jade').class # => false
-
Struct.attribute
yields a block with definition for nested structs. It defines a nested constant for the new struct and supports arrays (AMHOL + flash-gordon)class User < Dry::Struct attribute :name, Types::Strict::String attribute :address do attribute :country, Types::Strict::String attribute :city, Types::Strict::String end attribute :accounts, Types::Strict::Array do attribute :currency, Types::Strict::String attribute :balance, Types::Strict::Decimal end end # ^This automatically defines User::Address and User::Account
Fixed
- Adding a new attribute invalidates
attribute_names
(flash-gordon) - Struct classes track subclasses and define attributes in them, now it doesn't matter whether you define attributes first and then subclass or vice versa. Note this can lead to memory leaks in Rails environment when struct classes are reloaded (flash-gordon)
v0.4.0
v0.4.0 2017-11-04
Changed
- Attribute readers don't override existing instance methods (solnic)
Struct#new
uses raw attributes instead of method calls, this makes the behavior consistent with the change above (flash-gordon)constructor_type
now actively rejects:weak
and:symbolized
values (GustavoCaso)
Fixed
Struct#new
doesn't call.to_hash
recursively (flash-gordon)
v0.3.1
Added
Struct.constructor
that makes dry-struct more aligned with dry-types; now you can have a struct with a custom constructor that will be called before calling thenew
method (v-kolesnikov)Struct.attribute?
andStruct.attribute_names
for introspecting struct attributes (flash-gordon)Struct#__new__
is a safe-to-use-in-gems alias forStruct#new
(flash-gordon)
v0.3.0
Added
Dry::Struct#new
method to return new instance with applied changeset (Kukunin)
Fixed
.[]
and.call
does not coerce subclass to superclass anymore (Kukunin)- Raise ArgumentError when attribute type is a string and no value provided is for
new
(GustavoCaso)
Changed
.new
without arguments doesn't use nil as an input for non-default types anymore (flash-gordon)