kind 4.0.0 → 4.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.
- 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
|