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/error.rb
CHANGED
@@ -7,7 +7,7 @@ module Kind
|
|
7
7
|
private_constant :UNDEFINED_OBJECT
|
8
8
|
|
9
9
|
def initialize(arg, object = UNDEFINED_OBJECT)
|
10
|
-
if
|
10
|
+
if UNDEFINED_OBJECT == object
|
11
11
|
# Will be used when the exception was raised with a message. e.g:
|
12
12
|
# raise Kind::Error, "some message"
|
13
13
|
super(arg)
|
data/lib/kind/maybe.rb
CHANGED
@@ -2,9 +2,22 @@
|
|
2
2
|
|
3
3
|
module Kind
|
4
4
|
module Maybe
|
5
|
+
class Typed
|
6
|
+
def initialize(kind)
|
7
|
+
@kind_checker = Kind::Checker::Factory.create(kind)
|
8
|
+
end
|
9
|
+
|
10
|
+
def wrap(value)
|
11
|
+
@kind_checker.as_maybe(value)
|
12
|
+
end
|
13
|
+
|
14
|
+
alias_method :new, :wrap
|
15
|
+
alias_method :[], :wrap
|
16
|
+
end
|
17
|
+
|
5
18
|
module Value
|
6
19
|
def self.none?(value)
|
7
|
-
value
|
20
|
+
value.nil? || Undefined == value
|
8
21
|
end
|
9
22
|
|
10
23
|
def self.some?(value)
|
@@ -16,7 +29,7 @@ module Kind
|
|
16
29
|
attr_reader :value
|
17
30
|
|
18
31
|
def initialize(value)
|
19
|
-
@value = value
|
32
|
+
@value = value.kind_of?(Result) ? value.value : value
|
20
33
|
end
|
21
34
|
|
22
35
|
def value_or(method_name = Undefined, &block)
|
@@ -42,9 +55,9 @@ module Kind
|
|
42
55
|
INVALID_DEFAULT_ARG = 'the default value must be defined as an argument or block'.freeze
|
43
56
|
|
44
57
|
def value_or(default = Undefined, &block)
|
45
|
-
raise ArgumentError, INVALID_DEFAULT_ARG if
|
58
|
+
raise ArgumentError, INVALID_DEFAULT_ARG if Undefined == default && !block
|
46
59
|
|
47
|
-
|
60
|
+
Undefined != default ? default : block.call
|
48
61
|
end
|
49
62
|
|
50
63
|
def none?; true; end
|
@@ -55,12 +68,14 @@ module Kind
|
|
55
68
|
|
56
69
|
alias_method :then, :map
|
57
70
|
|
58
|
-
def try(method_name = Undefined, &block)
|
59
|
-
Kind.of.Symbol(method_name) if
|
71
|
+
def try!(method_name = Undefined, *args, &block)
|
72
|
+
Kind.of.Symbol(method_name) if Undefined != method_name
|
60
73
|
|
61
|
-
|
74
|
+
NONE_WITH_NIL_VALUE
|
62
75
|
end
|
63
76
|
|
77
|
+
alias_method :try, :try!
|
78
|
+
|
64
79
|
private_constant :INVALID_DEFAULT_ARG
|
65
80
|
end
|
66
81
|
|
@@ -79,32 +94,90 @@ module Kind
|
|
79
94
|
def map(&fn)
|
80
95
|
result = fn.call(@value)
|
81
96
|
|
82
|
-
|
83
|
-
return NONE_WITH_UNDEFINED_VALUE if result == Undefined
|
84
|
-
|
85
|
-
Some.new(result)
|
97
|
+
resolve(result)
|
86
98
|
end
|
87
99
|
|
88
100
|
alias_method :then, :map
|
89
101
|
|
90
|
-
def try(method_name = Undefined, *args, &block)
|
91
|
-
|
102
|
+
def try!(method_name = Undefined, *args, &block)
|
103
|
+
Kind::Of::Symbol(method_name) if Undefined != method_name
|
92
104
|
|
93
|
-
|
105
|
+
__try__(method_name, args, block)
|
106
|
+
end
|
94
107
|
|
95
|
-
|
108
|
+
def try(method_name = Undefined, *args, &block)
|
109
|
+
if (Undefined != method_name && value.respond_to?(Kind::Of::Symbol(method_name))) ||
|
110
|
+
(Undefined == method_name && block)
|
111
|
+
__try__(method_name, args, block)
|
112
|
+
else
|
113
|
+
NONE_WITH_NIL_VALUE
|
114
|
+
end
|
96
115
|
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
def __try__(method_name = Undefined, args, block)
|
120
|
+
fn = Undefined == method_name ? block : method_name.to_proc
|
121
|
+
|
122
|
+
result = args.empty? ? fn.call(value) : fn.call(*args.unshift(value))
|
123
|
+
|
124
|
+
resolve(result)
|
125
|
+
end
|
126
|
+
|
127
|
+
def resolve(result)
|
128
|
+
return result if Maybe::None === result
|
129
|
+
return NONE_WITH_NIL_VALUE if result.nil?
|
130
|
+
return NONE_WITH_UNDEFINED_VALUE if Undefined == result
|
131
|
+
|
132
|
+
Some.new(result)
|
133
|
+
end
|
97
134
|
end
|
98
135
|
|
99
136
|
def self.new(value)
|
100
137
|
result_type = Maybe::Value.none?(value) ? None : Some
|
101
|
-
result_type.new(value
|
138
|
+
result_type.new(value)
|
102
139
|
end
|
103
140
|
|
104
|
-
def self.[](value)
|
141
|
+
def self.[](value)
|
105
142
|
new(value)
|
106
143
|
end
|
144
|
+
|
145
|
+
def self.wrap(value)
|
146
|
+
new(value)
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.none
|
150
|
+
NONE_WITH_NIL_VALUE
|
151
|
+
end
|
152
|
+
|
153
|
+
VALUE_CANT_BE_NONE = "value can't be nil or Kind::Undefined".freeze
|
154
|
+
|
155
|
+
private_constant :VALUE_CANT_BE_NONE
|
156
|
+
|
157
|
+
def self.some(value)
|
158
|
+
return Maybe::Some.new(value) if Value.some?(value)
|
159
|
+
|
160
|
+
raise ArgumentError, VALUE_CANT_BE_NONE
|
161
|
+
end
|
107
162
|
end
|
108
163
|
|
109
164
|
Optional = Maybe
|
165
|
+
|
166
|
+
None = Maybe.none
|
167
|
+
|
168
|
+
def self.None
|
169
|
+
Kind::None
|
170
|
+
end
|
171
|
+
|
172
|
+
def self.Some(value)
|
173
|
+
Maybe.some(value)
|
174
|
+
end
|
175
|
+
|
176
|
+
def self.Maybe(kind)
|
177
|
+
Maybe::Typed.new(kind)
|
178
|
+
end
|
179
|
+
|
180
|
+
def self.Optional(kind)
|
181
|
+
Maybe::Typed.new(kind)
|
182
|
+
end
|
110
183
|
end
|
data/lib/kind/types.rb
CHANGED
@@ -10,15 +10,25 @@ module Kind
|
|
10
10
|
def self.%{method_name}(object = Undefined, options = Empty::HASH)
|
11
11
|
default = options[:or]
|
12
12
|
|
13
|
-
return Kind::Of::%{kind_name} if
|
13
|
+
return Kind::Of::%{kind_name} if Undefined == object && default.nil?
|
14
14
|
|
15
|
-
Kind::Of
|
15
|
+
is_instance = Kind::Of::%{kind_name}.__is_instance__(object)
|
16
|
+
|
17
|
+
return object if is_instance
|
18
|
+
|
19
|
+
Kind::Of.(::%{kind_name_to_check}, object && default ? default : object || default)
|
20
|
+
end
|
21
|
+
RUBY
|
22
|
+
|
23
|
+
KIND_OF_IS = <<-RUBY
|
24
|
+
def self.%{method_name}?(*args)
|
25
|
+
Kind::Of::%{kind_name}.instance?(*args)
|
16
26
|
end
|
17
27
|
RUBY
|
18
28
|
|
19
29
|
KIND_IS = <<-RUBY
|
20
30
|
def self.%{method_name}(value = Undefined)
|
21
|
-
return Kind::Is::%{kind_name} if
|
31
|
+
return Kind::Is::%{kind_name} if Undefined == value
|
22
32
|
|
23
33
|
Kind::Is.__call__(::%{kind_name_to_check}, value)
|
24
34
|
end
|
@@ -88,11 +98,12 @@ module Kind
|
|
88
98
|
kind_name = params[:kind_name]
|
89
99
|
params[:kind_name_to_check] ||= kind_name
|
90
100
|
|
91
|
-
kind_checker = ::Module.new { extend
|
101
|
+
kind_checker = ::Module.new { extend Checker::Protocol }
|
92
102
|
kind_checker.module_eval("def self.__kind; #{params[:kind_name_to_check]}; end")
|
93
103
|
|
94
104
|
kind_of_mod.instance_eval(KIND_OF % params)
|
95
105
|
kind_of_mod.const_set(method_name, kind_checker)
|
106
|
+
kind_of_mod.instance_eval(KIND_OF_IS % params)
|
96
107
|
end
|
97
108
|
|
98
109
|
unless kind_is_mod.respond_to?(method_name)
|
data/lib/kind/undefined.rb
CHANGED
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:
|
4
|
+
version: 3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rodrigo Serradura
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-25 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:
|
@@ -32,6 +32,8 @@ files:
|
|
32
32
|
- lib/kind/active_model/kind_validator.rb
|
33
33
|
- lib/kind/active_model/validation.rb
|
34
34
|
- lib/kind/checker.rb
|
35
|
+
- lib/kind/checker/factory.rb
|
36
|
+
- lib/kind/checker/protocol.rb
|
35
37
|
- lib/kind/empty.rb
|
36
38
|
- lib/kind/error.rb
|
37
39
|
- lib/kind/is.rb
|