kind 4.0.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +59 -22
- data/README.md +110 -18
- data/lib/kind.rb +3 -3
- data/lib/kind/active_model/kind_validator.rb +13 -6
- data/lib/kind/core.rb +1 -0
- data/lib/kind/core/kind.rb +1 -1
- data/lib/kind/core/wrong_number_of_args.rb +9 -0
- data/lib/kind/dig.rb +1 -1
- data/lib/kind/maybe/none.rb +1 -1
- data/lib/kind/maybe/result.rb +1 -1
- data/lib/kind/maybe/some.rb +1 -1
- data/lib/kind/maybe/typed.rb +2 -2
- data/lib/kind/maybe/wrappable.rb +2 -4
- data/lib/kind/try.rb +0 -2
- data/lib/kind/type_checker.rb +14 -0
- data/lib/kind/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ffb9807682a295f94cb8e4076d32fc3217da97268e943e7d6b028b6de95ed765
|
4
|
+
data.tar.gz: 7b61164996c0d96853ad5a0cde9269ecd18bb489b483b46956a7fa2e9b9f2cd6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f23b38b9f63d03638ded172c037b6ba9e048c397e9a31907850beca5151822c4983129e5726b777ccbdb30db18c8bcdfb9392c813c3e05546dfd33f97db9660
|
7
|
+
data.tar.gz: 3d7e663d65a591bff7bfeb152dd4e605948df7e95de15bb3632be0f52c747fd522041fc1be7678c8385cd9c0606a688abd203348e376ce264f3088d62ecb5f88
|
data/CHANGELOG.md
CHANGED
@@ -3,61 +3,63 @@
|
|
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
|
-
- [4.
|
6
|
+
- [4.1.0 (2021-02-22)](#410-2021-02-22)
|
7
7
|
- [Added](#added)
|
8
|
+
- [4.0.0 (2021-02-22)](#400-2021-02-22)
|
9
|
+
- [Added](#added-1)
|
8
10
|
- [Deprecated](#deprecated)
|
9
11
|
- [Fixed](#fixed)
|
10
12
|
- [3.1.0 (2020-07-08)](#310-2020-07-08)
|
11
|
-
- [Added](#added-
|
13
|
+
- [Added](#added-2)
|
12
14
|
- [3.0.0 (2020-06-25)](#300-2020-06-25)
|
13
15
|
- [Breaking Changes](#breaking-changes)
|
14
|
-
- [Added](#added-2)
|
15
|
-
- [2.3.0 (2020-06-24)](#230-2020-06-24)
|
16
16
|
- [Added](#added-3)
|
17
|
-
- [2.
|
17
|
+
- [2.3.0 (2020-06-24)](#230-2020-06-24)
|
18
18
|
- [Added](#added-4)
|
19
|
-
- [2.
|
19
|
+
- [2.2.0 (2020-06-23)](#220-2020-06-23)
|
20
20
|
- [Added](#added-5)
|
21
|
+
- [2.1.0 (2020-05-12)](#210-2020-05-12)
|
22
|
+
- [Added](#added-6)
|
21
23
|
- [Breaking Changes](#breaking-changes-1)
|
22
24
|
- [2.0.0 (2020-05-07)](#200-2020-05-07)
|
23
|
-
- [Added](#added-
|
25
|
+
- [Added](#added-7)
|
24
26
|
- [Breaking Changes](#breaking-changes-2)
|
25
27
|
- [Removed](#removed)
|
26
28
|
- [1.9.0 (2020-05-06)](#190-2020-05-06)
|
27
|
-
- [Added](#added-7)
|
28
|
-
- [1.8.0 (2020-05-03)](#180-2020-05-03)
|
29
29
|
- [Added](#added-8)
|
30
|
+
- [1.8.0 (2020-05-03)](#180-2020-05-03)
|
31
|
+
- [Added](#added-9)
|
30
32
|
- [1.7.0 (2020-05-03)](#170-2020-05-03)
|
31
33
|
- [Fixed](#fixed-1)
|
32
34
|
- [1.6.0 (2020-04-17)](#160-2020-04-17)
|
33
|
-
- [Added](#added-
|
35
|
+
- [Added](#added-10)
|
34
36
|
- [Changes](#changes)
|
35
37
|
- [1.5.0 (2020-04-12)](#150-2020-04-12)
|
36
|
-
- [Added](#added-10)
|
37
|
-
- [1.4.0 (2020-04-12)](#140-2020-04-12)
|
38
38
|
- [Added](#added-11)
|
39
|
-
- [1.
|
39
|
+
- [1.4.0 (2020-04-12)](#140-2020-04-12)
|
40
40
|
- [Added](#added-12)
|
41
|
-
- [1.
|
41
|
+
- [1.3.0 (2020-04-12)](#130-2020-04-12)
|
42
42
|
- [Added](#added-13)
|
43
|
-
- [1.
|
43
|
+
- [1.2.0 (2020-04-12)](#120-2020-04-12)
|
44
44
|
- [Added](#added-14)
|
45
|
+
- [1.1.0 (2020-04-09)](#110-2020-04-09)
|
46
|
+
- [Added](#added-15)
|
45
47
|
- [Fixed](#fixed-2)
|
46
48
|
- [1.0.0 (2020-03-16)](#100-2020-03-16)
|
47
|
-
- [Added](#added-15)
|
48
|
-
- [0.6.0 (2020-01-06)](#060-2020-01-06)
|
49
49
|
- [Added](#added-16)
|
50
|
-
- [0.
|
50
|
+
- [0.6.0 (2020-01-06)](#060-2020-01-06)
|
51
51
|
- [Added](#added-17)
|
52
|
-
- [0.
|
52
|
+
- [0.5.0 (2020-01-04)](#050-2020-01-04)
|
53
53
|
- [Added](#added-18)
|
54
|
-
- [0.
|
54
|
+
- [0.4.0 (2020-01-03)](#040-2020-01-03)
|
55
55
|
- [Added](#added-19)
|
56
|
+
- [0.3.0 (2020-01-03)](#030-2020-01-03)
|
57
|
+
- [Added](#added-20)
|
56
58
|
- [Breaking Changes](#breaking-changes-3)
|
57
59
|
- [0.2.0 (2020-01-02)](#020-2020-01-02)
|
58
|
-
- [Added](#added-20)
|
59
|
-
- [0.1.0 (2019-12-26)](#010-2019-12-26)
|
60
60
|
- [Added](#added-21)
|
61
|
+
- [0.1.0 (2019-12-26)](#010-2019-12-26)
|
62
|
+
- [Added](#added-22)
|
61
63
|
|
62
64
|
## Unreleased
|
63
65
|
|
@@ -69,6 +71,41 @@ This project follows [semver 2.0.0](http://semver.org/spec/v2.0.0.html) and the
|
|
69
71
|
### Fixed
|
70
72
|
-->
|
71
73
|
|
74
|
+
4.1.0 (2021-02-22)
|
75
|
+
------------------
|
76
|
+
|
77
|
+
### Added
|
78
|
+
|
79
|
+
* [#43](https://github.com/serradura/kind/pull/43) - Make `Kind::Maybe::Typed` verify the kind of the value via `===`, because of this, now is possible to use type checkers in typed Maybes.
|
80
|
+
```ruby
|
81
|
+
Kind::Maybe(Kind::Boolean).wrap(nil).value_or(false) # false
|
82
|
+
|
83
|
+
Kind::Maybe(Kind::Boolean).wrap(true).value_or(false) # true
|
84
|
+
```
|
85
|
+
|
86
|
+
* [#43](https://github.com/serradura/kind/pull/43) - Add `Kind::<Type>.maybe` and `Kind::<Type>.optional`. This method returns a typed Maybe with the expected kind when it is invoked without arguments. But, if it receives arguments, it will behave like the `Kind::Maybe.wrap` method. e.g.
|
87
|
+
```ruby
|
88
|
+
Kind::Integer.maybe #<Kind::Maybe::Typed:0x0000... @kind=Kind::Integer>
|
89
|
+
|
90
|
+
Kind::Integer.maybe(0).some? # true
|
91
|
+
Kind::Integer.maybe { 1 }.some? # true
|
92
|
+
Kind::Integer.maybe(2) { |n| n * 2 }.some? # true
|
93
|
+
|
94
|
+
Kind::Integer.maybe { 2 / 0 }.none? # true
|
95
|
+
Kind::Integer.maybe(2) { |n| n / 0 }.none? # true
|
96
|
+
Kind::Integer.maybe('2') { |n| n * n }.none? # true
|
97
|
+
```
|
98
|
+
|
99
|
+
* [#43](https://github.com/serradura/kind/pull/43) - Make the `:respond_to` kind validation verify by one or multiple methods. e.g.
|
100
|
+
```ruby
|
101
|
+
validates :params, kind: { respond_to: [:[], :values_at] }
|
102
|
+
```
|
103
|
+
|
104
|
+
* [#43](https://github.com/serradura/kind/pull/43) - Make the `:of` kind validation verify the expected value kind using `===`, because of this, now is possible to use type checkers as expected kinds. e.g.
|
105
|
+
```ruby
|
106
|
+
validates :alive, kind: Kind::Boolean
|
107
|
+
```
|
108
|
+
|
72
109
|
4.0.0 (2021-02-22)
|
73
110
|
------------------
|
74
111
|
|
data/README.md
CHANGED
@@ -35,7 +35,7 @@ One of the goals of this project is to do simple type checking like `"some strin
|
|
35
35
|
Version | Documentation
|
36
36
|
---------- | -------------
|
37
37
|
unreleased | https://github.com/serradura/u-case/blob/main/README.md
|
38
|
-
4.
|
38
|
+
4.1.0 | https://github.com/serradura/u-case/blob/v4.x/README.md
|
39
39
|
3.1.0 | https://github.com/serradura/u-case/blob/v3.x/README.md
|
40
40
|
2.3.0 | https://github.com/serradura/u-case/blob/v2.x/README.md
|
41
41
|
1.9.0 | https://github.com/serradura/u-case/blob/v1.x/README.md
|
@@ -51,9 +51,10 @@ unreleased | https://github.com/serradura/u-case/blob/main/README.md
|
|
51
51
|
- [Kind::\<Type\>.or_undefined()](#kindtypeor_undefined)
|
52
52
|
- [Kind::\<Type\>.or()](#kindtypeor)
|
53
53
|
- [Kind::\<Type\>.value()](#kindtypevalue-1)
|
54
|
+
- [Kind::\<Type\>.maybe](#kindtypemaybe)
|
54
55
|
- [Kind::\<Type\>?](#kindtype-2)
|
55
56
|
- [Kind::{Array,Hash,String,Set}.value_or_empty()](#kindarrayhashstringsetvalue_or_empty)
|
56
|
-
- [List of all type checkers
|
57
|
+
- [List of all type checkers](#list-of-all-type-checkers)
|
57
58
|
- [Core](#core)
|
58
59
|
- [Stdlib](#stdlib)
|
59
60
|
- [Custom](#custom)
|
@@ -92,11 +93,18 @@ unreleased | https://github.com/serradura/u-case/blob/main/README.md
|
|
92
93
|
- [Kind::Maybe#try!](#kindmaybetry-1)
|
93
94
|
- [Kind::Maybe#dig](#kindmaybedig)
|
94
95
|
- [Kind::Maybe#check](#kindmaybecheck)
|
96
|
+
- [Kind::Maybe#presence](#kindmaybepresence)
|
95
97
|
- [Kind::Empty](#kindempty)
|
96
98
|
- [Kind::Validator (ActiveModel::Validations)](#kindvalidator-activemodelvalidations)
|
97
99
|
- [Usage](#usage-1)
|
98
|
-
- [
|
99
|
-
- [
|
100
|
+
- [Object#===](#object)
|
101
|
+
- [Kind.is](#kindis-1)
|
102
|
+
- [Object#instance_of?](#objectinstance_of)
|
103
|
+
- [Object#respond_to?](#objectrespond_to)
|
104
|
+
- [Array.new.all? { |item| item.kind_of?(Class) }](#arraynewall--item-itemkind_ofclass-)
|
105
|
+
- [Array.new.all? { |item| expected_values.include?(item) }](#arraynewall--item-expected_valuesincludeitem-)
|
106
|
+
- [Defining the default validation strategy](#defining-the-default-validation-strategy)
|
107
|
+
- [Using the `allow_nil` and `strict` options](#using-the-allow_nil-and-strict-options)
|
100
108
|
- [Similar Projects](#similar-projects)
|
101
109
|
- [Development](#development)
|
102
110
|
- [Contributing](#contributing)
|
@@ -108,7 +116,7 @@ unreleased | https://github.com/serradura/u-case/blob/main/README.md
|
|
108
116
|
| u-case | branch | ruby | activemodel |
|
109
117
|
| -------------- | ------- | -------- | -------------- |
|
110
118
|
| unreleased | main | >= 2.2.0 | >= 3.2, <= 6.1 |
|
111
|
-
| 4.
|
119
|
+
| 4.1.0 | v4.x | >= 2.2.0 | >= 3.2, <= 6.1 |
|
112
120
|
| 3.1.0 | v3.x | >= 2.2.0 | >= 3.2, <= 6.1 |
|
113
121
|
| 2.3.0 | v2.x | >= 2.2.0 | >= 3.2, <= 6.0 |
|
114
122
|
| 1.9.0 | v1.x | >= 2.2.0 | >= 3.2, <= 6.0 |
|
@@ -257,6 +265,39 @@ Kind::String.value('1', default: 1) # Kind::Error (1 expected to be a kind of S
|
|
257
265
|
|
258
266
|
[⬆️ Back to Top](#table-of-contents-)
|
259
267
|
|
268
|
+
### Kind::\<Type\>.maybe
|
269
|
+
|
270
|
+
This method exposes a [typed `Kind::Maybe`](#kindmaybetype) and using it will be possible to apply a sequence of operations in the case of the wrapped value has the expected kind.
|
271
|
+
|
272
|
+
```ruby
|
273
|
+
Double = ->(value) do
|
274
|
+
Kind::Numeric.maybe(value)
|
275
|
+
.then { |number| number * 2 }
|
276
|
+
.value_or(0)
|
277
|
+
end
|
278
|
+
|
279
|
+
Double.('2') # 0
|
280
|
+
Double.(2) # 4
|
281
|
+
```
|
282
|
+
|
283
|
+
If it is invoked without arguments, it returns the typed Maybe. But, if it receives arguments, it will behave like the `Kind::Maybe.wrap` method. e.g.
|
284
|
+
|
285
|
+
```ruby
|
286
|
+
Kind::Integer.maybe #<Kind::Maybe::Typed:0x0000... @kind=Kind::Integer>
|
287
|
+
|
288
|
+
Kind::Integer.maybe(0).some? # true
|
289
|
+
Kind::Integer.maybe { 1 }.some? # true
|
290
|
+
Kind::Integer.maybe(2) { |n| n * 2 }.some? # true
|
291
|
+
|
292
|
+
Kind::Integer.maybe { 2 / 0 }.none? # true
|
293
|
+
Kind::Integer.maybe(2) { |n| n / 0 }.none? # true
|
294
|
+
Kind::Integer.maybe('2') { |n| n * n }.none? # true
|
295
|
+
```
|
296
|
+
|
297
|
+
> **Note:** You can use `Kind::\<Type\>.optional` as an alias for `Kind::\<Type\>.maybe`.
|
298
|
+
|
299
|
+
[⬆️ Back to Top](#table-of-contents-)
|
300
|
+
|
260
301
|
### Kind::\<Type\>?
|
261
302
|
|
262
303
|
There is a second way to do a type verification and know if one or multiple values has the expected type. You can use the predicate kind methods (`Kind::Hash?`). e.g:
|
@@ -289,7 +330,7 @@ Kind::Array.value_or_empty({}).frozen? # true
|
|
289
330
|
|
290
331
|
[⬆️ Back to Top](#table-of-contents-)
|
291
332
|
|
292
|
-
### List of all type checkers
|
333
|
+
### List of all type checkers
|
293
334
|
|
294
335
|
#### Core
|
295
336
|
|
@@ -396,6 +437,10 @@ kind_of_user.value(User.new, default: User.new) # #<User:0x0000...>
|
|
396
437
|
kind_of_user.value('1', default: User.new) # #<User:0x0000...>
|
397
438
|
|
398
439
|
kind_of_user.value('1', default: 1) # Kind::Error (1 expected to be a kind of User)
|
440
|
+
|
441
|
+
# kind_of_user.maybe
|
442
|
+
# This method returns a typed Kind::Maybe.
|
443
|
+
kind_of_user.maybe('1').value_or(User.new) # #<User:0x0000...>
|
399
444
|
```
|
400
445
|
|
401
446
|
[⬆️ Back to Top](#table-of-contents-)
|
@@ -463,6 +508,12 @@ PositiveInteger.value(2, default: 1) # 2
|
|
463
508
|
PositiveInteger.value('1', default: 1) # 1
|
464
509
|
|
465
510
|
PositiveInteger.value('1', default: 0) # Kind::Error (0 expected to be a kind of PositiveInteger)
|
511
|
+
|
512
|
+
# PositiveInteger.maybe
|
513
|
+
# This method returns a typed Kind::Maybe.
|
514
|
+
PositiveInteger.maybe(0).value_or(1) # 1
|
515
|
+
|
516
|
+
PositiveInteger.maybe(2).value_or(1) # 2
|
466
517
|
```
|
467
518
|
|
468
519
|
[⬆️ Back to Top](#table-of-contents-)
|
@@ -1099,7 +1150,7 @@ def person_name(params)
|
|
1099
1150
|
|
1100
1151
|
return default if names.size != 2
|
1101
1152
|
|
1102
|
-
first_name, last_name =
|
1153
|
+
first_name, last_name = names
|
1103
1154
|
|
1104
1155
|
"#{first_name} #{last_name}"
|
1105
1156
|
end
|
@@ -1126,7 +1177,7 @@ module PersonIntroduction1
|
|
1126
1177
|
end
|
1127
1178
|
|
1128
1179
|
def age(optional)
|
1129
|
-
optional.
|
1180
|
+
optional.dig(:age).value_or(0)
|
1130
1181
|
end
|
1131
1182
|
end
|
1132
1183
|
|
@@ -1336,6 +1387,18 @@ Kind::Maybe(Array)
|
|
1336
1387
|
|
1337
1388
|
[⬆️ Back to Top](#table-of-contents-)
|
1338
1389
|
|
1390
|
+
### Kind::Maybe#presence
|
1391
|
+
|
1392
|
+
This method will return None if the wrapped value wasn't present.
|
1393
|
+
|
1394
|
+
```ruby
|
1395
|
+
result = Kind::Maybe(Hash).wrap(foo: '').dig(:foo).presence
|
1396
|
+
result.none? # true
|
1397
|
+
result.value # nil
|
1398
|
+
```
|
1399
|
+
|
1400
|
+
[⬆️ Back to Top](#table-of-contents-)
|
1401
|
+
|
1339
1402
|
## Kind::Empty
|
1340
1403
|
|
1341
1404
|
When you define a method that has default arguments, for certain data types, you will always create a new object in memory. e.g:
|
@@ -1407,20 +1470,31 @@ gem 'kind', require: 'kind/active_model/validation'
|
|
1407
1470
|
require 'kind/active_model/validation'
|
1408
1471
|
```
|
1409
1472
|
|
1473
|
+
[⬆️ Back to Top](#table-of-contents-)
|
1474
|
+
|
1410
1475
|
### Usage
|
1411
1476
|
|
1412
|
-
|
1477
|
+
#### [Object#===](https://ruby-doc.org/core-3.0.0/Object.html#method-i-3D-3D-3D)
|
1413
1478
|
|
1414
1479
|
```ruby
|
1415
1480
|
validates :name, kind: { of: String }
|
1481
|
+
```
|
1416
1482
|
|
1417
|
-
|
1418
|
-
# is an instance of one of the classes/modules.
|
1483
|
+
Use an array to verify if the attribute is an instance of one of the classes/modules.
|
1419
1484
|
|
1485
|
+
```ruby
|
1420
1486
|
validates :status, kind: { of: [String, Symbol]}
|
1421
1487
|
```
|
1422
1488
|
|
1423
|
-
|
1489
|
+
Because of kind verification be made via `===` you can use type checkers as the expected kinds.
|
1490
|
+
|
1491
|
+
```ruby
|
1492
|
+
validates :alive, kind: Kind::Boolean
|
1493
|
+
```
|
1494
|
+
|
1495
|
+
[⬆️ Back to Top](#table-of-contents-)
|
1496
|
+
|
1497
|
+
#### [Kind.is](#verifying-the-kind-of-some-classmodule)
|
1424
1498
|
|
1425
1499
|
```ruby
|
1426
1500
|
#
|
@@ -1456,7 +1530,9 @@ validates :human_kind, kind: { is: Human }
|
|
1456
1530
|
validates :human_kind, kind: { is: [Person, User] }
|
1457
1531
|
```
|
1458
1532
|
|
1459
|
-
|
1533
|
+
[⬆️ Back to Top](#table-of-contents-)
|
1534
|
+
|
1535
|
+
#### [Object#instance_of?](https://ruby-doc.org/core-3.0.0/Object.html#method-i-instance_of-3F)
|
1460
1536
|
|
1461
1537
|
```ruby
|
1462
1538
|
validates :name, kind: { instance_of: String }
|
@@ -1467,13 +1543,23 @@ validates :name, kind: { instance_of: String }
|
|
1467
1543
|
validates :name, kind: { instance_of: [String, Symbol] }
|
1468
1544
|
```
|
1469
1545
|
|
1470
|
-
|
1546
|
+
[⬆️ Back to Top](#table-of-contents-)
|
1547
|
+
|
1548
|
+
#### [Object#respond_to?](https://ruby-doc.org/core-3.0.0/Object.html#method-i-respond_to-3F)
|
1471
1549
|
|
1472
1550
|
```ruby
|
1473
1551
|
validates :handler, kind: { respond_to: :call }
|
1474
1552
|
```
|
1475
1553
|
|
1476
|
-
|
1554
|
+
This validation can verify one or multiple methods.
|
1555
|
+
|
1556
|
+
```ruby
|
1557
|
+
validates :params, kind: { respond_to: [:[], :values_at] }
|
1558
|
+
```
|
1559
|
+
|
1560
|
+
[⬆️ Back to Top](#table-of-contents-)
|
1561
|
+
|
1562
|
+
#### Array.new.all? { |item| item.kind_of?(Class) }
|
1477
1563
|
|
1478
1564
|
```ruby
|
1479
1565
|
validates :account_types, kind: { array_of: String }
|
@@ -1484,7 +1570,9 @@ validates :account_types, kind: { array_of: String }
|
|
1484
1570
|
validates :account_types, kind: { array_of: [String, Symbol] }
|
1485
1571
|
```
|
1486
1572
|
|
1487
|
-
|
1573
|
+
[⬆️ Back to Top](#table-of-contents-)
|
1574
|
+
|
1575
|
+
#### Array.new.all? { |item| expected_values.include?(item) }
|
1488
1576
|
|
1489
1577
|
```ruby
|
1490
1578
|
# Verifies if the attribute value
|
@@ -1493,7 +1581,9 @@ validates :account_types, kind: { array_of: [String, Symbol] }
|
|
1493
1581
|
validates :account_types, kind: { array_with: ['foo', 'bar'] }
|
1494
1582
|
```
|
1495
1583
|
|
1496
|
-
|
1584
|
+
[⬆️ Back to Top](#table-of-contents-)
|
1585
|
+
|
1586
|
+
### Defining the default validation strategy
|
1497
1587
|
|
1498
1588
|
By default, you can define the attribute type directly (without a hash). e.g.
|
1499
1589
|
|
@@ -1515,7 +1605,9 @@ And these are the available options to define the default strategy:
|
|
1515
1605
|
- `kind_of` *(default)*
|
1516
1606
|
- `instance_of`
|
1517
1607
|
|
1518
|
-
|
1608
|
+
[⬆️ Back to Top](#table-of-contents-)
|
1609
|
+
|
1610
|
+
### Using the `allow_nil` and `strict` options
|
1519
1611
|
|
1520
1612
|
You can use the `allow_nil` option with any of the kind validations. e.g.
|
1521
1613
|
|
data/lib/kind.rb
CHANGED
@@ -12,10 +12,10 @@ require 'kind/dig'
|
|
12
12
|
require 'kind/try'
|
13
13
|
require 'kind/presence'
|
14
14
|
require 'kind/undefined'
|
15
|
-
require 'kind/
|
15
|
+
require 'kind/maybe'
|
16
16
|
|
17
|
+
require 'kind/type_checker'
|
17
18
|
require 'kind/type_checkers'
|
18
|
-
require 'kind/maybe'
|
19
19
|
|
20
20
|
require 'kind/deprecations/checker'
|
21
21
|
require 'kind/deprecations/of'
|
@@ -59,7 +59,7 @@ module Kind
|
|
59
59
|
|
60
60
|
return is?(expected, object) if UNDEFINED != object
|
61
61
|
|
62
|
-
|
62
|
+
WRONG_NUMBER_OF_ARGS.error!(given: 1, expected: 2)
|
63
63
|
end
|
64
64
|
|
65
65
|
def self.of(kind = UNDEFINED, object = UNDEFINED)
|
@@ -35,9 +35,9 @@ class KindValidator < ActiveModel::EachValidator
|
|
35
35
|
def kind_of(expected, value)
|
36
36
|
types = Array(expected)
|
37
37
|
|
38
|
-
return if types.any? { |type|
|
38
|
+
return if types.any? { |type| type === value }
|
39
39
|
|
40
|
-
"must be a kind of: #{types.map { |
|
40
|
+
"must be a kind of: #{types.map { |type| type.name }.join(', ')}"
|
41
41
|
end
|
42
42
|
|
43
43
|
CLASS_OR_MODULE = 'Class/Module'.freeze
|
@@ -45,7 +45,7 @@ class KindValidator < ActiveModel::EachValidator
|
|
45
45
|
def kind_is(expected, value)
|
46
46
|
return kind_is_not(expected, value) unless expected.kind_of?(::Array)
|
47
47
|
|
48
|
-
result = expected.map { |kind| kind_is_not(kind, value) }.compact
|
48
|
+
result = expected.map { |kind| kind_is_not(kind, value) }.tap(&:compact!)
|
49
49
|
|
50
50
|
result.empty? || result.size < expected.size ? nil : result.join(', ')
|
51
51
|
end
|
@@ -66,10 +66,17 @@ class KindValidator < ActiveModel::EachValidator
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
def respond_to(
|
70
|
-
|
69
|
+
def respond_to(expected, value)
|
70
|
+
method_names = Array(expected)
|
71
71
|
|
72
|
-
|
72
|
+
expected_methods = method_names.select { |method_name| !value.respond_to?(method_name) }
|
73
|
+
expected_methods.map! { |method_name| "`#{method_name}`" }
|
74
|
+
|
75
|
+
return if expected_methods.empty?
|
76
|
+
|
77
|
+
methods = expected_methods.size == 1 ? 'method' : 'methods'
|
78
|
+
|
79
|
+
"must respond to the #{methods}: #{expected_methods.join(', ')}"
|
73
80
|
end
|
74
81
|
|
75
82
|
def instance_of(expected, value)
|
data/lib/kind/core.rb
CHANGED
data/lib/kind/core/kind.rb
CHANGED
@@ -27,7 +27,7 @@ module Kind
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def self.of_module?(value) # :nodoc:
|
30
|
-
::Module == value || (value.
|
30
|
+
::Module == value || (value.kind_of?(::Module) && !of_class?(value))
|
31
31
|
end
|
32
32
|
|
33
33
|
def self.of_module_or_class!(value) # :nodoc:
|
data/lib/kind/dig.rb
CHANGED
data/lib/kind/maybe/none.rb
CHANGED
data/lib/kind/maybe/result.rb
CHANGED
data/lib/kind/maybe/some.rb
CHANGED
data/lib/kind/maybe/typed.rb
CHANGED
@@ -12,7 +12,7 @@ module Kind
|
|
12
12
|
def new(arg)
|
13
13
|
value = Result::Value.(arg)
|
14
14
|
|
15
|
-
|
15
|
+
@kind === value ? Maybe.some(value) : Maybe.none
|
16
16
|
end
|
17
17
|
|
18
18
|
alias_method :[], :new
|
@@ -22,7 +22,7 @@ module Kind
|
|
22
22
|
def __call_before_expose_the_arg_in_a_block(arg)
|
23
23
|
value = Result::Value.(arg)
|
24
24
|
|
25
|
-
|
25
|
+
@kind === value ? value : Maybe.none
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
data/lib/kind/maybe/wrappable.rb
CHANGED
@@ -3,8 +3,6 @@
|
|
3
3
|
module Kind
|
4
4
|
module Maybe
|
5
5
|
module Wrappable
|
6
|
-
WRONG_NUMBER_OF_ARGS = 'wrong number of arguments (given 0, expected 1)'.freeze
|
7
|
-
|
8
6
|
def wrap(arg = UNDEFINED)
|
9
7
|
if block_given?
|
10
8
|
begin
|
@@ -12,14 +10,14 @@ module Kind
|
|
12
10
|
|
13
11
|
input = __call_before_expose_the_arg_in_a_block(arg)
|
14
12
|
|
15
|
-
input.kind_of?(
|
13
|
+
input.kind_of?(Maybe::None) ? input : new(yield(input))
|
16
14
|
rescue StandardError => exception
|
17
15
|
Maybe.__none__(exception)
|
18
16
|
end
|
19
17
|
else
|
20
18
|
return new(arg) if UNDEFINED != arg
|
21
19
|
|
22
|
-
|
20
|
+
WRONG_NUMBER_OF_ARGS.error!(given: 0, expected: 1)
|
23
21
|
end
|
24
22
|
end
|
25
23
|
|
data/lib/kind/try.rb
CHANGED
data/lib/kind/type_checker.rb
CHANGED
@@ -44,8 +44,22 @@ module Kind
|
|
44
44
|
KIND.null?(value) ? value : self[value]
|
45
45
|
end
|
46
46
|
|
47
|
+
def maybe(value = UNDEFINED, &block)
|
48
|
+
return __maybe[value] if UNDEFINED != value && !block
|
49
|
+
return __maybe.wrap(&block) if UNDEFINED == value && block
|
50
|
+
return __maybe.wrap(value, &block) if UNDEFINED != value && block
|
51
|
+
|
52
|
+
__maybe
|
53
|
+
end
|
54
|
+
|
55
|
+
alias optional maybe
|
56
|
+
|
47
57
|
private
|
48
58
|
|
59
|
+
def __maybe
|
60
|
+
@__maybe ||= Maybe::Typed.new(self)
|
61
|
+
end
|
62
|
+
|
49
63
|
def __or_func
|
50
64
|
@__or_func ||= ->(tc, fb, value) { tc === value ? value : tc.or_null(fb) }.curry[self]
|
51
65
|
end
|
data/lib/kind/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kind
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rodrigo Serradura
|
@@ -37,6 +37,7 @@ files:
|
|
37
37
|
- lib/kind/core/deprecation.rb
|
38
38
|
- lib/kind/core/kind.rb
|
39
39
|
- lib/kind/core/undefined.rb
|
40
|
+
- lib/kind/core/wrong_number_of_args.rb
|
40
41
|
- lib/kind/deprecations/built_in_type_checkers.rb
|
41
42
|
- lib/kind/deprecations/checker.rb
|
42
43
|
- lib/kind/deprecations/checker/factory.rb
|