kind 5.3.0 → 5.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b826449cc89c4cd8dc3d58694a37914f7de37cb7000a2ba534ffa914f10f7677
4
- data.tar.gz: e2ed88bcf83d332de58a8516533a58f858494e7ac2ea60f58517e08cd11066c9
3
+ metadata.gz: a01866d3dbb6b0ae5977a7e711b35eaa2152471b4d52781a285de03ec9ef86a1
4
+ data.tar.gz: 8fd0cc81e96aa364a90f3c161e824d1a501296b4c4b40e2aca1e4286a75baaec
5
5
  SHA512:
6
- metadata.gz: ac5f74a2ba85be82a6b9709745069047105ccdf8aacadbabdb7e96f66ff007dd0e7ce8e2001df206614c3bf852cb95f3c9d21d2f203490a39070a92bb2250afd
7
- data.tar.gz: 14b4f8b747a25b9c9535f40972dcfbc07116f97051090616053c663dbfe71cc5b8771bc5899da4e51a77168acb18a18a8c0b898a37c6730397d5c3a4afdc340b
6
+ metadata.gz: 10282e2b8777f2d1a738a6ce38285fc9f17f0d9a6b3aec26d46409d995cb0004fde5c20a3998ef68a98530c5fa25ee463fba8f3501e5cbeb0cb2b01e0f2627ba
7
+ data.tar.gz: 7d16bf63dbb4928bef6182a7886e9268da869bddab12ac0e1192e39bac3fce2a4489ed308366188df4d6550047b2003e1b427f87430ec5e68c49c34a3974c13f
data/CHANGELOG.md CHANGED
@@ -3,75 +3,85 @@
3
3
  This project follows [semver 2.0.0](http://semver.org/spec/v2.0.0.html) and the recommendations of [keepachangelog.com](http://keepachangelog.com/).
4
4
 
5
5
  - [Unreleased](#unreleased)
6
- - [5.3.0 (2021-03-23)](#530-2021-03-23)
6
+ - [5.7.0 (2021-06-22)](#570-2021-06-22)
7
7
  - [Added](#added)
8
- - [5.2.0 (2021-03-17)](#520-2021-03-17)
8
+ - [5.6.0 (2021-05-14)](#560-2021-05-14)
9
9
  - [Added](#added-1)
10
+ - [5.5.0 (2021-04-05)](#550-2021-04-05)
11
+ - [Added](#added-2)
12
+ - [5.4.1 (2021-03-26)](#541-2021-03-26)
13
+ - [Fixed](#fixed)
14
+ - [5.4.0 (2021-03-25)](#540-2021-03-25)
15
+ - [Added](#added-3)
16
+ - [5.3.0 (2021-03-23)](#530-2021-03-23)
17
+ - [Added](#added-4)
18
+ - [5.2.0 (2021-03-17)](#520-2021-03-17)
19
+ - [Added](#added-5)
10
20
  - [Deprecated](#deprecated)
11
21
  - [Changes](#changes)
12
22
  - [5.1.0 (2021-02-23)](#510-2021-02-23)
13
- - [Added](#added-2)
23
+ - [Added](#added-6)
14
24
  - [Deprecated](#deprecated-1)
15
25
  - [5.0.0 (2021-02-22)](#500-2021-02-22)
16
26
  - [Breaking Changes](#breaking-changes)
17
27
  - [Removed](#removed)
18
28
  - [4.1.0 (2021-02-22)](#410-2021-02-22)
19
- - [Added](#added-3)
29
+ - [Added](#added-7)
20
30
  - [4.0.0 (2021-02-22)](#400-2021-02-22)
21
- - [Added](#added-4)
31
+ - [Added](#added-8)
22
32
  - [Deprecated](#deprecated-2)
23
- - [Fixed](#fixed)
33
+ - [Fixed](#fixed-1)
24
34
  - [3.1.0 (2020-07-08)](#310-2020-07-08)
25
- - [Added](#added-5)
35
+ - [Added](#added-9)
26
36
  - [3.0.0 (2020-06-25)](#300-2020-06-25)
27
37
  - [Breaking Changes](#breaking-changes-1)
28
- - [Added](#added-6)
38
+ - [Added](#added-10)
29
39
  - [2.3.0 (2020-06-24)](#230-2020-06-24)
30
- - [Added](#added-7)
40
+ - [Added](#added-11)
31
41
  - [2.2.0 (2020-06-23)](#220-2020-06-23)
32
- - [Added](#added-8)
42
+ - [Added](#added-12)
33
43
  - [2.1.0 (2020-05-12)](#210-2020-05-12)
34
- - [Added](#added-9)
44
+ - [Added](#added-13)
35
45
  - [Breaking Changes](#breaking-changes-2)
36
46
  - [2.0.0 (2020-05-07)](#200-2020-05-07)
37
- - [Added](#added-10)
47
+ - [Added](#added-14)
38
48
  - [Breaking Changes](#breaking-changes-3)
39
49
  - [Removed](#removed-1)
40
50
  - [1.9.0 (2020-05-06)](#190-2020-05-06)
41
- - [Added](#added-11)
51
+ - [Added](#added-15)
42
52
  - [1.8.0 (2020-05-03)](#180-2020-05-03)
43
- - [Added](#added-12)
53
+ - [Added](#added-16)
44
54
  - [1.7.0 (2020-05-03)](#170-2020-05-03)
45
- - [Fixed](#fixed-1)
55
+ - [Fixed](#fixed-2)
46
56
  - [1.6.0 (2020-04-17)](#160-2020-04-17)
47
- - [Added](#added-13)
57
+ - [Added](#added-17)
48
58
  - [Changes](#changes-1)
49
59
  - [1.5.0 (2020-04-12)](#150-2020-04-12)
50
- - [Added](#added-14)
60
+ - [Added](#added-18)
51
61
  - [1.4.0 (2020-04-12)](#140-2020-04-12)
52
- - [Added](#added-15)
62
+ - [Added](#added-19)
53
63
  - [1.3.0 (2020-04-12)](#130-2020-04-12)
54
- - [Added](#added-16)
64
+ - [Added](#added-20)
55
65
  - [1.2.0 (2020-04-12)](#120-2020-04-12)
56
- - [Added](#added-17)
66
+ - [Added](#added-21)
57
67
  - [1.1.0 (2020-04-09)](#110-2020-04-09)
58
- - [Added](#added-18)
59
- - [Fixed](#fixed-2)
68
+ - [Added](#added-22)
69
+ - [Fixed](#fixed-3)
60
70
  - [1.0.0 (2020-03-16)](#100-2020-03-16)
61
- - [Added](#added-19)
71
+ - [Added](#added-23)
62
72
  - [0.6.0 (2020-01-06)](#060-2020-01-06)
63
- - [Added](#added-20)
73
+ - [Added](#added-24)
64
74
  - [0.5.0 (2020-01-04)](#050-2020-01-04)
65
- - [Added](#added-21)
75
+ - [Added](#added-25)
66
76
  - [0.4.0 (2020-01-03)](#040-2020-01-03)
67
- - [Added](#added-22)
77
+ - [Added](#added-26)
68
78
  - [0.3.0 (2020-01-03)](#030-2020-01-03)
69
- - [Added](#added-23)
79
+ - [Added](#added-27)
70
80
  - [Breaking Changes](#breaking-changes-4)
71
81
  - [0.2.0 (2020-01-02)](#020-2020-01-02)
72
- - [Added](#added-24)
82
+ - [Added](#added-28)
73
83
  - [0.1.0 (2019-12-26)](#010-2019-12-26)
74
- - [Added](#added-25)
84
+ - [Added](#added-29)
75
85
 
76
86
  ## Unreleased
77
87
 
@@ -83,6 +93,174 @@ This project follows [semver 2.0.0](http://semver.org/spec/v2.0.0.html) and the
83
93
  ### Fixed
84
94
  -->
85
95
 
96
+ 5.7.0 (2021-06-22)
97
+ ------------------
98
+
99
+ ### Added
100
+
101
+ * [#58](https://github.com/serradura/kind/pull/58) - Add `Add Kind.assert_hash!(hash, keys:)`, you can use the `require_all:` option to check if the hashes have the same keys.
102
+ ```ruby
103
+ h1 = {a: 1, b: 1}
104
+
105
+ Kind.assert_hash!(h1, keys: [:a, :b])
106
+ Kind.assert_hash!(h1, keys: [:a]) # ArgumentError (Unknown key: :b. Valid keys are: :a)
107
+
108
+ # --
109
+
110
+ h2 = {'a' => 1, 'b' => 2}
111
+
112
+ Kind.assert_hash!(h2, keys: ['a', 'b'])
113
+ ```
114
+
115
+ * [#58](https://github.com/serradura/kind/pull/58) - Add `Add Kind.assert_hash!(hash, schema:)`, you can use the `require_all:` option to check if the hashes have the same keys.
116
+ ```ruby
117
+ hash = {hash: {}, array: [], number: 1, string: 'foo', email: 'bar@bar.com', null: nil}
118
+
119
+ Kind.assert_hash!(hash, schema: {
120
+ hash: {},
121
+ array: [],
122
+ email: 'bar@bar.com',
123
+ string: 'foo',
124
+ number: 1,
125
+ null: nil
126
+ })
127
+
128
+ Kind.assert_hash!(hash, schema: {
129
+ hash: Enumerable,
130
+ array: Enumerable,
131
+ email: /\A.+@.+\..+\z/,
132
+ string: String
133
+ })
134
+
135
+ Kind.assert_hash!(hash, schema: {
136
+ hash: Hash,
137
+ array: Array,
138
+ email: String,
139
+ string: String
140
+ })
141
+
142
+ Kind.assert_hash!(h1, schema: {
143
+ email: ->(value) { value.is_a?(String) && value.include?('@') }
144
+ })
145
+ ```
146
+
147
+ [⬆️  Back to Top](#changelog-)
148
+
149
+ 5.6.0 (2021-05-14)
150
+ ------------------
151
+
152
+ ### Added
153
+
154
+ * [#57](https://github.com/serradura/kind/pull/57) - Allow the usage of `nil` to define union types.
155
+ ```ruby
156
+ (Kind::String | nil) === '' # true
157
+ (Kind::String | nil) === nil # true
158
+
159
+ (Kind::String | nil) === {} # false
160
+ ```
161
+
162
+ [⬆️  Back to Top](#changelog-)
163
+
164
+ 5.5.0 (2021-04-05)
165
+ ------------------
166
+
167
+ ### Added
168
+
169
+ * [#56](https://github.com/serradura/kind/pull/56) - Add `Kind.or_nil()`.
170
+ ```ruby
171
+ Kind.or_nil(String, 1) # nil
172
+
173
+ Kind.or_nil(String, '') # ""
174
+
175
+ # --
176
+
177
+ filled_string = ->(value) { value.is_a?(String) && !value.empty? }
178
+
179
+ Kind.or_nil(filled_string, 1) # nil
180
+ Kind.or_nil(filled_string, '') # nil
181
+
182
+ Kind.or_nil(filled_string, '1') # "1"
183
+ ```
184
+
185
+ [⬆️  Back to Top](#changelog-)
186
+
187
+ 5.4.1 (2021-03-26)
188
+ ------------------
189
+
190
+ ### Fixed
191
+
192
+ * [#55](https://github.com/serradura/kind/pull/55) - Fix `Kind::Either::Left#value_or` and `Kind::Result::Failure#value_or` by allowing them to receive the value of the monad in a call using a block.
193
+
194
+ [⬆️  Back to Top](#changelog-)
195
+
196
+ 5.4.0 (2021-03-25)
197
+ ------------------
198
+
199
+ ### Added
200
+
201
+ * [#54](https://github.com/serradura/kind/pull/54) - Add `Kind::Functional::Steps` to allow the usage of `Step`, `Map`, `Try`, `Tee`, `Check`, `Success` and `Failure` in any kind of object.
202
+ ```ruby
203
+ # Usage in classes' instances
204
+
205
+ class BaseJob
206
+ def self.perform_now(input); new.perform(input); end
207
+
208
+ def perform(input); raise NotImplementedError; end
209
+ end
210
+
211
+ class CreateUserJob < BaseJob
212
+ include Kind::Functional::Steps
213
+
214
+ def perform(input)
215
+ validate(input) \
216
+ >> Step(:create) \
217
+ >> Step(:welcome_email)
218
+ end
219
+
220
+ private
221
+
222
+ def validate(input)
223
+ # Success() or Failure()
224
+ end
225
+
226
+ def create(input)
227
+ # Success() or Failure()
228
+ end
229
+
230
+ def welcome_email(email)
231
+ # Success() or Failure()
232
+ end
233
+ end
234
+
235
+ # Usage in modules (singleton methods)
236
+
237
+ module CreateUser
238
+ extend self, Kind::Functional::Steps
239
+
240
+ def perform(input)
241
+ Step!(:validate, input) \
242
+ >> Step(:create) \
243
+ >> Step(:welcome_email)
244
+ end
245
+
246
+ private
247
+
248
+ def validate(input)
249
+ # Success() or Failure()
250
+ end
251
+
252
+ def create(input)
253
+ # Success() or Failure()
254
+ end
255
+
256
+ def welcome_email(email)
257
+ # Success() or Failure()
258
+ end
259
+ end
260
+ ```
261
+
262
+ [⬆️ &nbsp;Back to Top](#changelog-)
263
+
86
264
  5.3.0 (2021-03-23)
87
265
  ------------------
88
266
 
@@ -122,6 +300,8 @@ This project follows [semver 2.0.0](http://semver.org/spec/v2.0.0.html) and the
122
300
  * `Kind::<Type>[1]`
123
301
  * `Kind::NotNil[1]`
124
302
 
303
+ [⬆️ &nbsp;Back to Top](#changelog-)
304
+
125
305
  5.2.0 (2021-03-17)
126
306
  ------------------
127
307
 
@@ -295,6 +475,8 @@ This project follows [semver 2.0.0](http://semver.org/spec/v2.0.0.html) and the
295
475
  p number # 0
296
476
  ```
297
477
 
478
+ [⬆️ &nbsp;Back to Top](#changelog-)
479
+
298
480
  * [#46](https://github.com/serradura/kind/pull/46) - Add `Kind::Either` (either monad). This is basically the same as the `Maybe` monad, but with `Some` called `Right` and `None` called `Left`. But this time, `Left` is also allowed to have an underlying value. This module isn't loaded by default, so you will need to require it.
299
481
  ```ruby
300
482
  require 'kind/either'
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <p align="center">
2
2
  <h1 align="center">🤷 kind</h1>
3
- <p align="center"><i>A simple type system (at runtime) for Ruby - free of dependencies.</i></p>
3
+ <p align="center"><i>A development toolkit for Ruby with several small/cohesive abstractions to empower your development workflow - It's totally free of dependencies.</i></p>
4
4
  </p>
5
5
 
6
6
  <p align="center">
@@ -31,16 +31,18 @@
31
31
 
32
32
  **Motivation:**
33
33
 
34
- As a creator of Ruby gems, I have a common need that I have to handle in many of my projects: type checking of method arguments.
34
+ This project was born to help me with a simple task, create a light and fast type checker (at runtime) for Ruby. The initial idea was to have something to raise an exception when a method or function (procs) received a wrong input.
35
35
 
36
- One of the goals of this project is to do simple type checking like `"some string".is_a?(String)`, but, exposing useful abstractions around this. e.g: [Kind.\<Type\> methods](#verifying-the-kind-of-some-object), [active model validations](#kindvalidator-activemodelvalidations), [maybe monad](#kindmaybe).
36
+ But through time it was natural the addition of more features to improve the development workflow, like monads ([`Kind::Maybe`](#kindmaybe), `Kind::Either` / `Kind::Result`), enums (`Kind::Enum`), immutable objects (`Kind::ImmutableAttributes`), [type validation via ActiveModel::Validation](#kindvalidator-activemodelvalidations), and several abstractions to help the implementation of business logic (`Kind::Functional::Steps`, `Kind::Functional::Action`, `Kind::Action`).
37
+
38
+ So, I invite you to check out these features to see how they could be useful for you. Enjoy!
37
39
 
38
40
  ## Documentation <!-- omit in toc -->
39
41
 
40
42
  Version | Documentation
41
43
  ---------- | -------------
42
44
  unreleased | https://github.com/serradura/kind/blob/main/README.md
43
- 5.3.0 | https://github.com/serradura/kind/blob/v5.x/README.md
45
+ 5.7.0 | https://github.com/serradura/kind/blob/v5.x/README.md
44
46
  4.1.0 | https://github.com/serradura/kind/blob/v4.x/README.md
45
47
  3.1.0 | https://github.com/serradura/kind/blob/v3.x/README.md
46
48
  2.3.0 | https://github.com/serradura/kind/blob/v2.x/README.md
@@ -120,14 +122,14 @@ unreleased | https://github.com/serradura/kind/blob/main/README.md
120
122
 
121
123
  ## Compatibility
122
124
 
123
- | kind | branch | ruby | activemodel |
124
- | -------------- | ------- | -------- | -------------- |
125
- | unreleased | main | >= 2.1.0 | >= 3.2, <= 6.1 |
126
- | 5.3.0 | v5.x | >= 2.1.0 | >= 3.2, <= 6.1 |
127
- | 4.1.0 | v4.x | >= 2.2.0 | >= 3.2, <= 6.1 |
128
- | 3.1.0 | v3.x | >= 2.2.0 | >= 3.2, <= 6.1 |
129
- | 2.3.0 | v2.x | >= 2.2.0 | >= 3.2, <= 6.0 |
130
- | 1.9.0 | v1.x | >= 2.2.0 | >= 3.2, <= 6.0 |
125
+ | kind | branch | ruby | activemodel |
126
+ | -------------- | ------- | ------------------ | -------------- |
127
+ | unreleased | main | >= 2.1.0, <= 3.0.0 | >= 3.2, < 7.0 |
128
+ | 5.7.0 | v5.x | >= 2.1.0, <= 3.0.0 | >= 3.2, < 7.0 |
129
+ | 4.1.0 | v4.x | >= 2.2.0, <= 3.0.0 | >= 3.2, < 7.0 |
130
+ | 3.1.0 | v3.x | >= 2.2.0, <= 2.7 | >= 3.2, < 7.0 |
131
+ | 2.3.0 | v2.x | >= 2.2.0, <= 2.7 | >= 3.2, <= 6.0 |
132
+ | 1.9.0 | v1.x | >= 2.2.0, <= 2.7 | >= 3.2, <= 6.0 |
131
133
 
132
134
  > Note: The activemodel is an optional dependency, it is related with the [Kind::Validator](#kindvalidator-activemodelvalidations).
133
135
 
data/kind.gemspec CHANGED
@@ -6,8 +6,8 @@ Gem::Specification.new do |spec|
6
6
  spec.authors = ['Rodrigo Serradura']
7
7
  spec.email = ['rodrigo.serradura@gmail.com']
8
8
 
9
- spec.summary = %q{A simple type system (at runtime) for Ruby.}
10
- spec.description = %q{A simple type system (at runtime) for Ruby - free of dependencies.}
9
+ spec.summary = %q{A development toolkit for Ruby with several small/cohesive abstractions to empower your development workflow.}
10
+ spec.description = %q{A development toolkit for Ruby with several small/cohesive abstractions (monads, enums, business logic, data validation...) to empower your development workflow - It's totally free of dependencies.}
11
11
  spec.homepage = 'https://github.com/serradura/kind'
12
12
  spec.license = 'MIT'
13
13
  spec.required_ruby_version = Gem::Requirement.new('>= 2.1.0')
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module ASSERT_HASH_KEYS
5
+ def self.require_all(keys, hash)
6
+ expected_keys = keys - hash.keys
7
+
8
+ unless expected_keys.empty?
9
+ raise KeyError.new("#{hash.inspect} expected to have these keys: #{expected_keys}")
10
+ end
11
+
12
+ unexpected_keys = hash.keys - keys
13
+
14
+ unless unexpected_keys.empty?
15
+ raise KeyError.new("#{hash.inspect} expected to NOT have these keys: #{unexpected_keys}")
16
+ end
17
+
18
+ hash
19
+ end
20
+ end
21
+
22
+ module ASSERT_HASH_SCHEMA
23
+ extend self
24
+
25
+ UnionType = ->(value) do
26
+ defined?(Kind::UnionType) ? Kind::UnionType === value : false
27
+ end
28
+
29
+ def any(hash, spec)
30
+ spec.each do |key, expected|
31
+ value = hash[key]
32
+ error_message = "The key #{key.inspect} has an invalid value"
33
+
34
+ case expected
35
+ when ::Module then assert_kind_of(expected, value, error_message)
36
+ when ::Proc then assert(expected.call(value), error_message)
37
+ when ::Regexp then assert_match(expected, value, error_message)
38
+ when ::NilClass then assert_nil(value, error_message)
39
+ when UnionType then assert(expected === value, error_message)
40
+ else assert_equal(expected, value, error_message)
41
+ end
42
+ end
43
+
44
+ hash
45
+ end
46
+
47
+ def all(hash, spec)
48
+ ASSERT_HASH_KEYS.require_all(spec.keys, hash)
49
+
50
+ any(hash, spec)
51
+ end
52
+
53
+ private
54
+
55
+ def assert_equal(expected, value, message)
56
+ raise_kind_error(message) if expected != value
57
+ end
58
+
59
+ def assert(value, message)
60
+ raise_kind_error(message) unless value
61
+ end
62
+
63
+ def assert_nil(value, message)
64
+ raise_kind_error(message) unless value.nil?
65
+ end
66
+
67
+ def assert_match(expected, value, message)
68
+ STRICT.kind_of(String, value)
69
+
70
+ raise_kind_error(message) if value !~ expected
71
+ end
72
+
73
+ def assert_kind_of(expected, value, message)
74
+ raise_kind_error(message) unless expected === value
75
+ end
76
+
77
+ def raise_kind_error(message)
78
+ raise Error.new(message)
79
+ end
80
+ end
81
+ end
@@ -6,6 +6,8 @@ module Kind
6
6
  module STRICT
7
7
  extend self
8
8
 
9
+ require 'kind/__lib__/assert_hash_schema'
10
+
9
11
  def error(kind_name, value, label = nil) # :nodoc:
10
12
  raise Error.new(kind_name, value, label: label)
11
13
  end
@@ -43,6 +45,41 @@ module Kind
43
45
 
44
46
  raise Error.new("#{label_text}expected to not be nil")
45
47
  end
48
+
49
+ def in!(list, value)
50
+ return value if list.include?(value)
51
+
52
+ raise Error.new("#{value} expected to be included in #{list.inspect}")
53
+ end
54
+
55
+ def assert_hash!(hash, options)
56
+ require_all = options[:require_all]
57
+
58
+ return assert_hash_keys!(hash, options[:keys], require_all) if options.key?(:keys)
59
+ return assert_hash_schema!(hash, options[:schema], require_all) if options.key?(:schema)
60
+
61
+ raise ArgumentError, ':keys or :schema is missing'
62
+ end
63
+
64
+ private
65
+
66
+ def assert_hash_keys!(hash, arg, require_all)
67
+ keys = Array(arg)
68
+
69
+ ASSERT_HASH_KEYS.require_all(keys, hash) if require_all
70
+
71
+ hash.each_key do |k|
72
+ unless keys.include?(k)
73
+ raise ArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{keys.map(&:inspect).join(', ')}")
74
+ end
75
+ end
76
+ end
77
+
78
+ def assert_hash_schema!(hash, schema, require_all)
79
+ return ASSERT_HASH_SCHEMA.all(hash, schema) if require_all
80
+
81
+ ASSERT_HASH_SCHEMA.any(hash, schema)
82
+ end
46
83
  end
47
84
 
48
85
  private_constant :STRICT
data/lib/kind/basic.rb CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  require 'kind/version'
4
4
 
5
- require 'kind/__lib__/kind'
6
5
  require 'kind/__lib__/undefined'
6
+ require 'kind/__lib__/kind'
7
7
 
8
8
  require 'kind/basic/undefined'
9
9
  require 'kind/basic/error'
@@ -76,4 +76,20 @@ module Kind
76
76
  def value(kind, value, default:)
77
77
  KIND.value(kind, value, of(kind, default))
78
78
  end
79
+
80
+ def or_nil(kind, value)
81
+ return value if kind === value
82
+ end
83
+
84
+ def in!(list, value)
85
+ STRICT.in!(list, value)
86
+ end
87
+
88
+ def include!(value, list)
89
+ STRICT.in!(list, value)
90
+ end
91
+
92
+ def assert_hash!(hash, **kargs)
93
+ STRICT.assert_hash!(hash, kargs)
94
+ end
79
95
  end
@@ -9,7 +9,7 @@ module Kind
9
9
  def value_or(default = UNDEFINED, &block)
10
10
  Error.invalid_default_arg! if UNDEFINED == default && !block
11
11
 
12
- UNDEFINED != default ? default : block.call
12
+ UNDEFINED != default ? default : block.call(value)
13
13
  end
14
14
 
15
15
  def map(&_)
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'kind/result'
4
3
  require 'kind/functional'
5
- require 'kind/__lib__/action_steps'
4
+ require 'kind/functional/steps'
6
5
 
7
6
  module Kind
8
7
  module Functional::Action
@@ -58,11 +57,9 @@ module Kind
58
57
  )
59
58
 
60
59
  if Kind.of_module?(self)
61
- self.send(:extend, Result::Methods)
62
- self.send(:extend, ACTION_STEPS)
60
+ self.send(:extend, Functional::Steps)
63
61
  else
64
- self.send(:include, Result::Methods)
65
- self.send(:include, ACTION_STEPS)
62
+ self.send(:include, Functional::Steps)
66
63
  self.send(:include, Functional::Behavior)
67
64
 
68
65
  __dependencies__.freeze
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'kind/basic'
4
+ require 'kind/empty'
5
+ require 'kind/result'
6
+ require 'kind/__lib__/action_steps'
7
+
8
+ module Kind
9
+ module Functional
10
+ module Steps
11
+ def self.extended(base)
12
+ base.extend(Result::Methods)
13
+ base.extend(ACTION_STEPS)
14
+ end
15
+
16
+ def self.included(base)
17
+ base.send(:include, Result::Methods)
18
+ base.send(:include, ACTION_STEPS)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -16,7 +16,7 @@ module Kind
16
16
  end
17
17
 
18
18
  def |(kind)
19
- self.class.new(@kinds + [Interface[kind]])
19
+ self.class.new(@kinds + [Interface[kind.nil? ? Kind::Nil : kind]])
20
20
  end
21
21
 
22
22
  def ===(value)
@@ -11,7 +11,7 @@ module Kind
11
11
  def value_or(default = UNDEFINED, &block)
12
12
  Error.invalid_default_arg! if UNDEFINED == default && !block
13
13
 
14
- UNDEFINED != default ? default : block.call
14
+ UNDEFINED != default ? default : block.call(value)
15
15
  end
16
16
 
17
17
  def map(_ = UNDEFINED, &_fn)
@@ -3,8 +3,14 @@
3
3
  module Kind
4
4
  module STRICT
5
5
  [
6
- :object_is_a, :class!, :kind_of,
7
- :module_or_class, :module!, :not_nil
6
+ :object_is_a,
7
+ :class!,
8
+ :kind_of,
9
+ :module_or_class,
10
+ :module!,
11
+ :not_nil,
12
+ :in!,
13
+ :assert_hash!
8
14
  ].each { |method_name| remove_method(method_name) }
9
15
 
10
16
  def object_is_a(_kind, value, _label = nil) # :nodoc:
@@ -30,5 +36,17 @@ module Kind
30
36
  def not_nil(value, label) # :nodoc:
31
37
  value
32
38
  end
39
+
40
+ def in!(list, value) # :nodoc:
41
+ value
42
+ end
43
+
44
+ def assert_hash!(hash, _options) # :nodoc:
45
+ hash
46
+ end
47
+
48
+ def assert_hash!(hash, _options) # :nodoc:
49
+ hash
50
+ end
33
51
  end
34
52
  end
data/lib/kind/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kind
4
- VERSION = '5.3.0'
4
+ VERSION = '5.7.0'
5
5
  end
metadata CHANGED
@@ -1,16 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kind
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.3.0
4
+ version: 5.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-23 00:00:00.000000000 Z
11
+ date: 2021-06-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: A simple type system (at runtime) for Ruby - free of dependencies.
13
+ description: A development toolkit for Ruby with several small/cohesive abstractions
14
+ (monads, enums, business logic, data validation...) to empower your development
15
+ workflow - It's totally free of dependencies.
14
16
  email:
15
17
  - rodrigo.serradura@gmail.com
16
18
  executables: []
@@ -32,6 +34,7 @@ files:
32
34
  - kind.gemspec
33
35
  - lib/kind.rb
34
36
  - lib/kind/__lib__/action_steps.rb
37
+ - lib/kind/__lib__/assert_hash_schema.rb
35
38
  - lib/kind/__lib__/attributes.rb
36
39
  - lib/kind/__lib__/kind.rb
37
40
  - lib/kind/__lib__/of.rb
@@ -57,6 +60,7 @@ files:
57
60
  - lib/kind/function.rb
58
61
  - lib/kind/functional.rb
59
62
  - lib/kind/functional/action.rb
63
+ - lib/kind/functional/steps.rb
60
64
  - lib/kind/immutable_attributes.rb
61
65
  - lib/kind/immutable_attributes/initializer.rb
62
66
  - lib/kind/immutable_attributes/reader.rb
@@ -141,5 +145,6 @@ requirements: []
141
145
  rubygems_version: 3.2.11
142
146
  signing_key:
143
147
  specification_version: 4
144
- summary: A simple type system (at runtime) for Ruby.
148
+ summary: A development toolkit for Ruby with several small/cohesive abstractions to
149
+ empower your development workflow.
145
150
  test_files: []