u-struct 0.11.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +5 -5
  3. data/.rubocop.yml +129 -0
  4. data/.rubocop_todo.yml +10 -0
  5. data/.tool-versions +1 -0
  6. data/CHANGELOG.md +558 -13
  7. data/Gemfile +14 -3
  8. data/README.md +682 -16
  9. data/Rakefile +5 -5
  10. data/bin/console +3 -3
  11. data/bin/prepare_coverage +7 -9
  12. data/bin/run_ci +17 -0
  13. data/bin/tapioca +28 -0
  14. data/examples/rgb/number.rb +1 -1
  15. data/examples/rgb_1.rb +7 -6
  16. data/examples/rgb_2.rb +2 -2
  17. data/examples/rgb_3.rb +1 -1
  18. data/lib/micro/struct/factory/create_struct.rb +95 -69
  19. data/lib/micro/struct/factory/members.rb +1 -0
  20. data/lib/micro/struct/factory.rb +13 -4
  21. data/lib/micro/struct/features.rb +35 -16
  22. data/lib/micro/struct/normalize_names.rb +4 -3
  23. data/lib/micro/struct/version.rb +2 -1
  24. data/lib/micro/struct.rb +37 -5
  25. data/lib/u-struct.rb +2 -0
  26. data/rbi/micro/struct/factory/create_struct.rbi +60 -0
  27. data/rbi/micro/struct/factory/members.rbi +67 -0
  28. data/rbi/micro/struct/factory.rbi +41 -0
  29. data/rbi/micro/struct/features.rbi +41 -0
  30. data/rbi/micro/struct/normalize_names.rbi +20 -0
  31. data/rbi/micro/struct/version.rbi +3 -0
  32. data/rbi/micro/struct.rbi +68 -0
  33. data/sorbet/config +8 -0
  34. data/sorbet/rbi/gems/ast@2.4.2.rbi +54 -0
  35. data/sorbet/rbi/gems/coderay@1.1.3.rbi +8 -0
  36. data/sorbet/rbi/gems/diff-lcs@1.5.0.rbi +11 -0
  37. data/sorbet/rbi/gems/docile@1.4.0.rbi +54 -0
  38. data/sorbet/rbi/gems/method_source@1.0.0.rbi +8 -0
  39. data/sorbet/rbi/gems/minitest@5.15.0.rbi +345 -0
  40. data/sorbet/rbi/gems/parser@3.1.0.0.rbi +1196 -0
  41. data/sorbet/rbi/gems/pry@0.14.1.rbi +8 -0
  42. data/sorbet/rbi/gems/rake@13.0.6.rbi +806 -0
  43. data/sorbet/rbi/gems/rbi@0.0.9.rbi +1602 -0
  44. data/sorbet/rbi/gems/simplecov-html@0.12.3.rbi +89 -0
  45. data/sorbet/rbi/gems/simplecov@0.21.2.rbi +577 -0
  46. data/sorbet/rbi/gems/simplecov_json_formatter@0.1.3.rbi +8 -0
  47. data/sorbet/rbi/gems/spoom@1.1.8.rbi +1252 -0
  48. data/sorbet/rbi/gems/tapioca@0.6.2.rbi +1232 -0
  49. data/sorbet/rbi/gems/thor@1.2.1.rbi +844 -0
  50. data/sorbet/rbi/gems/unparser@0.6.3.rbi +8 -0
  51. data/sorbet/rbi/gems/webrick@1.7.0.rbi +601 -0
  52. data/sorbet/rbi/gems/yard-sorbet@0.6.1.rbi +199 -0
  53. data/sorbet/rbi/gems/yard@0.9.27.rbi +4112 -0
  54. data/sorbet/tapioca/config.yml +13 -0
  55. data/sorbet/tapioca/require.rb +4 -0
  56. data/u-struct.gemspec +3 -3
  57. metadata +38 -4
  58. data/bin/test +0 -8
data/CHANGELOG.md CHANGED
@@ -1,45 +1,590 @@
1
+ # Changelog <!-- omit in toc -->
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ - [[Unreleased]](#unreleased)
9
+ - [[1.1.0] - 2021-03-23](#110---2021-03-23)
10
+ - [Added](#added)
11
+ - [[1.0.0] - 2021-01-19](#100---2021-01-19)
12
+ - [[0.12.0] - 2021-12-22](#0120---2021-12-22)
13
+ - [Added](#added-1)
14
+ - [[0.11.0] - 2021-12-19](#0110---2021-12-19)
15
+ - [Added](#added-2)
16
+ - [[0.10.0] - 2021-12-15](#0100---2021-12-15)
17
+ - [Changed](#changed)
18
+ - [[0.9.0] - 2021-12-14](#090---2021-12-14)
19
+ - [Added](#added-3)
20
+ - [Changed](#changed-1)
21
+ - [[0.8.0] - 2021-12-05](#080---2021-12-05)
22
+ - [Added](#added-4)
23
+ - [[0.7.0] - 2021-12-04](#070---2021-12-04)
24
+ - [Added](#added-5)
25
+ - [Changed](#changed-2)
26
+ - [[0.6.0] - 2021-12-03](#060---2021-12-03)
27
+ - [Added](#added-6)
28
+ - [[0.5.0] - 2021-12-02](#050---2021-12-02)
29
+ - [Added](#added-7)
30
+ - [[0.4.0] - 2021-12-02](#040---2021-12-02)
31
+ - [Added](#added-8)
32
+ - [[0.3.1] - 2021-12-02](#031---2021-12-02)
33
+ - [Fixed](#fixed)
34
+ - [[0.3.0] - 2021-12-02](#030---2021-12-02)
35
+ - [Added](#added-9)
36
+ - [[0.2.0] - 2021-12-02](#020---2021-12-02)
37
+ - [Added](#added-10)
38
+ - [[0.1.0] - 2021-12-02](#010---2021-12-02)
39
+ - [Added](#added-11)
1
40
  ## [Unreleased]
2
41
 
42
+ [Diff](https://github.com/serradura/u-struct/compare/v1.1.0...main)
43
+
44
+ ## [1.1.0] - 2021-03-23
45
+
46
+ [Diff](https://github.com/serradura/u-struct/compare/v1.0.0...v1.1.0) | [Tag](https://github.com/serradura/u-struct/tree/v1.1.0)
47
+ ### Added
48
+
49
+ - Add `Micro::Struct[]` as an alias of `Micro::Struct.with`.
50
+ ```ruby
51
+ Micro::Struct[:readonly] # is the same as Micro::Struct.with(:readonly)
52
+ ```
53
+
54
+ - Add `Micro::Struct.immutable` method as a shortcut to `Micro::Struct.with(:readonly, :instance_copy)`.
55
+ It also accepts the `with:` option, which can be used to define additional features.
56
+ ```ruby
57
+ Micro::Struct.immutable.new(:name)
58
+
59
+ Micro::Struct.immutable.new(:name) do
60
+ def hi(other_name)
61
+ "Hi, #{other_name}! My name is #{name}"
62
+ end
63
+ end
64
+
65
+ Micro::Struct.immutable(with: :to_hash).new(:name)
66
+
67
+ Micro::Struct.immutable(with: [:to_hash, :to_proc]).new(:name)
68
+
69
+ Micro::Struct.immutable.instance(name: 'Rodrigo')
70
+
71
+ Micro::Struct.immutable(with: [:to_hash]).instance(name: 'Serradura')
72
+ ```
73
+
74
+ - Add `Micro::Struct.readonly` method as a shortcut to `Micro::Struct.with(:readonly)`.
75
+ It has the same properties of `Micro::Struct.immutable`.
76
+ ```ruby
77
+ Micro::Struct.readonly.new(:name)
78
+
79
+ Micro::Struct.readonly.new(:name) do
80
+ def hi(other_name)
81
+ "Hi, #{other_name}! My name is #{name}"
82
+ end
83
+ end
84
+
85
+ Micro::Struct.readonly(with: :to_hash).new(:name)
86
+
87
+ Micro::Struct.readonly(with: [:to_hash, :to_proc]).new(:name)
88
+
89
+ Micro::Struct.readonly.instance(name: 'Rodrigo')
90
+
91
+ Micro::Struct.readonly(with: [:to_hash]).instance(name: 'Serradura')
92
+ ```
93
+ **Development stuff**
94
+
95
+ - Set up Rubocop.
96
+ - Add `.rbi` files, and set up sorbet to be used in development.
97
+
98
+ <p align="right">(<a href="#changelog-">⬆️ &nbsp;back to top</a>)</p>
99
+
100
+ <p align="right">(<a href="#changelog-">⬆️ &nbsp;back to top</a>)</p>
101
+
102
+ ## [1.0.0] - 2021-01-19
103
+
104
+ [Diff](https://github.com/serradura/u-struct/compare/v0.12.0...v1.0.0) | [Tag](https://github.com/serradura/u-struct/tree/v1.0.0)
105
+
106
+ - Review and update docs and examples. ;)
107
+
108
+ <p align="right">(<a href="#changelog-">⬆️ &nbsp;back to top</a>)</p>
109
+
110
+ ## [0.12.0] - 2021-12-22
111
+
112
+ [Diff](https://github.com/serradura/u-struct/compare/v0.11.0...v0.12.0) | [Tag](https://github.com/serradura/u-struct/tree/v0.12.0)
113
+
114
+ ### Added
115
+
116
+ - Add `Micro::Struct.instance` to create a struct instance from a given hash.
117
+ This could be useful to create constants or a singleton value.
118
+
119
+ ```ruby
120
+ person1 = Micro::Struct.instance(first_name: 'Rodrigo', last_name: 'Serradura')
121
+ # => #<struct first_name="Rodrigo", last_name="Serradura">
122
+
123
+ person1.first_name = 'John'
124
+
125
+ person1.first_name # => "John"
126
+ ```
127
+
128
+ You can use the instance method after defining some struct feature.
129
+
130
+ ```ruby
131
+ person2 = Micro::Struct.with(:readonly).instance(first_name: 'Rodrigo', last_name: 'Serradura')
132
+ # => #<struct first_name="Rodrigo", last_name="Serradura">
133
+
134
+ person2.first_name = 'John'
135
+ # NoMethodError (private method `first_name=' called for #<struct first_name="Rodrigo", last_name="Serradura">)
136
+ ```
137
+ You can use pass a block to define some custom behavior to the struct instance.
138
+
139
+ ```ruby
140
+ person3 = Micro::Struct.instance(first_name: 'Rodrigo', last_name: 'Serradura') do
141
+ def name
142
+ "#{first_name} #{last_name}"
143
+ end
144
+ end
145
+
146
+ person4 = Micro::Struct.with(:readonly).instance(first_name: 'Rodrigo', last_name: 'Serradura') do
147
+ def name
148
+ "#{first_name} #{last_name}"
149
+ end
150
+ end
151
+
152
+ person3.name # => "Rodrigo Serradura"
153
+ person4.name # => "Rodrigo Serradura"
154
+ ```
155
+
156
+ - Add `Micro::Struct.with(:exposed_features)` to expose the struct's configured features.
157
+ Via the methods: `.features` and `.__features__`.
158
+
159
+ ```ruby
160
+ Person = Micro::Struct.with(:exposed_features, :readonly, :to_proc).new(:name)
161
+
162
+ Person.features
163
+ # => #<struct Micro::Struct::Features::Exposed
164
+ # names=[:readonly, :to_proc],
165
+ # options={:to_ary=>false, :to_hash=>false, :to_proc=>true, :readonly=>true, :instance_copy=>false}>
166
+
167
+ Person.__features__.equal?(Person.features) # `.__features__` is an alias of `.features` method
168
+
169
+ Person.features.names # => [:readonly, :to_proc]
170
+ Person.features.options # => {:to_ary=>false, :to_hash=>false, :to_proc=>true, :readonly=>true, :instance_copy=>false}
171
+
172
+ Person.features.option?(:to_proc) # => true
173
+ Person.features.option?(:readonly) # => true
174
+
175
+ Person.features.options?(:to_proc) # => true
176
+ Person.features.options?(:readonly) # => true
177
+
178
+ Person.features.options?(:to_proc, :readonly) # => true
179
+ Person.features.options?(:to_ary, :readonly) # => false
180
+ ```
181
+
182
+ <p align="right">(<a href="#changelog-">⬆️ &nbsp;back to top</a>)</p>
183
+
184
+ ## [0.11.0] - 2021-12-19
185
+
186
+ [Diff](https://github.com/serradura/u-struct/compare/v0.10.0...v0.11.0) | [Tag](https://github.com/serradura/u-struct/tree/v0.11.0)
187
+
188
+ ### Added
189
+
190
+ - Reduce the required Ruby version to `>= 2.2.0`.
191
+ - Set up a CI with Github actions.
192
+ - Test the codebase against the Ruby versions: `2.2`, `2.3`, `2.4`, `2.5`, `2.6`, `2.7`, `3.0` and `3.1.0-preview1`.
193
+
194
+ <p align="right">(<a href="#changelog-">⬆️ &nbsp;back to top</a>)</p>
195
+
3
196
  ## [0.10.0] - 2021-12-15
4
197
 
5
- - To-do
198
+ [Diff](https://github.com/serradura/u-struct/compare/v0.9.0...v0.10.0) | [Tag](https://github.com/serradura/u-struct/tree/v0.10.0)
199
+
200
+ ### Changed
201
+
202
+ - Make `Micro::Struct.new` return a Ruby struct instead of a module.
203
+
204
+ ```ruby
205
+ module RGB
206
+ Number = ::Struct.new(:value) { def to_s; '%02x' % value; end }
207
+
208
+ Color = Micro::Struct.new(:red, :green, :blue) do
209
+ def self.new(r, g, b)
210
+ __new__(
211
+ red: Number.new(r),
212
+ green: Number.new(g),
213
+ blue: Number.new(b),
214
+ )
215
+ end
216
+
217
+ def to_hex
218
+ "##{red}#{green}#{blue}"
219
+ end
220
+ end
221
+ end
222
+
223
+ rgb_color = RGB::Color.new(1,5,255)
224
+ # => #<struct RGB::Color red=#<struct RGB::Number value=1>, green=#<struct RGB::Number value=5>, blue=#<struct RGB::Number value=255>>
225
+
226
+ rgb_color.to_hex
227
+ # => "#0105ff"
228
+ ```
229
+
230
+ <p align="right">(<a href="#changelog-">⬆️ &nbsp;back to top</a>)</p>
6
231
 
7
232
  ## [0.9.0] - 2021-12-14
8
233
 
9
- - To-do
234
+ [Diff](https://github.com/serradura/u-struct/compare/v0.8.0...v0.9.0) | [Tag](https://github.com/serradura/u-struct/tree/v0.9.0)
235
+
236
+ ### Added
237
+
238
+ - Add `__new__` method and make `.new` its alias. You can use `__new__` when overwriting the module's `new`.
239
+
240
+ ```ruby
241
+ module RGB
242
+ Number = ::Struct.new(:value) { def to_s; '%02x' % value; end }
243
+
244
+ Color = Micro::Struct.new(:red, :green, :blue) do
245
+ def to_hex
246
+ "##{red}#{green}#{blue}"
247
+ end
248
+ end
249
+
250
+ module Color
251
+ def self.new(r, g, b)
252
+ __new__(
253
+ red: Number.new(r),
254
+ green: Number.new(g),
255
+ blue: Number.new(b),
256
+ )
257
+ end
258
+ end
259
+ end
260
+
261
+ rgb_color = RGB::Color.new(1,5,255)
262
+ # => #<struct RGB::Color::Struct red=#<struct RGB::Number value=1>, green=#<struct RGB::Number value=5>, blue=#<struct RGB::Number value=255>>
263
+
264
+ rgb_color.to_hex
265
+ # => "#0105ff"
266
+ ```
267
+
268
+ ### Changed
269
+
270
+ - Change `:readonly` feature, now it doesn't require the `:instance_copy` by default.
271
+ So, If you want both features, you will need to declare them together.
272
+
273
+ ```ruby
274
+ Person = Micro::Struct.with(:readonly).new(:name)
275
+ Persona = Micro::Struct.with(:readonly, :instance_copy).new(:name)
276
+
277
+ person = Person.new(name: 'Rodrigo')
278
+ persona = Persona.new(name: 'Serradura')
279
+
280
+ person.respond_to?(:name=) # false
281
+ persona.respond_to?(:name=) # false
282
+
283
+ person.respond_to?(:with) # false
284
+ persona.respond_to?(:with) # true
285
+ ```
286
+
287
+ - Change `:to_ary` to invoke the `#to_a` method instead of defining it as an alias.
288
+ - Change `:to_hash` to invoke the `#to_h` method instead of defining it as an alias.
289
+
290
+ ```ruby
291
+ module RGB
292
+ Number = ::Struct.new(:value) { def to_s; '%02x' % value; end }
293
+
294
+ Color = Micro::Struct.with(:readonly, :to_ary, :to_hash).new(:red, :green, :blue) do
295
+ def initialize(r, g, b)
296
+ super(Number.new(r), Number.new(g), Number.new(b))
297
+ end
298
+
299
+ def to_hex
300
+ "##{red}#{green}#{blue}"
301
+ end
302
+
303
+ def to_a
304
+ [red, green, blue].map(&:value)
305
+ end
306
+
307
+ def to_h
308
+ { r: red.value, g: green.value, b: blue.value }
309
+ end
310
+ end
311
+ end
312
+
313
+ rgb_color = RGB::Color.new(red: 1, green: 5, blue: 255)
314
+ # => #<struct RGB::Color::Struct red=#<struct RGB::Number value=1>, green=#<struct RGB::Number value=5>, blue=#<struct RGB::Number value=255>>
315
+
316
+ rgb_color.to_hex # => "#0105ff"
317
+ rgb_color.to_ary # => [1, 5, 255]
318
+ rgb_color.to_hash # => {:r=>1, :g=>5, :b=>255}
319
+ ```
320
+
321
+ <p align="right">(<a href="#changelog-">⬆️ &nbsp;back to top</a>)</p>
10
322
 
11
323
  ## [0.8.0] - 2021-12-05
12
324
 
13
- - To-do
325
+ [Diff](https://github.com/serradura/u-struct/compare/v0.7.0...v0.8.0) | [Tag](https://github.com/serradura/u-struct/tree/v0.8.0)
326
+
327
+ ### Added
328
+
329
+ - Add `.===` to the module, it delegates the calling to its struct.
330
+
331
+ ```ruby
332
+ Person = Micro::Struct.new(:name)
333
+
334
+ person = Person.new(name: 'Rodrigo Serradura')
335
+ # => #<struct Person::Struct name="Rodrigo Serradura">
336
+
337
+ Person === person
338
+ # => true
339
+ ```
340
+
341
+ <p align="right">(<a href="#changelog-">⬆️ &nbsp;back to top</a>)</p>
14
342
 
15
343
  ## [0.7.0] - 2021-12-04
16
344
 
17
- - To-do
345
+ [Diff](https://github.com/serradura/u-struct/compare/v0.6.0...v0.7.0) | [Tag](https://github.com/serradura/u-struct/tree/v0.7.0)
346
+
347
+ ### Added
348
+
349
+ - Add `required:` option to define required struct members.
350
+
351
+ ```ruby
352
+ # All of the alternatives have the same equivalence.
353
+
354
+ Person = Micro::Struct.new(:first_name, :last_name)
355
+
356
+ Person = Micro::Struct.new(required: [:first_name, :last_name])
357
+
358
+ Person = Micro::Struct.new(:first_name, required: :last_name)
359
+ ```
360
+
361
+ ### Changed
362
+
363
+ - Remove the `_` from the `optional:` option.
364
+
365
+ ```ruby
366
+ Person = Micro::Struct.new(
367
+ required: [:first_name, :last_name],
368
+ optional: :age
369
+ )
370
+ ```
371
+
372
+ <p align="right">(<a href="#changelog-">⬆️ &nbsp;back to top</a>)</p>
18
373
 
19
374
  ## [0.6.0] - 2021-12-03
20
375
 
21
- - To-do
376
+ [Diff](https://github.com/serradura/u-struct/compare/v0.5.0...v0.6.0) | [Tag](https://github.com/serradura/u-struct/tree/v0.6.0)
377
+
378
+ ### Added
379
+
380
+ - Add the capability to create a struct with optional members.
381
+
382
+ ```ruby
383
+ Person = Micro::Struct.new(:first_name, _optional: :last_name)
384
+
385
+ Person.new
386
+ # ArgumentError (missing keyword: :first_name)
387
+
388
+ Person.new(first_name: 'Rodrigo')
389
+ # => #<struct Person::Struct first_name="Rodrigo", last_name=nil>
390
+
391
+ # --
392
+
393
+ Persona = Micro::Struct.new(_optional: [:first_name, :last_name])
394
+
395
+ Persona.new
396
+ # => #<struct Persona::Struct first_name=nil, last_name=nil>
397
+ ```
398
+
399
+ <p align="right">(<a href="#changelog-">⬆️ &nbsp;back to top</a>)</p>
400
+
401
+ ## [0.5.0] - 2021-12-02
402
+
403
+ [Diff](https://github.com/serradura/u-struct/compare/v0.4.0...v0.5.0) | [Tag](https://github.com/serradura/u-struct/tree/v0.5.0)
404
+
405
+ ### Added
406
+
407
+ - Add new feature `:instance_copy`. It instantiates a struct of the same kind from its current state.
408
+
409
+ ```ruby
410
+ Person = Micro::Struct.with(:instance_copy).new(:first_name, :last_name)
411
+
412
+ person = Person.new(first_name: 'Rodrigo', last_name: 'Serradura')
413
+ # => #<struct Person::Struct first_name="Rodrigo", last_name="Serradura">
414
+
415
+ person.first_name = 'John'
416
+ # => "John"
417
+
418
+ person.inspect
419
+ # => #<struct Person::Struct first_name="John", last_name="Serradura">
420
+
421
+ new_person = person.with(last_name: 'Doe')
422
+ # => #<struct Person::Struct first_name="John", last_name="Doe">
423
+
424
+ person === new_person # => false
425
+ person.equal?(new_person) # => false
426
+
427
+ person.last_name # => "Serradura"
428
+ new_person.last_name # => "Doe"
429
+ ```
430
+
431
+ - Add new feature `:readonly`. It sets members' writers private and requires the `:instance_copy` feature.
432
+
433
+ ```ruby
434
+ Person = Micro::Struct.with(:readonly).new(:name)
435
+
436
+ person = Person.new(name: 'Rodrigo Serradura')
437
+ # => #<struct Person::Struct name="Rodrigo Serradura">
438
+
439
+ person.name = 'John Doe'
440
+ # NoMethodError (private method `name=' called for #<struct Person::Struct name="Rodrigo Serradura">)
441
+
442
+ new_person = person.with(name: 'John Doe')
443
+ # => #<struct Person::Struct name="John Doe">
444
+
445
+ person === new_person # => false
446
+ person.equal?(new_person) # => false
447
+
448
+ person.name # => "Rodrigo Serradura"
449
+ new_person.name # => "John Doe"
450
+ ```
22
451
 
23
- ## [0.5.0] - 2021-12-03
452
+ <p align="right">(<a href="#changelog-">⬆️ &nbsp;back to top</a>)</p>
24
453
 
25
- - To-do
454
+ ## [0.4.0] - 2021-12-02
26
455
 
27
- ## [0.4.0] - 2021-12-03
456
+ [Diff](https://github.com/serradura/u-struct/compare/v0.3.1...v0.4.0) | [Tag](https://github.com/serradura/u-struct/tree/v0.4.0)
28
457
 
29
- - To-do
458
+ ### Added
459
+
460
+ - Add `.members` to the module, it delegates the calling to its struct.
461
+
462
+ ```ruby
463
+ Person = Micro::Struct.new(:first_name, :last_name)
464
+
465
+ Person.members # => [:first_name, :last_name]
466
+ ```
467
+
468
+ - Add `Micro::Struct.with()` to enable or disable the creation of structs with custom features.
469
+ So now, you can create the structs with one, some, or all features. They are: `to_ary`, `to_hash`, `to_proc`.
470
+
471
+ ```ruby
472
+ Person = Micro::Struct.with(:to_ary).new(:name)
473
+
474
+ person = Person.new(name: 'Rodrigo')
475
+ # => #<struct Person::Struct name="Rodrigo">
476
+
477
+ person.respond_to?(:to_ary) # => true
478
+ person.respond_to?(:to_hash) # => false
479
+
480
+ Person.respond_to?(:to_proc) # => false
481
+ ```
482
+
483
+ <p align="right">(<a href="#changelog-">⬆️ &nbsp;back to top</a>)</p>
30
484
 
31
485
  ## [0.3.1] - 2021-12-02
32
486
 
33
- - To-do
487
+ [Diff](https://github.com/serradura/u-struct/compare/v0.3.0...v0.3.1) | [Tag](https://github.com/serradura/u-struct/tree/v0.3.1)
488
+
489
+ ### Fixed
490
+
491
+ - Fix the spec.files config of `u-struct.gemspec`.
492
+
493
+ <p align="right">(<a href="#changelog-">⬆️ &nbsp;back to top</a>)</p>
34
494
 
35
495
  ## [0.3.0] - 2021-12-02
36
496
 
37
- - To-do
497
+ [Diff](https://github.com/serradura/u-struct/compare/v0.2.0...v0.3.0) | [Tag](https://github.com/serradura/u-struct/tree/v0.3.0)
498
+
499
+ ### Added
500
+
501
+ - Add `lib/u-struct.rb` to allow the bundler to require the gem in an automatic way.
502
+
503
+ <p align="right">(<a href="#changelog-">⬆️ &nbsp;back to top</a>)</p>
38
504
 
39
505
  ## [0.2.0] - 2021-12-02
40
506
 
41
- - To-do
507
+ [Diff](https://github.com/serradura/u-struct/compare/v0.1.0...v0.2.0) | [Tag](https://github.com/serradura/u-struct/tree/v0.2.0)
508
+
509
+ ### Added
510
+
511
+ - Add `to_hash` as an alias of Struct's `to_h`.
512
+
513
+ ```ruby
514
+ Person = Micro::Struct.new(:first_name, :last_name)
515
+
516
+ def print_first_and_last_name(first_name:, last_name:)
517
+ puts "#{first_name} #{last_name}"
518
+ end
519
+
520
+ person = Person.new(first_name: 'Rodrigo', last_name: 'Serradura')
521
+
522
+ print_first_and_last_name(**person) # Rodrigo Serradura
523
+ ```
524
+
525
+ <p align="right">(<a href="#changelog-">⬆️ &nbsp;back to top</a>)</p>
42
526
 
43
527
  ## [0.1.0] - 2021-12-02
44
528
 
45
- - Initial release
529
+ [Diff](https://github.com/serradura/u-struct/compare/19beceb97a9bc22f2a485b82e4002b6a2e20a73c...v0.1.0) | [Tag](https://github.com/serradura/u-struct/tree/v0.1.0)
530
+
531
+ ### Added
532
+
533
+ - Create a module containing a Ruby struct with some custom features.
534
+ - The module's `.new` method receives the struct arguments as keyword arguments.
535
+ - The module's `.new` can receive a block as a regular `Struct` to add some custom behavior.
536
+ - The module's `to_proc` can instantiate the struct by receiving a hash.
537
+ - The module's struct has its initializer set up as private.
538
+ - Add `to_ary` as an alias of module's struct `to_a`.
539
+
540
+ ```ruby
541
+ Person = Micro::Struct.new(:first_name, :last_name) do
542
+ def name
543
+ "#{first_name} #{last_name}"
544
+ end
545
+ end
546
+
547
+ # == Module's .new ==
548
+
549
+ Person.new
550
+ # ArgumentError (missing keywords: :first_name, :last_name)
551
+
552
+ Person.new(first_name: 'Rodrigo')
553
+ # ArgumentError (missing keyword: :last_name)
554
+
555
+ person = Person.new(first_name: 'Rodrigo', last_name: 'Serradura')
556
+ # => #<struct Person::Struct first_name="Rodrigo", last_name="Serradura">
557
+
558
+ # == Struct's block - it sets up custom behavior ==
559
+
560
+ person.name # => "Rodrigo Serradura"
561
+
562
+ # == Struct's #to_ary ==
563
+
564
+ first_name, last_name = person
565
+
566
+ p first_name # => "Rodrigo"
567
+ p last_name # => "Serradura"
568
+
569
+ *first_and_last_name = person
570
+
571
+ p first_and_last_name # => ["Rodrigo", "Serradura"]
572
+
573
+ # == Module's .to_proc ==
574
+
575
+ [
576
+ {first_name: 'John', last_name: 'Doe'},
577
+ {first_name: 'Mary', last_name: 'Doe'}
578
+ ].map(&Person)
579
+ # => [
580
+ # #<struct Person::Struct first_name="John", last_name="Doe">,
581
+ # #<struct Person::Struct first_name="Mary", last_name="Doe">
582
+ # ]
583
+
584
+ # == Struct's private initializer ==
585
+
586
+ Person::Struct.new
587
+ # => NoMethodError (private method `new' called for Person::Struct:Class)
588
+ ```
589
+
590
+ <p align="right">(<a href="#changelog-">⬆️ &nbsp;back to top</a>)</p>
data/Gemfile CHANGED
@@ -5,7 +5,18 @@ source 'https://rubygems.org'
5
5
  # Specify your gem's dependencies in micro-struct.gemspec
6
6
  gemspec
7
7
 
8
- gem 'rake', '~> 13.0'
8
+ gem 'rake', '13.0.6'
9
9
 
10
- gem 'minitest', '~> 5.0'
11
- gem 'simplecov', '~> 0.21.2' if RUBY_VERSION >= '2.5.0'
10
+ gem 'minitest', '5.15.0'
11
+
12
+ if RUBY_VERSION >= '2.5.0'
13
+ gem 'rubocop', '1.26'
14
+ gem 'rubocop-minitest', '0.18.0'
15
+ gem 'rubocop-rake', '0.6.0'
16
+ gem 'simplecov', '0.21.2'
17
+ end
18
+
19
+ if RUBY_VERSION >= '2.7.0'
20
+ gem 'sorbet', '0.5.9775'
21
+ gem 'tapioca', '0.7.0'
22
+ end