u-struct 0.11.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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