kind 2.0.0 → 3.0.1
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.yml +4 -1
- data/README.md +401 -173
- data/lib/kind.rb +47 -39
- data/lib/kind/active_model/kind_validator.rb +2 -2
- data/lib/kind/checker.rb +3 -63
- data/lib/kind/checker/factory.rb +35 -0
- data/lib/kind/checker/protocol.rb +73 -0
- data/lib/kind/error.rb +1 -1
- data/lib/kind/maybe.rb +90 -17
- data/lib/kind/types.rb +15 -4
- data/lib/kind/undefined.rb +1 -1
- data/lib/kind/version.rb +1 -1
- metadata +4 -2
data/lib/kind.rb
CHANGED
@@ -4,12 +4,12 @@ require 'kind/version'
|
|
4
4
|
|
5
5
|
require 'kind/empty'
|
6
6
|
require 'kind/undefined'
|
7
|
+
require 'kind/checker'
|
7
8
|
require 'kind/maybe'
|
8
9
|
|
9
10
|
require 'kind/error'
|
10
11
|
require 'kind/of'
|
11
12
|
require 'kind/is'
|
12
|
-
require 'kind/checker'
|
13
13
|
require 'kind/types'
|
14
14
|
|
15
15
|
module Kind
|
@@ -18,35 +18,23 @@ module Kind
|
|
18
18
|
private_constant :WRONG_NUMBER_OF_ARGUMENTS
|
19
19
|
|
20
20
|
def self.is(expected = Undefined, object = Undefined)
|
21
|
-
return Is if
|
21
|
+
return Is if Undefined == expected && Undefined == object
|
22
22
|
|
23
|
-
return Kind::Is.(expected, object) if
|
23
|
+
return Kind::Is.(expected, object) if Undefined != object
|
24
24
|
|
25
25
|
raise ArgumentError, WRONG_NUMBER_OF_ARGUMENTS
|
26
26
|
end
|
27
27
|
|
28
|
-
MODULE_OR_CLASS = 'Module/Class'.freeze
|
29
|
-
|
30
|
-
private_constant :MODULE_OR_CLASS
|
31
|
-
|
32
28
|
def self.of(kind = Undefined, object = Undefined)
|
33
|
-
return Of if
|
34
|
-
|
35
|
-
return Kind::Of.(kind, object) if object != Undefined
|
29
|
+
return Of if Undefined == kind && Undefined == object
|
36
30
|
|
37
|
-
|
38
|
-
kind_name = kind.name
|
31
|
+
return Kind::Of.(kind, object) if Undefined != object
|
39
32
|
|
40
|
-
|
41
|
-
Kind::Of.const_get(kind_name)
|
42
|
-
else
|
43
|
-
Checker.new(Kind::Of.(Module, kind, MODULE_OR_CLASS))
|
44
|
-
end
|
45
|
-
end
|
33
|
+
Kind::Checker::Factory.create(kind)
|
46
34
|
end
|
47
35
|
|
48
|
-
|
49
|
-
|
36
|
+
def self.of?(kind, *args)
|
37
|
+
Kind.of(kind).instance?(*args)
|
50
38
|
end
|
51
39
|
|
52
40
|
# --------------------- #
|
@@ -59,7 +47,7 @@ module Kind
|
|
59
47
|
end
|
60
48
|
|
61
49
|
def self.Module(value)
|
62
|
-
|
50
|
+
::Module == value || (value.is_a?(::Module) && !self.Class(value))
|
63
51
|
end
|
64
52
|
|
65
53
|
def self.Boolean(value)
|
@@ -75,13 +63,13 @@ module Kind
|
|
75
63
|
# -- Class
|
76
64
|
|
77
65
|
def self.Class(object = Undefined)
|
78
|
-
return Class if
|
66
|
+
return Class if Undefined == object
|
79
67
|
|
80
68
|
self.call(::Class, object)
|
81
69
|
end
|
82
70
|
|
83
71
|
const_set(:Class, ::Module.new do
|
84
|
-
extend
|
72
|
+
extend Checker::Protocol
|
85
73
|
|
86
74
|
def self.__kind; ::Class; end
|
87
75
|
|
@@ -90,19 +78,23 @@ module Kind
|
|
90
78
|
def self.__is_instance__(value); class?(value); end
|
91
79
|
end)
|
92
80
|
|
81
|
+
def self.Class?(*args)
|
82
|
+
Kind::Of::Class.instance?(*args)
|
83
|
+
end
|
84
|
+
|
93
85
|
# -- Module
|
94
86
|
|
95
87
|
def self.Module(object = Undefined)
|
96
|
-
return Module if
|
88
|
+
return Module if Undefined == object
|
97
89
|
|
98
90
|
self.call(::Module, object)
|
99
91
|
end
|
100
92
|
|
101
93
|
const_set(:Module, ::Module.new do
|
102
|
-
extend
|
94
|
+
extend Checker::Protocol
|
103
95
|
|
104
96
|
def self.__kind_undefined(value)
|
105
|
-
__kind_error(Kind::Undefined) if
|
97
|
+
__kind_error(Kind::Undefined) if Kind::Undefined == value
|
106
98
|
|
107
99
|
yield
|
108
100
|
end
|
@@ -127,7 +119,7 @@ module Kind
|
|
127
119
|
if ::Kind::Maybe::Value.none?(default)
|
128
120
|
__kind_undefined(value) { __kind_of(value) }
|
129
121
|
else
|
130
|
-
return value if
|
122
|
+
return value if Kind::Undefined != value && instance?(value)
|
131
123
|
|
132
124
|
__kind_undefined(default) { __kind_of(default) }
|
133
125
|
end
|
@@ -136,12 +128,16 @@ module Kind
|
|
136
128
|
def self.__is_instance__(value); class?(value); end
|
137
129
|
end)
|
138
130
|
|
131
|
+
def self.Module?(*args)
|
132
|
+
Kind::Of::Module.instance?(*args)
|
133
|
+
end
|
134
|
+
|
139
135
|
# -- Boolean
|
140
136
|
|
141
137
|
def self.Boolean(object = Undefined, options = Empty::HASH)
|
142
138
|
default = options[:or]
|
143
139
|
|
144
|
-
return Kind::Of::Boolean if
|
140
|
+
return Kind::Of::Boolean if Undefined == object && default.nil?
|
145
141
|
|
146
142
|
bool = object.nil? ? default : object
|
147
143
|
|
@@ -151,7 +147,7 @@ module Kind
|
|
151
147
|
end
|
152
148
|
|
153
149
|
const_set(:Boolean, ::Module.new do
|
154
|
-
extend
|
150
|
+
extend Checker::Protocol
|
155
151
|
|
156
152
|
def self.__kind; [TrueClass, FalseClass].freeze; end
|
157
153
|
|
@@ -163,14 +159,14 @@ module Kind
|
|
163
159
|
if ::Kind::Maybe::Value.none?(default)
|
164
160
|
__kind_undefined(value) { Kind::Of::Boolean(value) }
|
165
161
|
else
|
166
|
-
return value if
|
162
|
+
return value if Kind::Undefined != value && instance?(value)
|
167
163
|
|
168
164
|
__kind_undefined(default) { Kind::Of::Boolean(default) }
|
169
165
|
end
|
170
166
|
end
|
171
167
|
|
172
168
|
def self.__kind_undefined(value)
|
173
|
-
if
|
169
|
+
if Kind::Undefined == value
|
174
170
|
raise Kind::Error.new('Boolean'.freeze, Kind::Undefined)
|
175
171
|
else
|
176
172
|
yield
|
@@ -187,12 +183,16 @@ module Kind
|
|
187
183
|
end
|
188
184
|
end)
|
189
185
|
|
186
|
+
def self.Boolean?(*args)
|
187
|
+
Kind::Of::Boolean.instance?(*args)
|
188
|
+
end
|
189
|
+
|
190
190
|
# -- Lambda
|
191
191
|
|
192
192
|
def self.Lambda(object = Undefined, options = Empty::HASH)
|
193
193
|
default = options[:or]
|
194
194
|
|
195
|
-
return Kind::Of::Lambda if
|
195
|
+
return Kind::Of::Lambda if Undefined == object && default.nil?
|
196
196
|
|
197
197
|
func = object || default
|
198
198
|
|
@@ -202,7 +202,7 @@ module Kind
|
|
202
202
|
end
|
203
203
|
|
204
204
|
const_set(:Lambda, ::Module.new do
|
205
|
-
extend
|
205
|
+
extend Checker::Protocol
|
206
206
|
|
207
207
|
def self.__kind; ::Proc; end
|
208
208
|
|
@@ -212,14 +212,14 @@ module Kind
|
|
212
212
|
if ::Kind::Maybe::Value.none?(default)
|
213
213
|
__kind_undefined(value) { Kind::Of::Lambda(value) }
|
214
214
|
else
|
215
|
-
return value if
|
215
|
+
return value if Kind::Undefined != value && instance?(value)
|
216
216
|
|
217
217
|
__kind_undefined(default) { Kind::Of::Lambda(default) }
|
218
218
|
end
|
219
219
|
end
|
220
220
|
|
221
221
|
def self.__kind_undefined(value)
|
222
|
-
if
|
222
|
+
if Kind::Undefined == value
|
223
223
|
raise Kind::Error.new('Lambda'.freeze, Kind::Undefined)
|
224
224
|
else
|
225
225
|
yield
|
@@ -231,12 +231,16 @@ module Kind
|
|
231
231
|
end
|
232
232
|
end)
|
233
233
|
|
234
|
+
def self.Lambda?(*args)
|
235
|
+
Kind::Of::Lambda.instance?(*args)
|
236
|
+
end
|
237
|
+
|
234
238
|
# -- Callable
|
235
239
|
|
236
240
|
def self.Callable(object = Undefined, options = Empty::HASH)
|
237
241
|
default = options[:or]
|
238
242
|
|
239
|
-
return Kind::Of::Callable if
|
243
|
+
return Kind::Of::Callable if Undefined == object && default.nil?
|
240
244
|
|
241
245
|
callable = object || default
|
242
246
|
|
@@ -246,7 +250,7 @@ module Kind
|
|
246
250
|
end
|
247
251
|
|
248
252
|
const_set(:Callable, ::Module.new do
|
249
|
-
extend
|
253
|
+
extend Checker::Protocol
|
250
254
|
|
251
255
|
def self.__kind; Object; end
|
252
256
|
|
@@ -260,14 +264,14 @@ module Kind
|
|
260
264
|
if ::Kind::Maybe::Value.none?(default)
|
261
265
|
__kind_undefined(value) { Kind::Of::Callable(value) }
|
262
266
|
else
|
263
|
-
return value if
|
267
|
+
return value if Kind::Undefined != value && instance?(value)
|
264
268
|
|
265
269
|
__kind_undefined(default) { Kind::Of::Callable(default) }
|
266
270
|
end
|
267
271
|
end
|
268
272
|
|
269
273
|
def self.__kind_undefined(value)
|
270
|
-
if
|
274
|
+
if Kind::Undefined == value
|
271
275
|
raise Kind::Error.new('Callable'.freeze, Kind::Undefined)
|
272
276
|
else
|
273
277
|
yield
|
@@ -279,6 +283,10 @@ module Kind
|
|
279
283
|
end
|
280
284
|
end)
|
281
285
|
|
286
|
+
def self.Callable?(*args)
|
287
|
+
Kind::Of::Callable.instance?(*args)
|
288
|
+
end
|
289
|
+
|
282
290
|
# ---------------------- #
|
283
291
|
# Built-in type checkers #
|
284
292
|
# ---------------------- #
|
@@ -53,12 +53,12 @@ class KindValidator < ActiveModel::EachValidator
|
|
53
53
|
def kind_is_not(expected, value)
|
54
54
|
case expected
|
55
55
|
when Class
|
56
|
-
return if Kind.of.Class(value)
|
56
|
+
return if expected == Kind.of.Class(value) || value < expected
|
57
57
|
|
58
58
|
"must be the class or a subclass of `#{expected.name}`"
|
59
59
|
when Module
|
60
60
|
return if value.kind_of?(Class) && value <= expected
|
61
|
-
return if Kind.of.Module(value)
|
61
|
+
return if expected == Kind.of.Module(value) || value.kind_of?(expected)
|
62
62
|
|
63
63
|
"must include the `#{expected.name}` module"
|
64
64
|
else
|
data/lib/kind/checker.rb
CHANGED
@@ -1,70 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'kind/checker/factory'
|
4
|
+
require 'kind/checker/protocol'
|
3
5
|
module Kind
|
4
|
-
module Checkable
|
5
|
-
def class?(value)
|
6
|
-
Kind::Is.__call__(__kind, value)
|
7
|
-
end
|
8
|
-
|
9
|
-
def instance(value, options = Empty::HASH)
|
10
|
-
default = options[:or]
|
11
|
-
|
12
|
-
return Kind::Of.(__kind, value) if ::Kind::Maybe::Value.none?(default)
|
13
|
-
|
14
|
-
value != Kind::Undefined && instance?(value) ? value : Kind::Of.(__kind, default)
|
15
|
-
end
|
16
|
-
|
17
|
-
def [](value, options = options = Empty::HASH)
|
18
|
-
instance(value, options)
|
19
|
-
end
|
20
|
-
|
21
|
-
def instance?(value = Kind::Undefined)
|
22
|
-
return __is_instance__(value) if value != Kind::Undefined
|
23
|
-
|
24
|
-
to_proc
|
25
|
-
end
|
26
|
-
|
27
|
-
def __is_instance__(value)
|
28
|
-
value.is_a?(__kind)
|
29
|
-
end
|
30
|
-
|
31
|
-
def to_proc
|
32
|
-
@to_proc ||=
|
33
|
-
-> checker { -> value { checker.__is_instance__(value) } }.call(self)
|
34
|
-
end
|
35
|
-
|
36
|
-
def or_nil(value)
|
37
|
-
return value if instance?(value)
|
38
|
-
end
|
39
|
-
|
40
|
-
def or_undefined(value)
|
41
|
-
or_nil(value) || Kind::Undefined
|
42
|
-
end
|
43
|
-
|
44
|
-
def as_maybe(value = Kind::Undefined)
|
45
|
-
return __as_maybe__(value) if value != Kind::Undefined
|
46
|
-
|
47
|
-
as_maybe_to_proc
|
48
|
-
end
|
49
|
-
|
50
|
-
def as_optional(value = Kind::Undefined)
|
51
|
-
as_maybe(value)
|
52
|
-
end
|
53
|
-
|
54
|
-
def __as_maybe__(value)
|
55
|
-
Kind::Maybe.new(or_nil(value))
|
56
|
-
end
|
57
|
-
|
58
|
-
def as_maybe_to_proc
|
59
|
-
@as_maybe_to_proc ||=
|
60
|
-
-> checker { -> value { checker.__as_maybe__(value) } }.call(self)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
private_constant :Checkable
|
65
|
-
|
66
6
|
class Checker
|
67
|
-
include
|
7
|
+
include Protocol
|
68
8
|
|
69
9
|
attr_reader :__kind
|
70
10
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'singleton'
|
4
|
+
|
5
|
+
module Kind
|
6
|
+
class Checker
|
7
|
+
class Factory
|
8
|
+
include Singleton
|
9
|
+
|
10
|
+
def self.create(kind)
|
11
|
+
instance.create(kind)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@__checkers__ = {}
|
16
|
+
end
|
17
|
+
|
18
|
+
MODULE_OR_CLASS = 'Module/Class'.freeze
|
19
|
+
|
20
|
+
private_constant :MODULE_OR_CLASS
|
21
|
+
|
22
|
+
def create(kind)
|
23
|
+
@__checkers__[kind] ||= begin
|
24
|
+
kind_name = kind.name
|
25
|
+
|
26
|
+
if Kind::Of.const_defined?(kind_name, false)
|
27
|
+
Kind::Of.const_get(kind_name)
|
28
|
+
else
|
29
|
+
Kind::Checker.new(Kind::Of.(Module, kind, MODULE_OR_CLASS))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kind
|
4
|
+
class Checker
|
5
|
+
module Protocol
|
6
|
+
def class?(value)
|
7
|
+
Kind::Is.__call__(__kind, value)
|
8
|
+
end
|
9
|
+
|
10
|
+
def instance(value, options = Empty::HASH)
|
11
|
+
default = options[:or]
|
12
|
+
|
13
|
+
return Kind::Of.(__kind, value) if ::Kind::Maybe::Value.none?(default)
|
14
|
+
|
15
|
+
Kind::Undefined != value && instance?(value) ? value : Kind::Of.(__kind, default)
|
16
|
+
end
|
17
|
+
|
18
|
+
def [](value, options = options = Empty::HASH)
|
19
|
+
instance(value, options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_proc
|
23
|
+
@to_proc ||=
|
24
|
+
-> checker { -> value { checker.instance(value) } }.call(self)
|
25
|
+
end
|
26
|
+
|
27
|
+
def __is_instance__(value)
|
28
|
+
value.kind_of?(__kind)
|
29
|
+
end
|
30
|
+
|
31
|
+
def is_instance_to_proc
|
32
|
+
@is_instance_to_proc ||=
|
33
|
+
-> checker { -> value { checker.__is_instance__(value) } }.call(self)
|
34
|
+
end
|
35
|
+
|
36
|
+
def instance?(*args)
|
37
|
+
return is_instance_to_proc if args.empty?
|
38
|
+
|
39
|
+
return args.all? { |object| __is_instance__(object) } if args.size > 1
|
40
|
+
|
41
|
+
arg = args[0]
|
42
|
+
Kind::Undefined == arg ? is_instance_to_proc : __is_instance__(arg)
|
43
|
+
end
|
44
|
+
|
45
|
+
def or_nil(value)
|
46
|
+
return value if instance?(value)
|
47
|
+
end
|
48
|
+
|
49
|
+
def or_undefined(value)
|
50
|
+
or_nil(value) || Kind::Undefined
|
51
|
+
end
|
52
|
+
|
53
|
+
def __as_maybe__(value)
|
54
|
+
Kind::Maybe.new(or_nil(value))
|
55
|
+
end
|
56
|
+
|
57
|
+
def as_maybe_to_proc
|
58
|
+
@as_maybe_to_proc ||=
|
59
|
+
-> checker { -> value { checker.__as_maybe__(value) } }.call(self)
|
60
|
+
end
|
61
|
+
|
62
|
+
def as_maybe(value = Kind::Undefined)
|
63
|
+
return __as_maybe__(value) if Kind::Undefined != value
|
64
|
+
|
65
|
+
as_maybe_to_proc
|
66
|
+
end
|
67
|
+
|
68
|
+
def as_optional(value = Kind::Undefined)
|
69
|
+
as_maybe(value)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|