dry-struct 1.2.0 → 1.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +105 -61
- data/LICENSE +1 -1
- data/README.md +16 -12
- data/dry-struct.gemspec +26 -27
- data/lib/dry-struct.rb +2 -0
- data/lib/dry/struct.rb +14 -3
- data/lib/dry/struct/class_interface.rb +91 -34
- data/lib/dry/struct/compiler.rb +22 -0
- data/lib/dry/struct/constructor.rb +4 -24
- data/lib/dry/struct/errors.rb +13 -3
- data/lib/dry/struct/extensions.rb +2 -0
- data/lib/dry/struct/extensions/pretty_print.rb +3 -1
- data/lib/dry/struct/hashify.rb +5 -1
- data/lib/dry/struct/printer.rb +5 -0
- data/lib/dry/struct/struct_builder.rb +18 -11
- data/lib/dry/struct/sum.rb +3 -0
- data/lib/dry/struct/value.rb +4 -6
- data/lib/dry/struct/version.rb +3 -1
- metadata +36 -59
- data/.codeclimate.yml +0 -12
- data/.github/ISSUE_TEMPLATE/----please-don-t-ask-for-support-via-issues.md +0 -10
- data/.github/ISSUE_TEMPLATE/---bug-report.md +0 -30
- data/.github/ISSUE_TEMPLATE/---feature-request.md +0 -18
- data/.github/workflows/ci.yml +0 -74
- data/.github/workflows/docsite.yml +0 -34
- data/.github/workflows/sync_configs.yml +0 -34
- data/.gitignore +0 -12
- data/.rspec +0 -4
- data/.rubocop.yml +0 -95
- data/.yardopts +0 -4
- data/CODE_OF_CONDUCT.md +0 -13
- data/CONTRIBUTING.md +0 -29
- data/Gemfile +0 -28
- data/Rakefile +0 -10
- data/benchmarks/basic.rb +0 -57
- data/benchmarks/constrained.rb +0 -37
- data/benchmarks/profile_instantiation.rb +0 -19
- data/benchmarks/setup.rb +0 -11
- data/bin/console +0 -12
- data/bin/setup +0 -7
- data/docsite/source/index.html.md +0 -103
- data/docsite/source/nested-structs.html.md +0 -49
- data/docsite/source/recipes.html.md +0 -143
- data/log/.gitkeep +0 -0
@@ -1,49 +0,0 @@
|
|
1
|
-
---
|
2
|
-
title: Nested Structs
|
3
|
-
layout: gem-single
|
4
|
-
name: dry-struct
|
5
|
-
---
|
6
|
-
|
7
|
-
The DSL allows to define nested structs by passing a block to `attribute`:
|
8
|
-
|
9
|
-
```ruby
|
10
|
-
class User < Dry::Struct
|
11
|
-
attribute :name, Types::String
|
12
|
-
attribute :address do
|
13
|
-
attribute :city, Types::String
|
14
|
-
attribute :street, Types::String
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
User.new(name: 'Jane', address: { city: 'London', street: 'Oxford' })
|
19
|
-
# => #<User name="Jane" address=#<User::Address city="London" street="Oxford">>
|
20
|
-
|
21
|
-
# constants for nested structs are automatically defined
|
22
|
-
User::Address
|
23
|
-
# => User::Address
|
24
|
-
```
|
25
|
-
|
26
|
-
By default, new struct classes uses `Dry::Struct` as a base class (`Dry::Struct::Value` for values). You can explicitly pass a different class:
|
27
|
-
|
28
|
-
```ruby
|
29
|
-
class User < Dry::Struct
|
30
|
-
attribute :address, MyStruct do
|
31
|
-
# ...
|
32
|
-
end
|
33
|
-
end
|
34
|
-
```
|
35
|
-
|
36
|
-
It is even possible to define an array of struct:
|
37
|
-
|
38
|
-
```ruby
|
39
|
-
class User < Dry::Struct
|
40
|
-
attribute :addresses, Types::Array do
|
41
|
-
attribute :city, Types::String
|
42
|
-
attribute :street, Types::String
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# constants are still there!
|
47
|
-
User::Address
|
48
|
-
# => User::Address
|
49
|
-
```
|
@@ -1,143 +0,0 @@
|
|
1
|
-
---
|
2
|
-
title: Recipes
|
3
|
-
layout: gem-single
|
4
|
-
name: dry-struct
|
5
|
-
---
|
6
|
-
|
7
|
-
### Symbolize input keys
|
8
|
-
|
9
|
-
```ruby
|
10
|
-
require 'dry-struct'
|
11
|
-
|
12
|
-
module Types
|
13
|
-
include Dry.Types()
|
14
|
-
end
|
15
|
-
|
16
|
-
class User < Dry::Struct
|
17
|
-
transform_keys(&:to_sym)
|
18
|
-
|
19
|
-
attribute :name, Types::String
|
20
|
-
end
|
21
|
-
|
22
|
-
User.new('name' => 'Jane')
|
23
|
-
# => #<User name="Jane">
|
24
|
-
```
|
25
|
-
|
26
|
-
### Tolerance to extra keys
|
27
|
-
|
28
|
-
Structs ignore extra keys by default. This can be changed by replacing the constructor.
|
29
|
-
|
30
|
-
```ruby
|
31
|
-
class User < Dry::Struct
|
32
|
-
# This does the trick
|
33
|
-
schema schema.strict
|
34
|
-
|
35
|
-
attribute :name, Types::String
|
36
|
-
end
|
37
|
-
|
38
|
-
User.new(name: 'Jane', age: 21)
|
39
|
-
# => Dry::Struct::Error ([User.new] unexpected keys [:age] in Hash input)
|
40
|
-
```
|
41
|
-
|
42
|
-
### Tolerance to missing keys
|
43
|
-
|
44
|
-
You can mark certain keys as optional by calling `attribute?`.
|
45
|
-
|
46
|
-
```ruby
|
47
|
-
class User < Dry::Struct
|
48
|
-
attribute :name, Types::String
|
49
|
-
attribute? :age, Types::Integer
|
50
|
-
end
|
51
|
-
|
52
|
-
user = User.new(name: 'Jane')
|
53
|
-
# => #<User name="Jane" age=nil>
|
54
|
-
user.age
|
55
|
-
# => nil
|
56
|
-
```
|
57
|
-
|
58
|
-
In the example above `nil` violates the type constraint so be careful with `attribute?`.
|
59
|
-
|
60
|
-
### Default values
|
61
|
-
|
62
|
-
Instead of violating constraints you can assign default values to attributes:
|
63
|
-
|
64
|
-
```ruby
|
65
|
-
class User < Dry::Struct
|
66
|
-
attribute :name, Types::String
|
67
|
-
attribute :age, Types::Integer.default(18)
|
68
|
-
end
|
69
|
-
|
70
|
-
User.new(name: 'Jane')
|
71
|
-
# => #<User name="Jane" age=18>
|
72
|
-
```
|
73
|
-
|
74
|
-
### Resolving default values on `nil`
|
75
|
-
|
76
|
-
`nil` as a value isn't replaced with a default value for default types. You may use `transform_types` to turn all types into constructors which map `nil` to `Dry::Types::Undefined` which in order triggers default values.
|
77
|
-
|
78
|
-
```ruby
|
79
|
-
class User < Dry::Struct
|
80
|
-
transform_types do |type|
|
81
|
-
if type.default?
|
82
|
-
type.constructor do |value|
|
83
|
-
value.nil? ? Dry::Types::Undefined : value
|
84
|
-
end
|
85
|
-
else
|
86
|
-
type
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
attribute :name, Types::String
|
91
|
-
attribute :age, Types::Integer.default(18)
|
92
|
-
end
|
93
|
-
|
94
|
-
User.new(name: 'Jane')
|
95
|
-
# => #<User name="Jane" age=18>
|
96
|
-
User.new(name: 'Jane', age: nil)
|
97
|
-
# => #<User name="Jane" age=18>
|
98
|
-
```
|
99
|
-
|
100
|
-
### Creating a custom struct class
|
101
|
-
|
102
|
-
You can combine examples from this page to create a custom-purposed base struct class and the reuse it your application or gem
|
103
|
-
|
104
|
-
```ruby
|
105
|
-
class MyStruct < Dry::Struct
|
106
|
-
# throw an error when unknown keys provided
|
107
|
-
schema schema.strict
|
108
|
-
|
109
|
-
# convert string keys to symbols
|
110
|
-
transform_keys(&:to_sym)
|
111
|
-
|
112
|
-
# resolve default types on nil
|
113
|
-
transform_types do |type|
|
114
|
-
if type.default?
|
115
|
-
type.constructor do |value|
|
116
|
-
value.nil? ? Dry::Types::Undefined : value
|
117
|
-
end
|
118
|
-
else
|
119
|
-
type
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
```
|
124
|
-
|
125
|
-
### Set default value for a nested hash
|
126
|
-
|
127
|
-
```ruby
|
128
|
-
class Foo < Dry::Struct
|
129
|
-
attribute :bar do
|
130
|
-
attribute :nested, Types::Integer
|
131
|
-
end
|
132
|
-
end
|
133
|
-
```
|
134
|
-
|
135
|
-
```ruby
|
136
|
-
class Foo < Dry::Struct
|
137
|
-
class Bar < Dry::Struct
|
138
|
-
attribute :nested, Types::Integer
|
139
|
-
end
|
140
|
-
|
141
|
-
attribute :bar, Bar.default { Bar.new(nested: 1) }
|
142
|
-
end
|
143
|
-
```
|
data/log/.gitkeep
DELETED
File without changes
|