kind 5.2.0 → 5.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/.travis.sh +2 -0
- data/CHANGELOG.md +66 -25
- data/README.md +2 -2
- data/lib/kind/__lib__/action_steps.rb +57 -0
- data/lib/kind/__lib__/attributes.rb +1 -1
- data/lib/kind/__lib__/kind.rb +6 -26
- data/lib/kind/__lib__/of.rb +17 -0
- data/lib/kind/__lib__/strict.rb +49 -0
- data/lib/kind/action.rb +36 -1
- data/lib/kind/basic.rb +12 -6
- data/lib/kind/dig.rb +2 -2
- data/lib/kind/function.rb +1 -3
- data/lib/kind/functional.rb +2 -2
- data/lib/kind/functional/action.rb +6 -5
- data/lib/kind/immutable_attributes/reader.rb +1 -1
- data/lib/kind/maybe.rb +1 -1
- data/lib/kind/maybe/none.rb +1 -1
- data/lib/kind/maybe/some.rb +5 -5
- data/lib/kind/objects/basic_object.rb +2 -4
- data/lib/kind/objects/not_nil.rb +1 -5
- data/lib/kind/objects/object.rb +1 -1
- data/lib/kind/objects/respond_to.rb +1 -1
- data/lib/kind/presence.rb +1 -1
- data/lib/kind/result/failure.rb +3 -1
- data/lib/kind/result/monad.rb +9 -4
- data/lib/kind/result/success.rb +22 -9
- data/lib/kind/strict/disabled.rb +34 -0
- data/lib/kind/try.rb +2 -2
- data/lib/kind/validator.rb +1 -1
- data/lib/kind/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b826449cc89c4cd8dc3d58694a37914f7de37cb7000a2ba534ffa914f10f7677
|
|
4
|
+
data.tar.gz: e2ed88bcf83d332de58a8516533a58f858494e7ac2ea60f58517e08cd11066c9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ac5f74a2ba85be82a6b9709745069047105ccdf8aacadbabdb7e96f66ff007dd0e7ce8e2001df206614c3bf852cb95f3c9d21d2f203490a39070a92bb2250afd
|
|
7
|
+
data.tar.gz: 14b4f8b747a25b9c9535f40972dcfbc07116f97051090616053c663dbfe71cc5b8771bc5899da4e51a77168acb18a18a8c0b898a37c6730397d5c3a4afdc340b
|
data/.travis.sh
CHANGED
|
@@ -21,6 +21,8 @@ function run_basic_tests {
|
|
|
21
21
|
eval "KIND_BASIC=t $bundle_cmd exec rake test TEST='test/kind/{functional/*_test,functional_test}.rb'"
|
|
22
22
|
eval "KIND_BASIC=t $bundle_cmd exec rake test TEST='test/kind/either/*_test.rb'"
|
|
23
23
|
eval "KIND_BASIC=t $bundle_cmd exec rake test TEST='test/kind/result/*_test.rb'"
|
|
24
|
+
|
|
25
|
+
eval "KIND_STRICT=t $bundle_cmd exec rake test TEST='test/kind/strict_disabled_test.rb'"
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
function run_with_bundler {
|
data/CHANGELOG.md
CHANGED
|
@@ -3,73 +3,75 @@
|
|
|
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.
|
|
6
|
+
- [5.3.0 (2021-03-23)](#530-2021-03-23)
|
|
7
7
|
- [Added](#added)
|
|
8
|
+
- [5.2.0 (2021-03-17)](#520-2021-03-17)
|
|
9
|
+
- [Added](#added-1)
|
|
8
10
|
- [Deprecated](#deprecated)
|
|
9
11
|
- [Changes](#changes)
|
|
10
12
|
- [5.1.0 (2021-02-23)](#510-2021-02-23)
|
|
11
|
-
- [Added](#added-
|
|
13
|
+
- [Added](#added-2)
|
|
12
14
|
- [Deprecated](#deprecated-1)
|
|
13
15
|
- [5.0.0 (2021-02-22)](#500-2021-02-22)
|
|
14
16
|
- [Breaking Changes](#breaking-changes)
|
|
15
17
|
- [Removed](#removed)
|
|
16
18
|
- [4.1.0 (2021-02-22)](#410-2021-02-22)
|
|
17
|
-
- [Added](#added-2)
|
|
18
|
-
- [4.0.0 (2021-02-22)](#400-2021-02-22)
|
|
19
19
|
- [Added](#added-3)
|
|
20
|
+
- [4.0.0 (2021-02-22)](#400-2021-02-22)
|
|
21
|
+
- [Added](#added-4)
|
|
20
22
|
- [Deprecated](#deprecated-2)
|
|
21
23
|
- [Fixed](#fixed)
|
|
22
24
|
- [3.1.0 (2020-07-08)](#310-2020-07-08)
|
|
23
|
-
- [Added](#added-
|
|
25
|
+
- [Added](#added-5)
|
|
24
26
|
- [3.0.0 (2020-06-25)](#300-2020-06-25)
|
|
25
27
|
- [Breaking Changes](#breaking-changes-1)
|
|
26
|
-
- [Added](#added-5)
|
|
27
|
-
- [2.3.0 (2020-06-24)](#230-2020-06-24)
|
|
28
28
|
- [Added](#added-6)
|
|
29
|
-
- [2.
|
|
29
|
+
- [2.3.0 (2020-06-24)](#230-2020-06-24)
|
|
30
30
|
- [Added](#added-7)
|
|
31
|
-
- [2.
|
|
31
|
+
- [2.2.0 (2020-06-23)](#220-2020-06-23)
|
|
32
32
|
- [Added](#added-8)
|
|
33
|
+
- [2.1.0 (2020-05-12)](#210-2020-05-12)
|
|
34
|
+
- [Added](#added-9)
|
|
33
35
|
- [Breaking Changes](#breaking-changes-2)
|
|
34
36
|
- [2.0.0 (2020-05-07)](#200-2020-05-07)
|
|
35
|
-
- [Added](#added-
|
|
37
|
+
- [Added](#added-10)
|
|
36
38
|
- [Breaking Changes](#breaking-changes-3)
|
|
37
39
|
- [Removed](#removed-1)
|
|
38
40
|
- [1.9.0 (2020-05-06)](#190-2020-05-06)
|
|
39
|
-
- [Added](#added-10)
|
|
40
|
-
- [1.8.0 (2020-05-03)](#180-2020-05-03)
|
|
41
41
|
- [Added](#added-11)
|
|
42
|
+
- [1.8.0 (2020-05-03)](#180-2020-05-03)
|
|
43
|
+
- [Added](#added-12)
|
|
42
44
|
- [1.7.0 (2020-05-03)](#170-2020-05-03)
|
|
43
45
|
- [Fixed](#fixed-1)
|
|
44
46
|
- [1.6.0 (2020-04-17)](#160-2020-04-17)
|
|
45
|
-
- [Added](#added-
|
|
47
|
+
- [Added](#added-13)
|
|
46
48
|
- [Changes](#changes-1)
|
|
47
49
|
- [1.5.0 (2020-04-12)](#150-2020-04-12)
|
|
48
|
-
- [Added](#added-13)
|
|
49
|
-
- [1.4.0 (2020-04-12)](#140-2020-04-12)
|
|
50
50
|
- [Added](#added-14)
|
|
51
|
-
- [1.
|
|
51
|
+
- [1.4.0 (2020-04-12)](#140-2020-04-12)
|
|
52
52
|
- [Added](#added-15)
|
|
53
|
-
- [1.
|
|
53
|
+
- [1.3.0 (2020-04-12)](#130-2020-04-12)
|
|
54
54
|
- [Added](#added-16)
|
|
55
|
-
- [1.
|
|
55
|
+
- [1.2.0 (2020-04-12)](#120-2020-04-12)
|
|
56
56
|
- [Added](#added-17)
|
|
57
|
+
- [1.1.0 (2020-04-09)](#110-2020-04-09)
|
|
58
|
+
- [Added](#added-18)
|
|
57
59
|
- [Fixed](#fixed-2)
|
|
58
60
|
- [1.0.0 (2020-03-16)](#100-2020-03-16)
|
|
59
|
-
- [Added](#added-18)
|
|
60
|
-
- [0.6.0 (2020-01-06)](#060-2020-01-06)
|
|
61
61
|
- [Added](#added-19)
|
|
62
|
-
- [0.
|
|
62
|
+
- [0.6.0 (2020-01-06)](#060-2020-01-06)
|
|
63
63
|
- [Added](#added-20)
|
|
64
|
-
- [0.
|
|
64
|
+
- [0.5.0 (2020-01-04)](#050-2020-01-04)
|
|
65
65
|
- [Added](#added-21)
|
|
66
|
-
- [0.
|
|
66
|
+
- [0.4.0 (2020-01-03)](#040-2020-01-03)
|
|
67
67
|
- [Added](#added-22)
|
|
68
|
+
- [0.3.0 (2020-01-03)](#030-2020-01-03)
|
|
69
|
+
- [Added](#added-23)
|
|
68
70
|
- [Breaking Changes](#breaking-changes-4)
|
|
69
71
|
- [0.2.0 (2020-01-02)](#020-2020-01-02)
|
|
70
|
-
- [Added](#added-23)
|
|
71
|
-
- [0.1.0 (2019-12-26)](#010-2019-12-26)
|
|
72
72
|
- [Added](#added-24)
|
|
73
|
+
- [0.1.0 (2019-12-26)](#010-2019-12-26)
|
|
74
|
+
- [Added](#added-25)
|
|
73
75
|
|
|
74
76
|
## Unreleased
|
|
75
77
|
|
|
@@ -81,6 +83,45 @@ This project follows [semver 2.0.0](http://semver.org/spec/v2.0.0.html) and the
|
|
|
81
83
|
### Fixed
|
|
82
84
|
-->
|
|
83
85
|
|
|
86
|
+
5.3.0 (2021-03-23)
|
|
87
|
+
------------------
|
|
88
|
+
|
|
89
|
+
### Added
|
|
90
|
+
|
|
91
|
+
* [#53](https://github.com/serradura/kind/pull/53) - Allow `Kind::Result#map` and `Kind::Result#map!` receive a callable as an argument.
|
|
92
|
+
|
|
93
|
+
* [#53](https://github.com/serradura/kind/pull/53) - Add `|` and `>>` as an alias of `Kind::Result#map!`.
|
|
94
|
+
|
|
95
|
+
* [#53](https://github.com/serradura/kind/pull/53) - Add step adapters for `Kind::Action` and `Kind::Functional::Action`. This is the list of methods: `Step`, `Map`, `Try`, `Tee`, `Check`.
|
|
96
|
+
```ruby
|
|
97
|
+
module CreateUser
|
|
98
|
+
extend Kind::Functional::Action
|
|
99
|
+
|
|
100
|
+
def call!(input)
|
|
101
|
+
Step!(:validate, input) \
|
|
102
|
+
| Step(:create)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
private
|
|
106
|
+
|
|
107
|
+
def validate(input)
|
|
108
|
+
# returns Success(valid_data) or Failure(validation)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def create(input)
|
|
112
|
+
# returns Success(user)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
* [#53](https://github.com/serradura/kind/pull/53) - Add `kind/strict/disabled` to turn off all of the strict validations and optimize the runtime. Use case: As strict validation is useful in development, this mechanism could be used to optimize the runtime in production. List of methods that will be disabled:
|
|
118
|
+
* `Kind.of()`
|
|
119
|
+
* `Kind.of_class()`
|
|
120
|
+
* `Kind.of_module()`
|
|
121
|
+
* `Kind.of_module_or_class()`
|
|
122
|
+
* `Kind::<Type>[1]`
|
|
123
|
+
* `Kind::NotNil[1]`
|
|
124
|
+
|
|
84
125
|
5.2.0 (2021-03-17)
|
|
85
126
|
------------------
|
|
86
127
|
|
data/README.md
CHANGED
|
@@ -40,7 +40,7 @@ One of the goals of this project is to do simple type checking like `"some strin
|
|
|
40
40
|
Version | Documentation
|
|
41
41
|
---------- | -------------
|
|
42
42
|
unreleased | https://github.com/serradura/kind/blob/main/README.md
|
|
43
|
-
5.
|
|
43
|
+
5.3.0 | https://github.com/serradura/kind/blob/v5.x/README.md
|
|
44
44
|
4.1.0 | https://github.com/serradura/kind/blob/v4.x/README.md
|
|
45
45
|
3.1.0 | https://github.com/serradura/kind/blob/v3.x/README.md
|
|
46
46
|
2.3.0 | https://github.com/serradura/kind/blob/v2.x/README.md
|
|
@@ -123,7 +123,7 @@ unreleased | https://github.com/serradura/kind/blob/main/README.md
|
|
|
123
123
|
| kind | branch | ruby | activemodel |
|
|
124
124
|
| -------------- | ------- | -------- | -------------- |
|
|
125
125
|
| unreleased | main | >= 2.1.0 | >= 3.2, <= 6.1 |
|
|
126
|
-
| 5.
|
|
126
|
+
| 5.3.0 | v5.x | >= 2.1.0 | >= 3.2, <= 6.1 |
|
|
127
127
|
| 4.1.0 | v4.x | >= 2.2.0 | >= 3.2, <= 6.1 |
|
|
128
128
|
| 3.1.0 | v3.x | >= 2.2.0 | >= 3.2, <= 6.1 |
|
|
129
129
|
| 2.3.0 | v2.x | >= 2.2.0 | >= 3.2, <= 6.0 |
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Kind
|
|
4
|
+
module ACTION_STEPS
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
def Check(mthod); ->(value) { __Check(thod, value) }; end
|
|
8
|
+
def Step(mthod); ->(value) { __Step(mthod, value) }; end
|
|
9
|
+
def Map(mthod); ->(value) { __Map(mthod, value) }; end
|
|
10
|
+
def Tee(mthod); ->(value) { __Tee(mthod, value) }; end
|
|
11
|
+
def Try(mthod, opt = Empty::HASH)
|
|
12
|
+
->(value) { __Try(mthod, value, opt) }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def Check!(mthod, value); __Check(mthod, value); end
|
|
16
|
+
def Step!(mthod, value); __Step(mthod, value); end
|
|
17
|
+
def Map!(mthod, value); __Map(mthod, value); end
|
|
18
|
+
def Tee!(mthod, value); __Tee(mthod, value); end
|
|
19
|
+
def Try!(mthod, value, opt = Empty::HASH); __Try(mthod, value, opt); end
|
|
20
|
+
|
|
21
|
+
def __Check(mthod, value) # :nodoc:
|
|
22
|
+
__resolve_step(mthod, value) ? Success(mthod, value) : Failure(mthod, value)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def __Step(mthod, value) # :nodoc:
|
|
26
|
+
__resolve_step(mthod, value)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def __Map(mthod, value) # :nodoc:
|
|
30
|
+
Success(mthod, __resolve_step(mthod, value))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def __Tee(mthod, value) # :nodoc:
|
|
34
|
+
__resolve_step(mthod, value)
|
|
35
|
+
|
|
36
|
+
Success(mthod, value)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def __Try(mthod, value, opt = Empty::HASH) # :nodoc:
|
|
40
|
+
begin
|
|
41
|
+
Success(mthod, __resolve_step(mthod, value))
|
|
42
|
+
rescue opt.fetch(:catch, StandardError) => e
|
|
43
|
+
Failure(mthod, __map_step_exception(e))
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def __resolve_step(mthod, value) # :nodoc:
|
|
48
|
+
send(mthod, value)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def __map_step_exception(value) # :nodoc:
|
|
52
|
+
value
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private_constant :ACTION_STEPS
|
|
57
|
+
end
|
data/lib/kind/__lib__/kind.rb
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'kind/__lib__/strict'
|
|
4
|
+
|
|
3
5
|
module Kind
|
|
4
6
|
module KIND
|
|
5
7
|
extend self
|
|
6
8
|
|
|
7
|
-
def
|
|
9
|
+
def nil_or_undefined?(value) # :nodoc:
|
|
8
10
|
value.nil? || Undefined == value
|
|
9
11
|
end
|
|
10
12
|
|
|
@@ -14,28 +16,6 @@ module Kind
|
|
|
14
16
|
values.empty? ? of_kind : values.all?(&of_kind)
|
|
15
17
|
end
|
|
16
18
|
|
|
17
|
-
def of!(kind, value, kind_name = nil) # :nodoc:
|
|
18
|
-
return value if kind === value
|
|
19
|
-
|
|
20
|
-
error!(kind_name || kind.name, value)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def error!(kind_name, value, label = nil) # :nodoc:
|
|
24
|
-
raise Error.new(kind_name, value, label: label)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def of_class?(value) # :nodoc:
|
|
28
|
-
value.kind_of?(::Class)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def of_module?(value) # :nodoc:
|
|
32
|
-
::Module == value || (value.kind_of?(::Module) && !of_class?(value))
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def of_module_or_class!(value) # :nodoc:
|
|
36
|
-
of!(::Module, value, 'Module/Class')
|
|
37
|
-
end
|
|
38
|
-
|
|
39
19
|
def respond_to!(method_name, value) # :nodoc:
|
|
40
20
|
return value if value.respond_to?(method_name)
|
|
41
21
|
|
|
@@ -51,15 +31,15 @@ module Kind
|
|
|
51
31
|
end
|
|
52
32
|
|
|
53
33
|
def is?(expected, value) # :nodoc:
|
|
54
|
-
is(
|
|
34
|
+
is(STRICT.module_or_class(expected), value)
|
|
55
35
|
end
|
|
56
36
|
|
|
57
37
|
private
|
|
58
38
|
|
|
59
39
|
def is(expected_kind, value) # :nodoc:
|
|
60
|
-
kind =
|
|
40
|
+
kind = STRICT.module_or_class(value)
|
|
61
41
|
|
|
62
|
-
if
|
|
42
|
+
if OF.class?(kind)
|
|
63
43
|
kind <= expected_kind || expected_kind == ::Class
|
|
64
44
|
else
|
|
65
45
|
kind == expected_kind || kind.kind_of?(expected_kind)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Kind
|
|
4
|
+
module OF
|
|
5
|
+
extend self
|
|
6
|
+
|
|
7
|
+
def class?(value) # :nodoc:
|
|
8
|
+
value.kind_of?(::Class)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def module?(value) # :nodoc:
|
|
12
|
+
::Module == value || (value.kind_of?(::Module) && !class?(value))
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private_constant :OF
|
|
17
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'kind/__lib__/of'
|
|
4
|
+
|
|
5
|
+
module Kind
|
|
6
|
+
module STRICT
|
|
7
|
+
extend self
|
|
8
|
+
|
|
9
|
+
def error(kind_name, value, label = nil) # :nodoc:
|
|
10
|
+
raise Error.new(kind_name, value, label: label)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def object_is_a(kind, value, label = nil) # :nodoc:
|
|
14
|
+
return value if kind === value
|
|
15
|
+
|
|
16
|
+
error(kind.name, value, label)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def kind_of(kind, value, kind_name = nil) # :nodoc:
|
|
20
|
+
return value if kind === value
|
|
21
|
+
|
|
22
|
+
error(kind_name || kind.name, value)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def module_or_class(value) # :nodoc:
|
|
26
|
+
kind_of(::Module, value, 'Module/Class')
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def class!(value) # :nodoc:
|
|
30
|
+
kind_of(::Class, value)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def module!(value) # :nodoc:
|
|
34
|
+
return value if OF.module?(value)
|
|
35
|
+
|
|
36
|
+
error('Module', value)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def not_nil(value, label) # :nodoc:
|
|
40
|
+
return value unless value.nil?
|
|
41
|
+
|
|
42
|
+
label_text = label ? "#{label}: " : ''
|
|
43
|
+
|
|
44
|
+
raise Error.new("#{label_text}expected to not be nil")
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private_constant :STRICT
|
|
49
|
+
end
|
data/lib/kind/action.rb
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'kind/basic'
|
|
4
|
+
require 'kind/empty'
|
|
4
5
|
require 'kind/result'
|
|
5
6
|
require 'kind/immutable_attributes'
|
|
7
|
+
require 'kind/__lib__/action_steps'
|
|
6
8
|
|
|
7
9
|
module Kind
|
|
8
10
|
module Action
|
|
@@ -20,6 +22,8 @@ module Kind
|
|
|
20
22
|
'end'
|
|
21
23
|
].join("\n").freeze
|
|
22
24
|
|
|
25
|
+
private_constant :CALL_TMPL
|
|
26
|
+
|
|
23
27
|
module ClassMethods
|
|
24
28
|
include ImmutableAttributes::ClassMethods
|
|
25
29
|
|
|
@@ -71,21 +75,52 @@ module Kind
|
|
|
71
75
|
end
|
|
72
76
|
end
|
|
73
77
|
|
|
78
|
+
module StepAdapters
|
|
79
|
+
private
|
|
80
|
+
|
|
81
|
+
def Check!(mthod); __Check(mthod, Empty::HASH); end
|
|
82
|
+
def Step!(mthod); __Step(mthod, Empty::HASH); end
|
|
83
|
+
def Map!(mthod); __Map(mthod, Empty::HASH); end
|
|
84
|
+
def Tee!(_mthod); raise NotImplementedError; end
|
|
85
|
+
def Try!(mthod, opt = Empty::HASH); __Try(mthod, Empty::HASH, opt); end
|
|
86
|
+
|
|
87
|
+
def __resolve_step(method_name, value)
|
|
88
|
+
m = method(method_name)
|
|
89
|
+
m.arity > 0 ? m.call(value) : m.call
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def __map_step_exception(value)
|
|
93
|
+
{ exception: value }
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
private_constant :StepAdapters
|
|
98
|
+
|
|
74
99
|
def self.included(base)
|
|
75
|
-
|
|
100
|
+
Kind.of_class(base).extend(ClassMethods)
|
|
76
101
|
|
|
102
|
+
base.send(:include, ACTION_STEPS)
|
|
103
|
+
base.send(:include, StepAdapters)
|
|
77
104
|
base.send(:include, ImmutableAttributes::Reader)
|
|
78
105
|
end
|
|
79
106
|
|
|
80
107
|
include ImmutableAttributes::Initializer
|
|
81
108
|
|
|
109
|
+
def inspect
|
|
110
|
+
'#<%s attributes=%p nil_attributes=%p>' % [self.class.name, attributes, nil_attributes]
|
|
111
|
+
end
|
|
112
|
+
|
|
82
113
|
private
|
|
83
114
|
|
|
84
115
|
def Failure(arg1 = UNDEFINED, arg2 = UNDEFINED)
|
|
116
|
+
arg1 = Empty::HASH if UNDEFINED == arg1 && UNDEFINED == arg2
|
|
117
|
+
|
|
85
118
|
Result::Failure[arg1, arg2, value_must_be_a: ::Hash]
|
|
86
119
|
end
|
|
87
120
|
|
|
88
121
|
def Success(arg1 = UNDEFINED, arg2 = UNDEFINED)
|
|
122
|
+
arg1 = Empty::HASH if UNDEFINED == arg1 && UNDEFINED == arg2
|
|
123
|
+
|
|
89
124
|
Result::Success[arg1, arg2, value_must_be_a: ::Hash]
|
|
90
125
|
end
|
|
91
126
|
end
|
data/lib/kind/basic.rb
CHANGED
|
@@ -35,11 +35,11 @@ module Kind
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def of_class?(value)
|
|
38
|
-
|
|
38
|
+
OF.class?(value)
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def of_module?(value)
|
|
42
|
-
|
|
42
|
+
OF.module?(value)
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def respond_to?(value, *method_names)
|
|
@@ -49,15 +49,21 @@ module Kind
|
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
def of(kind, value, label: nil)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
KIND.error!(kind.name, value, label)
|
|
52
|
+
STRICT.object_is_a(kind, value, label)
|
|
55
53
|
end
|
|
56
54
|
|
|
57
55
|
alias_method :of!, :of
|
|
58
56
|
|
|
57
|
+
def of_class(value)
|
|
58
|
+
STRICT.class!(value)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def of_module(value)
|
|
62
|
+
STRICT.module!(value)
|
|
63
|
+
end
|
|
64
|
+
|
|
59
65
|
def of_module_or_class(value)
|
|
60
|
-
|
|
66
|
+
STRICT.module_or_class(value)
|
|
61
67
|
end
|
|
62
68
|
|
|
63
69
|
def respond_to(value, *method_names)
|
data/lib/kind/dig.rb
CHANGED
|
@@ -12,7 +12,7 @@ module Kind
|
|
|
12
12
|
keys.reduce(data) do |memo, key|
|
|
13
13
|
value = get(memo, key)
|
|
14
14
|
|
|
15
|
-
break if KIND.
|
|
15
|
+
break if KIND.nil_or_undefined?(value)
|
|
16
16
|
|
|
17
17
|
value
|
|
18
18
|
end
|
|
@@ -25,7 +25,7 @@ module Kind
|
|
|
25
25
|
|
|
26
26
|
return result unless block_given?
|
|
27
27
|
|
|
28
|
-
yield(result) unless KIND.
|
|
28
|
+
yield(result) unless KIND.nil_or_undefined?(result)
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def presence(*args, &block)
|
data/lib/kind/function.rb
CHANGED
data/lib/kind/functional.rb
CHANGED
|
@@ -11,7 +11,7 @@ module Kind
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def self.included(base)
|
|
14
|
-
|
|
14
|
+
Kind.of_class(base).send(:extend, ClassMethods)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
module Behavior
|
|
@@ -22,7 +22,7 @@ module Kind
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def initialize(arg = Empty::HASH)
|
|
25
|
-
hash =
|
|
25
|
+
hash = STRICT.kind_of(::Hash, arg)
|
|
26
26
|
|
|
27
27
|
self.class.__dependencies__.each do |name, (kind, default, _visibility)|
|
|
28
28
|
value_to_assign = ATTRIBUTES.value_to_assign!(kind, default, hash, name)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'kind/result'
|
|
4
4
|
require 'kind/functional'
|
|
5
|
+
require 'kind/__lib__/action_steps'
|
|
5
6
|
|
|
6
7
|
module Kind
|
|
7
8
|
module Functional::Action
|
|
@@ -56,10 +57,12 @@ module Kind
|
|
|
56
57
|
"#{CALL_TMPL % [call_tmpl_args, call_tmpl_args]}"
|
|
57
58
|
)
|
|
58
59
|
|
|
59
|
-
if
|
|
60
|
+
if Kind.of_module?(self)
|
|
60
61
|
self.send(:extend, Result::Methods)
|
|
62
|
+
self.send(:extend, ACTION_STEPS)
|
|
61
63
|
else
|
|
62
64
|
self.send(:include, Result::Methods)
|
|
65
|
+
self.send(:include, ACTION_STEPS)
|
|
63
66
|
self.send(:include, Functional::Behavior)
|
|
64
67
|
|
|
65
68
|
__dependencies__.freeze
|
|
@@ -72,15 +75,13 @@ module Kind
|
|
|
72
75
|
end
|
|
73
76
|
|
|
74
77
|
def self.included(base)
|
|
75
|
-
|
|
78
|
+
Kind.of_class(base).send(:extend, Functional::DependencyInjection)
|
|
76
79
|
|
|
77
80
|
base.send(:extend, Macros)
|
|
78
81
|
end
|
|
79
82
|
|
|
80
83
|
def self.extended(base)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
base.send(:extend, base)
|
|
84
|
+
base.send(:extend, Kind.of_module(base))
|
|
84
85
|
base.send(:extend, Macros)
|
|
85
86
|
end
|
|
86
87
|
|
data/lib/kind/maybe.rb
CHANGED
data/lib/kind/maybe/none.rb
CHANGED
data/lib/kind/maybe/some.rb
CHANGED
|
@@ -6,12 +6,12 @@ require 'kind/presence'
|
|
|
6
6
|
module Kind
|
|
7
7
|
module Maybe
|
|
8
8
|
class Some < Monad
|
|
9
|
-
KindSymbol = ->(value) {
|
|
9
|
+
KindSymbol = ->(value) { STRICT.kind_of(::Symbol, value) }
|
|
10
10
|
|
|
11
11
|
VALUE_CANT_BE_NONE = "value can't be nil or Kind::Undefined".freeze
|
|
12
12
|
|
|
13
13
|
def self.[](value)
|
|
14
|
-
return new(value) if !KIND.
|
|
14
|
+
return new(value) if !KIND.nil_or_undefined?(value)
|
|
15
15
|
|
|
16
16
|
raise ArgumentError, VALUE_CANT_BE_NONE
|
|
17
17
|
end
|
|
@@ -57,7 +57,7 @@ module Kind
|
|
|
57
57
|
fn.call(@value)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
!result || KIND.
|
|
60
|
+
!result || KIND.nil_or_undefined?(result) ? NONE_INSTANCE : self
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
alias_method :accept, :check
|
|
@@ -73,7 +73,7 @@ module Kind
|
|
|
73
73
|
fn.call(@value)
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
-
result || KIND.
|
|
76
|
+
result || KIND.nil_or_undefined?(result) ? NONE_INSTANCE : self
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
def try!(method_name = UNDEFINED, *args, &block)
|
|
@@ -120,7 +120,7 @@ module Kind
|
|
|
120
120
|
|
|
121
121
|
def resolve(result)
|
|
122
122
|
return result if Maybe::None === result
|
|
123
|
-
return NONE_INSTANCE if KIND.
|
|
123
|
+
return NONE_INSTANCE if KIND.nil_or_undefined?(result)
|
|
124
124
|
return None.new(result) if ::Exception === result
|
|
125
125
|
|
|
126
126
|
Some.new(result)
|
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
module Kind
|
|
4
4
|
module BasicObject
|
|
5
5
|
def [](value, label: nil)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
KIND.error!(name, value, label)
|
|
6
|
+
STRICT.object_is_a(self, value, label)
|
|
9
7
|
end
|
|
10
8
|
|
|
11
9
|
def or_nil(value)
|
|
@@ -33,7 +31,7 @@ module Kind
|
|
|
33
31
|
end
|
|
34
32
|
|
|
35
33
|
def or_null(value) # :nodoc:
|
|
36
|
-
KIND.
|
|
34
|
+
KIND.nil_or_undefined?(value) ? value : self[value]
|
|
37
35
|
end
|
|
38
36
|
|
|
39
37
|
private
|
data/lib/kind/objects/not_nil.rb
CHANGED
data/lib/kind/objects/object.rb
CHANGED
data/lib/kind/presence.rb
CHANGED
data/lib/kind/result/failure.rb
CHANGED
|
@@ -14,10 +14,12 @@ module Kind
|
|
|
14
14
|
UNDEFINED != default ? default : block.call
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
def map(&
|
|
17
|
+
def map(_ = UNDEFINED, &_fn)
|
|
18
18
|
self
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
+
alias_method :|, :map
|
|
22
|
+
alias_method :>>, :map
|
|
21
23
|
alias_method :map!, :map
|
|
22
24
|
alias_method :then, :map
|
|
23
25
|
alias_method :then!, :map
|
data/lib/kind/result/monad.rb
CHANGED
|
@@ -4,18 +4,21 @@ module Kind
|
|
|
4
4
|
class Result::Monad
|
|
5
5
|
include Result::Abstract
|
|
6
6
|
|
|
7
|
+
require 'kind/empty'
|
|
7
8
|
require 'kind/result/monad/wrapper'
|
|
8
9
|
|
|
9
10
|
attr_reader :type, :value
|
|
10
11
|
|
|
11
|
-
def self.[](arg1 = UNDEFINED, arg2 = UNDEFINED,
|
|
12
|
-
|
|
12
|
+
def self.[](arg1 = UNDEFINED, arg2 = UNDEFINED, opt = Empty::HASH) # :nodoc:
|
|
13
|
+
value_must_be_a = opt[:value_must_be_a]
|
|
14
|
+
|
|
15
|
+
type = UNDEFINED == arg2 ? self::DEFAULT_TYPE : STRICT.kind_of(::Symbol, arg1)
|
|
13
16
|
|
|
14
17
|
Error.wrong_number_of_args!(given: 0, expected: '1 or 2') if UNDEFINED == arg1
|
|
15
18
|
|
|
16
19
|
value = UNDEFINED == arg2 ? arg1 : arg2
|
|
17
20
|
|
|
18
|
-
new(type, (value_must_be_a ?
|
|
21
|
+
new(type, (value_must_be_a ? STRICT.kind_of(value_must_be_a, value) : value))
|
|
19
22
|
end
|
|
20
23
|
|
|
21
24
|
private_class_method :new
|
|
@@ -29,10 +32,12 @@ module Kind
|
|
|
29
32
|
raise NotImplementedError
|
|
30
33
|
end
|
|
31
34
|
|
|
32
|
-
def map(&
|
|
35
|
+
def map(_ = UNDEFINED, &_fn)
|
|
33
36
|
raise NotImplementedError
|
|
34
37
|
end
|
|
35
38
|
|
|
39
|
+
alias_method :|, :map
|
|
40
|
+
alias_method :>>, :map
|
|
36
41
|
alias_method :map!, :map
|
|
37
42
|
alias_method :then, :map
|
|
38
43
|
alias_method :then!, :map
|
data/lib/kind/result/success.rb
CHANGED
|
@@ -12,29 +12,42 @@ module Kind
|
|
|
12
12
|
@value
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
def map(&fn)
|
|
16
|
-
|
|
15
|
+
def map(callable = UNDEFINED, &fn)
|
|
16
|
+
_resolve_map(callable, fn)
|
|
17
17
|
rescue Kind::Monad::Error => e
|
|
18
18
|
raise e
|
|
19
19
|
rescue StandardError => e
|
|
20
20
|
Result::Failure[:exception, e]
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return monad if Result::Monad === monad
|
|
23
|
+
alias_method :then, :map
|
|
24
|
+
alias_method :and_then, :map
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
def map!(callable = UNDEFINED, &fn)
|
|
27
|
+
_resolve_map(callable, fn)
|
|
29
28
|
end
|
|
30
29
|
|
|
31
|
-
alias_method
|
|
30
|
+
alias_method :|, :map!
|
|
31
|
+
alias_method :>>, :map!
|
|
32
32
|
alias_method :then!, :map!
|
|
33
|
-
alias_method :and_then, :map
|
|
34
33
|
alias_method :and_then!, :map!
|
|
35
34
|
|
|
36
35
|
def inspect
|
|
37
36
|
'#<%s type=%p value=%p>' % ['Kind::Success', type, value]
|
|
38
37
|
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def _resolve_map(callable, fn)
|
|
42
|
+
callable.respond_to?(:call) ? _map(callable) : _map(fn)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def _map(fn)
|
|
46
|
+
monad = fn.call(@value)
|
|
47
|
+
|
|
48
|
+
return monad if Result::Monad === monad
|
|
49
|
+
|
|
50
|
+
raise Kind::Monad::Error.new('Kind::Success | Kind::Failure', monad)
|
|
51
|
+
end
|
|
39
52
|
end
|
|
40
53
|
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Kind
|
|
4
|
+
module STRICT
|
|
5
|
+
[
|
|
6
|
+
:object_is_a, :class!, :kind_of,
|
|
7
|
+
:module_or_class, :module!, :not_nil
|
|
8
|
+
].each { |method_name| remove_method(method_name) }
|
|
9
|
+
|
|
10
|
+
def object_is_a(_kind, value, _label = nil) # :nodoc:
|
|
11
|
+
value
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def class!(value) # :nodoc:
|
|
15
|
+
value
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def kind_of(_kind, value, _kind_name = nil) # :nodoc:
|
|
19
|
+
value
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def module_or_class(value) # :nodoc:
|
|
23
|
+
value
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def module!(value) # :nodoc:
|
|
27
|
+
value
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def not_nil(value, label) # :nodoc:
|
|
31
|
+
value
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/kind/try.rb
CHANGED
|
@@ -9,7 +9,7 @@ module Kind
|
|
|
9
9
|
extend self
|
|
10
10
|
|
|
11
11
|
def call!(object, method_name, args = Empty::ARRAY) # :nodoc
|
|
12
|
-
return if KIND.
|
|
12
|
+
return if KIND.nil_or_undefined?(object)
|
|
13
13
|
|
|
14
14
|
resolve(object, method_name, args)
|
|
15
15
|
end
|
|
@@ -21,7 +21,7 @@ module Kind
|
|
|
21
21
|
|
|
22
22
|
return result unless block_given?
|
|
23
23
|
|
|
24
|
-
yield(result) unless KIND.
|
|
24
|
+
yield(result) unless KIND.nil_or_undefined?(result)
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def presence(*args, &block)
|
data/lib/kind/validator.rb
CHANGED
|
@@ -101,7 +101,7 @@ class KindValidator < ActiveModel::EachValidator
|
|
|
101
101
|
def kind_is_not(expected, value)
|
|
102
102
|
case expected
|
|
103
103
|
when ::Class
|
|
104
|
-
return if expected == Kind.
|
|
104
|
+
return if expected == Kind.of_class(value) || value < expected
|
|
105
105
|
|
|
106
106
|
"must be the class or a subclass of `#{expected.name}`"
|
|
107
107
|
when ::Module
|
data/lib/kind/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kind
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.3.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-
|
|
11
|
+
date: 2021-03-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: A simple type system (at runtime) for Ruby - free of dependencies.
|
|
14
14
|
email:
|
|
@@ -31,8 +31,11 @@ files:
|
|
|
31
31
|
- bin/setup
|
|
32
32
|
- kind.gemspec
|
|
33
33
|
- lib/kind.rb
|
|
34
|
+
- lib/kind/__lib__/action_steps.rb
|
|
34
35
|
- lib/kind/__lib__/attributes.rb
|
|
35
36
|
- lib/kind/__lib__/kind.rb
|
|
37
|
+
- lib/kind/__lib__/of.rb
|
|
38
|
+
- lib/kind/__lib__/strict.rb
|
|
36
39
|
- lib/kind/__lib__/undefined.rb
|
|
37
40
|
- lib/kind/action.rb
|
|
38
41
|
- lib/kind/active_model/validation.rb
|
|
@@ -109,6 +112,7 @@ files:
|
|
|
109
112
|
- lib/kind/result/monad.rb
|
|
110
113
|
- lib/kind/result/monad/wrapper.rb
|
|
111
114
|
- lib/kind/result/success.rb
|
|
115
|
+
- lib/kind/strict/disabled.rb
|
|
112
116
|
- lib/kind/try.rb
|
|
113
117
|
- lib/kind/validator.rb
|
|
114
118
|
- lib/kind/version.rb
|