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.callnow accepts an optional block that will be called on failed coercion. This behavior is consistent with dry-types 1.0. Note that.newdoesn'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.inputwas renamedStruct.schema, henceStruct.schemareturns an instance ofDry::Types::Hash::Schemarather than aHash. Schemas are also implementingEnumerablebut 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_typesnow passes one argument to the block, an instance of theKeytype. 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#newis 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_hrecursively 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_typewas removed, usetransform_typesandtransform_keysas a replacement (see below)- Default types are evaluated only on missing values. Again, use 
tranform_typesas a work around fornils - 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_typesaccepts 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
nilvaluesclass User < Dry::Struct transform_types do |type| type.constructor { |value| value.nil? ? Undefined : value } end end
 - 
Data::Struct.transform_keysaccepts a block/proc that transforms keys of input hashes. The most obvious usage is simbolization but arbitrary transformations are allowed (flash-gordon) - 
Dry.Structbuilds 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.metareturns 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.attributeyields 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#newuses raw attributes instead of method calls, this makes the behavior consistent with the change above (flash-gordon)constructor_typenow actively rejects:weakand:symbolizedvalues (GustavoCaso)
Fixed
Struct#newdoesn't call.to_hashrecursively (flash-gordon)
v0.3.1
Added
Struct.constructorthat makes dry-struct more aligned with dry-types; now you can have a struct with a custom constructor that will be called before calling thenewmethod (v-kolesnikov)Struct.attribute?andStruct.attribute_namesfor 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#newmethod to return new instance with applied changeset (Kukunin)
Fixed
.[]and.calldoes not coerce subclass to superclass anymore (Kukunin)- Raise ArgumentError when attribute type is a string and no value provided is for 
new(GustavoCaso) 
Changed
.newwithout arguments doesn't use nil as an input for non-default types anymore (flash-gordon)