kind 1.9.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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