-
-
Notifications
You must be signed in to change notification settings - Fork 62
/
changelog.yml
322 lines (302 loc) · 11.5 KB
/
changelog.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
---
- version: unreleased
summary:
date:
fixed:
added:
changed:
- 'Missing attribute error now includes the name of the class (issue #170 via #191)
(@phillipoertel + @cllns)'
- version: 1.6.0
date: 2022-11-04
changed:
- This version uses dry-core 1.0 (@flash-gordon + @solnic)
- version: 1.5.2
date: '2022-10-19'
fixed:
- Coercion failures keep the original error instead of just having a string (@flash-gordon
+ @newx)
- version: 1.5.1
date: '2022-10-17'
fixed:
- 'Fixed issues with auto-loading `Extensions` module (issue #183 fixed via #184)
(@solnic)'
- version: 1.5.0
date: '2022-10-15'
added:
changed:
- Use zeitwerk for auto-loading (@flash-gordon)
- version: 1.4.0
date: '2021-01-21'
added:
- Support for wrapping constructors and fallbacks, see release notes for dry-types
1.5.0 (@flash-gordon)
- |-
Improvements of the attribute DSL, now it's possible to use optional structs as a base class (@flash-gordon)
```ruby
class User < Dry::Struct
attribute :name, Types::String
attribute :address, Dry::Struct.optional do
attribute :city, Types::String
end
end
User.new(name: "John", address: nil) # => #<User name="John" address=nil>
```
- version: 1.3.0
date: '2020-02-10'
added:
- |-
Nested structures will reuse type and key transformations from the enclosing struct (@flash-gordon)
```ruby
class User < Dry::Struct
transform_keys(&:to_sym)
attribute :name, Types::String
attribute :address do
# this struct will inherit transform_keys(&:to_sym)
attribute :city, Types::String
end
# nested struct will _not_ transform keys because a parent
# struct is given
attribute :contacts, Dry::Struct do
attribute :email, Types::String
end
end
```
- "`Dry::Struct::Constructor` finally acts like a fully-featured type (@flash-gordon)"
- "`Dry::Struct.abstract` declares a struct class as abstract. An abstract class
is used as a default superclass for nested structs (@flash-gordon)"
- "`Dry::Struct.to_ast` and struct compiler (@flash-gordon)"
- |-
Struct composition with `Dry::Struct.attributes_from`. It's more flexible than inheritance (@waiting-for-dev + @flash-gordon)
```ruby
class Address < Dry::Struct
attribute :city, Types::String
attribute :zipcode, Types::String
end
class Buyer < Dry::Struct
attribute :name, Types::String
attributes_from Address
end
class Seller < Dry::Struct
attribute :name, Types::String
attribute :email, Types::String
attributes_from Address
end
```
changed:
- "[internal] metadata is now stored inside schema (@flash-gordon)"
- version: 1.2.0
date: '2019-12-20'
changed:
- "`Dry::Struct::Value` is deprecated. `Dry::Struct` instances were never meant
to be mutable, we have no support for this. The only difference between `Dry::Struct`
and `Dry::Struct::Value` is that the latter is deeply frozen. Freezing objects
slows the code down and gives you very little benefit in return. If you have a
use case for `Value`, it won't be hard to roll your own solution using [ice_nine](https://github.com/dkubb/ice_nine)
(flash-gordon)"
- In the thread of the previous change, structs now use immutable equalizer. This
means `Struct#hash` memoizes its value after the first invocation. Depending on
the case, this may speed up your code significantly (flash-gordon)
- version: 1.1.1
date: '2019-10-13'
changed:
- |-
Pattern matching syntax is simplified with `deconstruct_keys` (k-tsj)
```ruby
User = Dry.Struct(name: 'string', email: 'string')
user = User.new(name: 'John Doe', email: 'john@acme.org')
case user
in User(name: 'John Doe', email:)
puts email
else
puts 'Not John'
end
```
See more examples in the [specs](https://github.com/dry-rb/dry-struct/blob/8112772eb08d22ff2cd3e6997514d79a9b124968/spec/dry/struct/pattern_matching_spec.rb).
- version: 1.1.0
date: '2019-10-07'
added:
- 'Experimental support for pattern matching :tada: (flash-gordon)'
- version: 1.0.0
date: '2019-04-23'
changed:
- "`valid?` and `===` behave differently, `===` works the same way `Class#===` does
and `valid?` 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)
```ruby
User = Dry::Struct(name: 'string')
User.(1) { :oh_no }
# => :oh_no
```
- version: 0.7.0
date: '2019-03-22'
changed:
- |-
[BREAKING] `Struct.input` was renamed `Struct.schema`, hence `Struct.schema` returns an instance of `Dry::Types::Hash::Schema` rather than a `Hash`. Schemas are also implementing `Enumerable` but they iterate over key types.
New API:
```ruby
User.schema.each do |key|
puts "Key name: #{ key.name }"
puts "Key type: #{ key.type }"
end
```
To get a type by its name use `.key`:
```ruby
User.schema.key(:id) # => #<Dry::Types::Hash::Key ...>
```
- |-
[BREAKING] `transform_types` now passes one argument to the block, an instance of the `Key` type. Combined with the new API from dry-types it simplifies declaring omittable keys:
```ruby
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.
- version: 0.6.0
date: '2018-10-24'
changed:
- "[BREAKING] `Struct.attribute?` in the old sense is deprecated, use `has_attribute?`
as a replacement"
added:
- |-
`Struct.attribute?` is an easy way to define omittable attributes (flash-gordon):
```ruby
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)"
- version: 0.5.1
date: '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)
```ruby
Dry::Struct.load_extensions(:pretty_print)
PP.pp(user)
#<Test::User
name="Jane",
age=21,
address=#<Test::Address city="NYC", zipcode="123">>
```
- version: 0.5.0
date: '2018-05-03'
added:
- |-
`Dry::Struct.transform_types` accepts a block which is yielded on every type to add. Since types are `dry-types`' objects that come with a robust DSL it's rather simple to restore the behavior of `constructor_type`. See https://github.com/dry-rb/dry-struct/pull/64 for details (flash-gordon)
Example: evaluate defaults on `nil` values
```ruby
class 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)
```ruby
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)
```ruby
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)
```ruby
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)
- version: 0.4.0
date: '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)"
- version: 0.3.1
date: '2017-06-30'
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
the `new` method (v-kolesnikov)"
- "`Struct.attribute?` and `Struct.attribute_names` for introspecting struct attributes
(flash-gordon)"
- "`Struct#__new__` is a safe-to-use-in-gems alias for `Struct#new` (flash-gordon)"
- version: 0.3.0
date: '2017-05-05'
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)"
- version: 0.2.1
date: '2017-02-27'
fixed:
- Fixed `Dry::Struct::Value` which appeared to be broken in the last release (flash-gordon)
- version: 0.2.0
date: '2016-02-26'
changed:
- Struct attributes can be overridden in a subclass (flash-gordon)
- version: 0.1.1
date: '2016-11-13'
fixed:
- Make `Dry::Struct` act as a constrained type. This fixes the behavior of sum types
containing structs (flash-gordon)
- version: 0.1.0
date: '2016-09-21'
added:
- "`:strict_with_defaults` constructor type (backus)"
changed:
- "[BREAKING] `:strict` was renamed to `:permissive` as it ignores missing keys
(backus)"
- "[BREAKING] `:strict` now raises on unexpected keys (backus)"
- Structs no longer auto-register themselves in the types container as they implement
`Type` interface and we don't have to wrap them in `Type::Definition` (flash-gordon)
- version: 0.0.1
date: '2016-07-17'
summary: Initial release of code imported from dry-types