kind 4.0.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/.tool-versions +1 -1
- data/.travis.sh +39 -7
- data/.travis.yml +1 -2
- data/CHANGELOG.md +486 -28
- data/Gemfile +13 -6
- data/README.md +153 -49
- data/kind.gemspec +1 -1
- data/lib/kind.rb +2 -84
- data/lib/kind/__lib__/action_steps.rb +57 -0
- data/lib/kind/__lib__/attributes.rb +66 -0
- data/lib/kind/__lib__/kind.rb +51 -0
- data/lib/kind/__lib__/of.rb +17 -0
- data/lib/kind/__lib__/strict.rb +49 -0
- data/lib/kind/__lib__/undefined.rb +14 -0
- data/lib/kind/action.rb +127 -0
- data/lib/kind/active_model/validation.rb +3 -4
- data/lib/kind/basic.rb +79 -0
- data/lib/kind/basic/error.rb +29 -0
- data/lib/kind/{undefined.rb → basic/undefined.rb} +6 -1
- data/lib/kind/dig.rb +21 -5
- data/lib/kind/either.rb +30 -0
- data/lib/kind/either/left.rb +29 -0
- data/lib/kind/either/methods.rb +17 -0
- data/lib/kind/either/monad.rb +65 -0
- data/lib/kind/either/monad/wrapper.rb +19 -0
- data/lib/kind/either/right.rb +38 -0
- data/lib/kind/empty.rb +2 -2
- data/lib/kind/empty/constant.rb +7 -0
- data/lib/kind/enum.rb +63 -0
- data/lib/kind/enum/item.rb +40 -0
- data/lib/kind/enum/methods.rb +72 -0
- data/lib/kind/function.rb +45 -0
- data/lib/kind/functional.rb +89 -0
- data/lib/kind/functional/action.rb +90 -0
- data/lib/kind/immutable_attributes.rb +34 -0
- data/lib/kind/immutable_attributes/initializer.rb +70 -0
- data/lib/kind/immutable_attributes/reader.rb +38 -0
- data/lib/kind/maybe.rb +37 -12
- data/lib/kind/maybe/methods.rb +21 -0
- data/lib/kind/maybe/monad.rb +82 -0
- data/lib/kind/maybe/monad/wrapper.rb +19 -0
- data/lib/kind/maybe/none.rb +12 -19
- data/lib/kind/maybe/some.rb +68 -26
- data/lib/kind/maybe/typed.rb +11 -5
- data/lib/kind/maybe/{wrappable.rb → wrapper.rb} +9 -7
- data/lib/kind/monad.rb +22 -0
- data/lib/kind/monads.rb +5 -0
- data/lib/kind/objects.rb +17 -0
- data/lib/kind/objects/basic_object.rb +43 -0
- data/lib/kind/objects/modules.rb +32 -0
- data/lib/kind/{type_checkers → objects/modules}/core/array.rb +3 -1
- data/lib/kind/{type_checkers → objects/modules}/core/class.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/core/comparable.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/core/enumerable.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/core/enumerator.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/core/file.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/core/float.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/core/hash.rb +3 -1
- data/lib/kind/{type_checkers → objects/modules}/core/integer.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/core/io.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/core/method.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/core/module.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/core/numeric.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/core/proc.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/core/queue.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/core/range.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/core/regexp.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/core/string.rb +3 -1
- data/lib/kind/{type_checkers → objects/modules}/core/struct.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/core/symbol.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/core/time.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/custom/boolean.rb +2 -2
- data/lib/kind/{type_checkers → objects/modules}/custom/callable.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/custom/lambda.rb +1 -1
- data/lib/kind/{type_checkers → objects/modules}/stdlib/open_struct.rb +3 -1
- data/lib/kind/{type_checkers → objects/modules}/stdlib/set.rb +3 -1
- data/lib/kind/objects/nil.rb +17 -0
- data/lib/kind/objects/not_nil.rb +9 -0
- data/lib/kind/objects/object.rb +56 -0
- data/lib/kind/objects/respond_to.rb +30 -0
- data/lib/kind/objects/union_type.rb +44 -0
- data/lib/kind/presence.rb +4 -2
- data/lib/kind/result.rb +31 -0
- data/lib/kind/result/abstract.rb +53 -0
- data/lib/kind/result/failure.rb +33 -0
- data/lib/kind/result/methods.rb +17 -0
- data/lib/kind/result/monad.rb +74 -0
- data/lib/kind/result/monad/wrapper.rb +19 -0
- data/lib/kind/result/success.rb +53 -0
- data/lib/kind/strict/disabled.rb +34 -0
- data/lib/kind/try.rb +21 -11
- data/lib/kind/validator.rb +111 -0
- data/lib/kind/version.rb +1 -1
- metadata +78 -48
- data/lib/kind/active_model/kind_validator.rb +0 -96
- data/lib/kind/core.rb +0 -9
- data/lib/kind/core/deprecation.rb +0 -29
- data/lib/kind/core/kind.rb +0 -61
- data/lib/kind/core/undefined.rb +0 -7
- data/lib/kind/deprecations/built_in_type_checkers.rb +0 -23
- data/lib/kind/deprecations/checker.rb +0 -16
- data/lib/kind/deprecations/checker/factory.rb +0 -31
- data/lib/kind/deprecations/checker/protocol.rb +0 -73
- data/lib/kind/deprecations/is.rb +0 -35
- data/lib/kind/deprecations/of.rb +0 -258
- data/lib/kind/deprecations/types.rb +0 -121
- data/lib/kind/error.rb +0 -15
- data/lib/kind/maybe/result.rb +0 -51
- data/lib/kind/type_checker.rb +0 -73
- data/lib/kind/type_checkers.rb +0 -30
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
warn '[DEPRECATION] "kind/active_model/validation" is deprecated; use "kind/validator" instead. ' \
|
4
|
+
'It will be removed on next major release.'
|
5
|
+
|
4
6
|
require 'kind/validator'
|
5
|
-
require 'active_model'
|
6
|
-
require 'active_model/validations'
|
7
|
-
require_relative 'kind_validator'
|
data/lib/kind/basic.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kind/version'
|
4
|
+
|
5
|
+
require 'kind/__lib__/kind'
|
6
|
+
require 'kind/__lib__/undefined'
|
7
|
+
|
8
|
+
require 'kind/basic/undefined'
|
9
|
+
require 'kind/basic/error'
|
10
|
+
|
11
|
+
module Kind
|
12
|
+
extend self
|
13
|
+
|
14
|
+
def is?(kind, arg)
|
15
|
+
KIND.is?(kind, arg)
|
16
|
+
end
|
17
|
+
|
18
|
+
def is(*args)
|
19
|
+
warn '[DEPRECATION] Kind.is will behave like Kind.is! in the next major release; ' \
|
20
|
+
'use Kind.is? instead.'
|
21
|
+
|
22
|
+
is?(*args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def is!(kind, arg, label: nil)
|
26
|
+
return arg if KIND.is?(kind, arg)
|
27
|
+
|
28
|
+
label_text = label ? "#{label}: " : ''
|
29
|
+
|
30
|
+
raise Kind::Error.new("#{label_text}#{arg} expected to be a #{kind}")
|
31
|
+
end
|
32
|
+
|
33
|
+
def of?(kind, *args)
|
34
|
+
KIND.of?(kind, args)
|
35
|
+
end
|
36
|
+
|
37
|
+
def of_class?(value)
|
38
|
+
OF.class?(value)
|
39
|
+
end
|
40
|
+
|
41
|
+
def of_module?(value)
|
42
|
+
OF.module?(value)
|
43
|
+
end
|
44
|
+
|
45
|
+
def respond_to?(value, *method_names)
|
46
|
+
return super(value) if method_names.empty?
|
47
|
+
|
48
|
+
KIND.interface?(method_names, value)
|
49
|
+
end
|
50
|
+
|
51
|
+
def of(kind, value, label: nil)
|
52
|
+
STRICT.object_is_a(kind, value, label)
|
53
|
+
end
|
54
|
+
|
55
|
+
alias_method :of!, :of
|
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
|
+
|
65
|
+
def of_module_or_class(value)
|
66
|
+
STRICT.module_or_class(value)
|
67
|
+
end
|
68
|
+
|
69
|
+
def respond_to(value, *method_names)
|
70
|
+
method_names.each { |method_name| KIND.respond_to!(method_name, value) }
|
71
|
+
|
72
|
+
value
|
73
|
+
end
|
74
|
+
alias_method :respond_to!, :respond_to
|
75
|
+
|
76
|
+
def value(kind, value, default:)
|
77
|
+
KIND.value(kind, value, of(kind, default))
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kind
|
4
|
+
class Error < StandardError
|
5
|
+
INVALID_DEFAULT_ARG = 'the default value must be defined as an argument or block'.freeze
|
6
|
+
|
7
|
+
def self.wrong_number_of_args!(given:, expected:)
|
8
|
+
raise ArgumentError, "wrong number of arguments (given #{given}, expected #{expected})"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.invalid_default_arg!
|
12
|
+
raise ArgumentError, INVALID_DEFAULT_ARG
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(arg, object = UNDEFINED, label: nil)
|
16
|
+
if UNDEFINED == object
|
17
|
+
# Will be used when the exception was raised with a message. e.g:
|
18
|
+
# raise Kind::Error, "some message"
|
19
|
+
super(arg)
|
20
|
+
else
|
21
|
+
label_text = label ? "#{label}: " : ''
|
22
|
+
|
23
|
+
super("#{label_text}#{object.inspect} expected to be a kind of #{arg}")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private_constant :INVALID_DEFAULT_ARG
|
28
|
+
end
|
29
|
+
end
|
@@ -1,9 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Kind
|
3
4
|
Undefined = Object.new.tap do |undefined|
|
4
5
|
def undefined.inspect
|
5
6
|
@inspect ||= 'Kind::Undefined'.freeze
|
6
7
|
end
|
8
|
+
undefined.inspect
|
9
|
+
|
10
|
+
def undefined.empty?
|
11
|
+
true
|
12
|
+
end
|
7
13
|
|
8
14
|
def undefined.to_s
|
9
15
|
inspect
|
@@ -23,7 +29,6 @@ module Kind
|
|
23
29
|
default.respond_to?(:call) ? default.call : default
|
24
30
|
end
|
25
31
|
|
26
|
-
undefined.inspect
|
27
32
|
undefined.freeze
|
28
33
|
end
|
29
34
|
end
|
data/lib/kind/dig.rb
CHANGED
@@ -1,23 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'kind/basic'
|
4
|
+
require 'kind/empty'
|
5
|
+
require 'kind/presence'
|
6
|
+
|
3
7
|
module Kind
|
4
8
|
module Dig
|
5
9
|
extend self
|
6
10
|
|
7
|
-
def call(data, keys)
|
8
|
-
return unless keys.is_a?(::Array)
|
9
|
-
|
11
|
+
def call!(data, keys = Empty::ARRAY) # :nodoc
|
10
12
|
keys.reduce(data) do |memo, key|
|
11
13
|
value = get(memo, key)
|
12
14
|
|
13
|
-
break if KIND.
|
15
|
+
break if KIND.nil_or_undefined?(value)
|
14
16
|
|
15
17
|
value
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
21
|
+
def call(data, *input)
|
22
|
+
args = input.size == 1 && input[0].kind_of?(::Array) ? input[0] : input
|
23
|
+
|
24
|
+
result = call!(data, args)
|
25
|
+
|
26
|
+
return result unless block_given?
|
27
|
+
|
28
|
+
yield(result) unless KIND.nil_or_undefined?(result)
|
29
|
+
end
|
30
|
+
|
31
|
+
def presence(*args, &block)
|
32
|
+
Presence.(call(*args, &block))
|
33
|
+
end
|
34
|
+
|
19
35
|
def [](*keys)
|
20
|
-
->(data) { call(data, keys) }
|
36
|
+
->(data) { call!(data, keys) }
|
21
37
|
end
|
22
38
|
|
23
39
|
private
|
data/lib/kind/either.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kind/basic'
|
4
|
+
|
5
|
+
module Kind
|
6
|
+
module Either
|
7
|
+
require 'kind/either/monad'
|
8
|
+
require 'kind/either/left'
|
9
|
+
require 'kind/either/right'
|
10
|
+
require 'kind/either/methods'
|
11
|
+
|
12
|
+
extend self
|
13
|
+
|
14
|
+
def new(value)
|
15
|
+
Right[value]
|
16
|
+
end
|
17
|
+
|
18
|
+
alias_method :[], :new
|
19
|
+
|
20
|
+
def self.from
|
21
|
+
result = yield
|
22
|
+
|
23
|
+
Either::Monad === result ? result : Either::Right[result]
|
24
|
+
rescue StandardError => e
|
25
|
+
Either::Left[e]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
extend Either::Methods
|
30
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kind
|
4
|
+
class Either::Left < Either::Monad
|
5
|
+
def left?
|
6
|
+
true
|
7
|
+
end
|
8
|
+
|
9
|
+
def value_or(default = UNDEFINED, &block)
|
10
|
+
Error.invalid_default_arg! if UNDEFINED == default && !block
|
11
|
+
|
12
|
+
UNDEFINED != default ? default : block.call
|
13
|
+
end
|
14
|
+
|
15
|
+
def map(&_)
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
alias_method :map!, :map
|
20
|
+
alias_method :then, :map
|
21
|
+
alias_method :then!, :map
|
22
|
+
alias_method :and_then, :map
|
23
|
+
alias_method :and_then!, :map
|
24
|
+
|
25
|
+
def inspect
|
26
|
+
'#<%s value=%p>' % ['Kind::Left', value]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kind
|
4
|
+
module Either::Methods
|
5
|
+
def Left(value)
|
6
|
+
Either::Left[value]
|
7
|
+
end
|
8
|
+
|
9
|
+
def Right(value)
|
10
|
+
Either::Right[value]
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.included(base)
|
14
|
+
base.send(:private, :Left, :Right)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kind
|
4
|
+
class Either::Monad
|
5
|
+
require 'kind/either/monad/wrapper'
|
6
|
+
|
7
|
+
attr_reader :value
|
8
|
+
|
9
|
+
singleton_class.send(:alias_method, :[], :new)
|
10
|
+
|
11
|
+
def initialize(value)
|
12
|
+
@value = value
|
13
|
+
end
|
14
|
+
|
15
|
+
def left?
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
def right?
|
20
|
+
false
|
21
|
+
end
|
22
|
+
|
23
|
+
def value_or(_method_name = UNDEFINED, &block)
|
24
|
+
raise NotImplementedError
|
25
|
+
end
|
26
|
+
|
27
|
+
def map(&_)
|
28
|
+
raise NotImplementedError
|
29
|
+
end
|
30
|
+
|
31
|
+
alias_method :map!, :map
|
32
|
+
alias_method :then, :map
|
33
|
+
alias_method :then!, :map
|
34
|
+
alias_method :and_then, :map
|
35
|
+
alias_method :and_then!, :map
|
36
|
+
|
37
|
+
def on
|
38
|
+
monad = Wrapper.new(self)
|
39
|
+
|
40
|
+
yield(monad)
|
41
|
+
|
42
|
+
monad.output
|
43
|
+
end
|
44
|
+
|
45
|
+
def on_right(matcher = UNDEFINED)
|
46
|
+
yield(value) if right? && either?(matcher)
|
47
|
+
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
def on_left(matcher = UNDEFINED)
|
52
|
+
yield(value) if left? && either?(matcher)
|
53
|
+
|
54
|
+
self
|
55
|
+
end
|
56
|
+
|
57
|
+
def either?(matcher)
|
58
|
+
UNDEFINED == matcher || matcher === value
|
59
|
+
end
|
60
|
+
|
61
|
+
def ===(monad)
|
62
|
+
self.class === monad && self.value === monad.value
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kind
|
4
|
+
require 'kind/monad'
|
5
|
+
|
6
|
+
class Either::Monad::Wrapper < Kind::Monad::Wrapper
|
7
|
+
def left(matcher = UNDEFINED)
|
8
|
+
return if @monad.right? || output?
|
9
|
+
|
10
|
+
@output = yield(@monad.value) if @monad.either?(matcher)
|
11
|
+
end
|
12
|
+
|
13
|
+
def right(matcher = UNDEFINED)
|
14
|
+
return if @monad.left? || output?
|
15
|
+
|
16
|
+
@output = yield(@monad.value) if @monad.either?(matcher)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kind
|
4
|
+
class Either::Right < Either::Monad
|
5
|
+
def right?
|
6
|
+
true
|
7
|
+
end
|
8
|
+
|
9
|
+
def value_or(_default = UNDEFINED, &block)
|
10
|
+
@value
|
11
|
+
end
|
12
|
+
|
13
|
+
def map(&fn)
|
14
|
+
map!(&fn)
|
15
|
+
rescue Kind::Monad::Error => e
|
16
|
+
raise e
|
17
|
+
rescue StandardError => e
|
18
|
+
Either::Left[e]
|
19
|
+
end
|
20
|
+
|
21
|
+
def map!(&fn)
|
22
|
+
monad = fn.call(@value)
|
23
|
+
|
24
|
+
return monad if Either::Monad === monad
|
25
|
+
|
26
|
+
raise Kind::Monad::Error.new('Kind::Right | Kind::Left', monad)
|
27
|
+
end
|
28
|
+
|
29
|
+
alias_method :then, :map
|
30
|
+
alias_method :then!, :map!
|
31
|
+
alias_method :and_then, :map
|
32
|
+
alias_method :and_then!, :map!
|
33
|
+
|
34
|
+
def inspect
|
35
|
+
'#<%s value=%p>' % ['Kind::Right', value]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/kind/empty.rb
CHANGED
data/lib/kind/enum.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
require 'kind/basic'
|
5
|
+
|
6
|
+
module Kind
|
7
|
+
module Enum
|
8
|
+
require 'kind/enum/item'
|
9
|
+
require 'kind/enum/methods'
|
10
|
+
|
11
|
+
extend self
|
12
|
+
|
13
|
+
def values(input)
|
14
|
+
enum_module = ::Module.new
|
15
|
+
|
16
|
+
enum_items =
|
17
|
+
case input
|
18
|
+
when ::Hash then create_from_hash(input)
|
19
|
+
when ::Array then create_from_array(input)
|
20
|
+
else raise ArgumentError, 'use an array or hash to define a Kind::Enum'
|
21
|
+
end
|
22
|
+
|
23
|
+
enum_items.each { |item| enum_module.const_set(item.name, item) }
|
24
|
+
|
25
|
+
enum_map = enum_items.each_with_object({}) do |item, memo|
|
26
|
+
memo[item.to_s] = item
|
27
|
+
memo[item.value] = item
|
28
|
+
memo[item.to_sym] = item
|
29
|
+
end
|
30
|
+
|
31
|
+
enum_module.const_set(:ENUM__MAP, enum_map)
|
32
|
+
enum_module.const_set(:ENUM__HASH, enum_items.map(&:to_ary).to_h.freeze)
|
33
|
+
enum_module.const_set(:ENUM__KEYS, ::Set.new(enum_items.map(&:key)).freeze)
|
34
|
+
enum_module.const_set(:ENUM__VALS, ::Set.new(enum_items.map(&:value)).freeze)
|
35
|
+
enum_module.const_set(:ENUM__REFS, ::Set.new(enum_map.keys))
|
36
|
+
enum_module.const_set(:ENUM__ITEMS, enum_items.freeze)
|
37
|
+
|
38
|
+
enum_module.send(:private_constant, :ENUM__MAP, :ENUM__HASH, :ENUM__KEYS,
|
39
|
+
:ENUM__VALS, :ENUM__REFS, :ENUM__ITEMS)
|
40
|
+
|
41
|
+
enum_module.module_eval(METHODS)
|
42
|
+
|
43
|
+
enum_module.extend(enum_module)
|
44
|
+
enum_module
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def create_from_hash(input)
|
50
|
+
input.map { |key, value| build_item(key, value) }
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_from_array(input)
|
54
|
+
input.map.with_index { |key, index| build_item(key, index) }
|
55
|
+
end
|
56
|
+
|
57
|
+
def build_item(key, value)
|
58
|
+
return Item.new(key, value) if key.respond_to?(:to_sym)
|
59
|
+
|
60
|
+
raise ArgumentError, 'use a string or symbol to define a Kind::Enum item'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|