kind 1.9.0 → 3.0.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.
@@ -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 expected == Undefined && object == Undefined
21
+ return Is if Undefined == expected && Undefined == object
22
22
 
23
- return Kind::Is.(expected, object) if object != Undefined
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 kind == Undefined && object == Undefined
29
+ return Of if Undefined == kind && Undefined == object
34
30
 
35
- return Kind::Of.(kind, object) if object != Undefined
31
+ return Kind::Of.(kind, object) if Undefined != object
36
32
 
37
- __checkers__[kind] ||= begin
38
- kind_name = kind.name
39
-
40
- if Kind::Of.const_defined?(kind_name, false)
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
- private_class_method def self.__checkers__
49
- @__checkers__ ||= {}
36
+ def self.of?(kind, *args)
37
+ Kind.of(kind).instance?(*args)
50
38
  end
51
39
 
52
40
  # --------------------- #
@@ -55,20 +43,19 @@ module Kind
55
43
 
56
44
  module Is
57
45
  def self.Class(value)
58
- value.is_a?(::Class)
46
+ value.kind_of?(::Class)
59
47
  end
60
48
 
61
49
  def self.Module(value)
62
- value == ::Module || (value.is_a?(::Module) && !self.Class(value))
50
+ ::Module == value || (value.is_a?(::Module) && !self.Class(value))
63
51
  end
64
52
 
65
53
  def self.Boolean(value)
66
- klass = Kind.of.Class(value)
67
- klass <= TrueClass || klass <= FalseClass
54
+ Kind.of.Class(value) <= TrueClass || value <= FalseClass
68
55
  end
69
56
 
70
57
  def self.Callable(value)
71
- value.respond_to?(:call) || (value.is_a?(Module) && value.public_instance_methods.include?(:call))
58
+ value.respond_to?(:call)
72
59
  end
73
60
  end
74
61
 
@@ -76,13 +63,13 @@ module Kind
76
63
  # -- Class
77
64
 
78
65
  def self.Class(object = Undefined)
79
- return Class if object == Undefined
66
+ return Class if Undefined == object
80
67
 
81
68
  self.call(::Class, object)
82
69
  end
83
70
 
84
71
  const_set(:Class, ::Module.new do
85
- extend Checkable
72
+ extend Checker::Protocol
86
73
 
87
74
  def self.__kind; ::Class; end
88
75
 
@@ -91,18 +78,26 @@ module Kind
91
78
  def self.__is_instance__(value); class?(value); end
92
79
  end)
93
80
 
81
+ def self.Class?(*args)
82
+ Kind::Of::Class.instance?(*args)
83
+ end
84
+
94
85
  # -- Module
95
86
 
96
87
  def self.Module(object = Undefined)
97
- return Module if object == Undefined
88
+ return Module if Undefined == object
98
89
 
99
90
  self.call(::Module, object)
100
91
  end
101
92
 
102
93
  const_set(:Module, ::Module.new do
103
- extend Checkable
94
+ extend Checker::Protocol
104
95
 
105
- def self.__kind; ::Module; end
96
+ def self.__kind_undefined(value)
97
+ __kind_error(Kind::Undefined) if Kind::Undefined == value
98
+
99
+ yield
100
+ end
106
101
 
107
102
  def self.__kind_error(value)
108
103
  raise Kind::Error.new('Module'.freeze, value)
@@ -114,11 +109,7 @@ module Kind
114
109
  __kind_error(value)
115
110
  end
116
111
 
117
- def self.__kind_undefined(value)
118
- __kind_error(Kind::Undefined) if value == Kind::Undefined
119
-
120
- yield
121
- end
112
+ def self.__kind; ::Module; end
122
113
 
123
114
  def self.class?(value); Kind::Is.Module(value); end
124
115
 
@@ -128,7 +119,7 @@ module Kind
128
119
  if ::Kind::Maybe::Value.none?(default)
129
120
  __kind_undefined(value) { __kind_of(value) }
130
121
  else
131
- return value if value != Kind::Undefined && instance?(value)
122
+ return value if Kind::Undefined != value && instance?(value)
132
123
 
133
124
  __kind_undefined(default) { __kind_of(default) }
134
125
  end
@@ -137,12 +128,16 @@ module Kind
137
128
  def self.__is_instance__(value); class?(value); end
138
129
  end)
139
130
 
131
+ def self.Module?(*args)
132
+ Kind::Of::Module.instance?(*args)
133
+ end
134
+
140
135
  # -- Boolean
141
136
 
142
137
  def self.Boolean(object = Undefined, options = Empty::HASH)
143
138
  default = options[:or]
144
139
 
145
- return Kind::Of::Boolean if object == Undefined && default.nil?
140
+ return Kind::Of::Boolean if Undefined == object && default.nil?
146
141
 
147
142
  bool = object.nil? ? default : object
148
143
 
@@ -152,7 +147,7 @@ module Kind
152
147
  end
153
148
 
154
149
  const_set(:Boolean, ::Module.new do
155
- extend Checkable
150
+ extend Checker::Protocol
156
151
 
157
152
  def self.__kind; [TrueClass, FalseClass].freeze; end
158
153
 
@@ -164,14 +159,14 @@ module Kind
164
159
  if ::Kind::Maybe::Value.none?(default)
165
160
  __kind_undefined(value) { Kind::Of::Boolean(value) }
166
161
  else
167
- return value if value != Kind::Undefined && instance?(value)
162
+ return value if Kind::Undefined != value && instance?(value)
168
163
 
169
164
  __kind_undefined(default) { Kind::Of::Boolean(default) }
170
165
  end
171
166
  end
172
167
 
173
168
  def self.__kind_undefined(value)
174
- if value == Kind::Undefined
169
+ if Kind::Undefined == value
175
170
  raise Kind::Error.new('Boolean'.freeze, Kind::Undefined)
176
171
  else
177
172
  yield
@@ -188,12 +183,16 @@ module Kind
188
183
  end
189
184
  end)
190
185
 
186
+ def self.Boolean?(*args)
187
+ Kind::Of::Boolean.instance?(*args)
188
+ end
189
+
191
190
  # -- Lambda
192
191
 
193
192
  def self.Lambda(object = Undefined, options = Empty::HASH)
194
193
  default = options[:or]
195
194
 
196
- return Kind::Of::Lambda if object == Undefined && default.nil?
195
+ return Kind::Of::Lambda if Undefined == object && default.nil?
197
196
 
198
197
  func = object || default
199
198
 
@@ -203,7 +202,7 @@ module Kind
203
202
  end
204
203
 
205
204
  const_set(:Lambda, ::Module.new do
206
- extend Checkable
205
+ extend Checker::Protocol
207
206
 
208
207
  def self.__kind; ::Proc; end
209
208
 
@@ -213,14 +212,14 @@ module Kind
213
212
  if ::Kind::Maybe::Value.none?(default)
214
213
  __kind_undefined(value) { Kind::Of::Lambda(value) }
215
214
  else
216
- return value if value != Kind::Undefined && instance?(value)
215
+ return value if Kind::Undefined != value && instance?(value)
217
216
 
218
217
  __kind_undefined(default) { Kind::Of::Lambda(default) }
219
218
  end
220
219
  end
221
220
 
222
221
  def self.__kind_undefined(value)
223
- if value == Kind::Undefined
222
+ if Kind::Undefined == value
224
223
  raise Kind::Error.new('Lambda'.freeze, Kind::Undefined)
225
224
  else
226
225
  yield
@@ -232,12 +231,16 @@ module Kind
232
231
  end
233
232
  end)
234
233
 
234
+ def self.Lambda?(*args)
235
+ Kind::Of::Lambda.instance?(*args)
236
+ end
237
+
235
238
  # -- Callable
236
239
 
237
240
  def self.Callable(object = Undefined, options = Empty::HASH)
238
241
  default = options[:or]
239
242
 
240
- return Kind::Of::Callable if object == Undefined && default.nil?
243
+ return Kind::Of::Callable if Undefined == object && default.nil?
241
244
 
242
245
  callable = object || default
243
246
 
@@ -247,7 +250,7 @@ module Kind
247
250
  end
248
251
 
249
252
  const_set(:Callable, ::Module.new do
250
- extend Checkable
253
+ extend Checker::Protocol
251
254
 
252
255
  def self.__kind; Object; end
253
256
 
@@ -261,14 +264,14 @@ module Kind
261
264
  if ::Kind::Maybe::Value.none?(default)
262
265
  __kind_undefined(value) { Kind::Of::Callable(value) }
263
266
  else
264
- return value if value != Kind::Undefined && instance?(value)
267
+ return value if Kind::Undefined != value && instance?(value)
265
268
 
266
269
  __kind_undefined(default) { Kind::Of::Callable(default) }
267
270
  end
268
271
  end
269
272
 
270
273
  def self.__kind_undefined(value)
271
- if value == Kind::Undefined
274
+ if Kind::Undefined == value
272
275
  raise Kind::Error.new('Callable'.freeze, Kind::Undefined)
273
276
  else
274
277
  yield
@@ -280,6 +283,10 @@ module Kind
280
283
  end
281
284
  end)
282
285
 
286
+ def self.Callable?(*args)
287
+ Kind::Of::Callable.instance?(*args)
288
+ end
289
+
283
290
  # ---------------------- #
284
291
  # Built-in type checkers #
285
292
  # ---------------------- #
@@ -18,8 +18,8 @@ class KindValidator < ActiveModel::EachValidator
18
18
 
19
19
  return validate_with_default_strategy(expected, value) if expected
20
20
 
21
- return kind_of(expected, value) if expected = options[:of] || options[:is_a]
22
- return is_class(expected, value) if expected = options[:is] || options[:klass]
21
+ return kind_of(expected, value) if expected = options[:of]
22
+ return kind_is(expected, value) if expected = options[:is]
23
23
  return respond_to(expected, value) if expected = options[:respond_to]
24
24
  return instance_of(expected, value) if expected = options[:instance_of]
25
25
  return array_with(expected, value) if expected = options[:array_with]
@@ -32,26 +32,38 @@ class KindValidator < ActiveModel::EachValidator
32
32
  send(Kind::Validator.default_strategy, expected, value)
33
33
  end
34
34
 
35
- def instance_of(expected, value)
35
+ def kind_of(expected, value)
36
36
  types = Array(expected)
37
37
 
38
- return if types.any? { |type| value.instance_of?(type) }
38
+ return if types.any? { |type| value.kind_of?(type) }
39
39
 
40
- "must be an instance of: #{types.map { |klass| klass.name }.join(', ')}"
40
+ "must be a kind of: #{types.map { |klass| klass.name }.join(', ')}"
41
41
  end
42
42
 
43
- def kind_of(expected, value)
44
- types = Array(expected)
43
+ CLASS_OR_MODULE = 'Class/Module'.freeze
45
44
 
46
- return if types.any? { |type| value.is_a?(type) }
45
+ def kind_is(expected, value)
46
+ return kind_is_not(expected, value) unless expected.kind_of?(Array)
47
47
 
48
- "must be a kind of: #{types.map { |klass| klass.name }.join(', ')}"
48
+ result = expected.map { |kind| kind_is_not(kind, value) }.compact
49
+
50
+ result.empty? || result.size < expected.size ? nil : result.join(', ')
49
51
  end
50
52
 
51
- def is_class(klass, value)
52
- return if Kind.of.Class(value) == Kind.of.Class(klass) || value < klass
53
+ def kind_is_not(expected, value)
54
+ case expected
55
+ when Class
56
+ return if expected == Kind.of.Class(value) || value < expected
53
57
 
54
- "must be the class or a subclass of `#{klass.name}`"
58
+ "must be the class or a subclass of `#{expected.name}`"
59
+ when Module
60
+ return if value.kind_of?(Class) && value <= expected
61
+ return if expected == Kind.of.Module(value) || value.kind_of?(expected)
62
+
63
+ "must include the `#{expected.name}` module"
64
+ else
65
+ raise Kind::Error.new(CLASS_OR_MODULE, expected)
66
+ end
55
67
  end
56
68
 
57
69
  def respond_to(method_name, value)
@@ -60,17 +72,25 @@ class KindValidator < ActiveModel::EachValidator
60
72
  "must respond to the method `#{method_name}`"
61
73
  end
62
74
 
63
- def array_of(expected, value)
75
+ def instance_of(expected, value)
64
76
  types = Array(expected)
65
77
 
66
- return if value.is_a?(Array) && !value.empty? && value.all? { |value| types.any? { |type| value.is_a?(type) } }
78
+ return if types.any? { |type| value.instance_of?(type) }
67
79
 
68
- "must be an array of: #{types.map { |klass| klass.name }.join(', ')}"
80
+ "must be an instance of: #{types.map { |klass| klass.name }.join(', ')}"
69
81
  end
70
82
 
71
83
  def array_with(expected, value)
72
- return if value.is_a?(Array) && !value.empty? && (value - Kind.of.Array(expected)).empty?
84
+ return if value.kind_of?(Array) && !value.empty? && (value - Kind.of.Array(expected)).empty?
73
85
 
74
86
  "must be an array with: #{expected.join(', ')}"
75
87
  end
88
+
89
+ def array_of(expected, value)
90
+ types = Array(expected)
91
+
92
+ return if value.kind_of?(Array) && !value.empty? && value.all? { |value| types.any? { |type| value.kind_of?(type) } }
93
+
94
+ "must be an array of: #{types.map { |klass| klass.name }.join(', ')}"
95
+ end
76
96
  end
@@ -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 Checkable
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