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
data/kind.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.description = %q{A simple type system (at runtime) for Ruby - free of dependencies.}
|
11
11
|
spec.homepage = 'https://github.com/serradura/kind'
|
12
12
|
spec.license = 'MIT'
|
13
|
-
spec.required_ruby_version = Gem::Requirement.new('>= 2.
|
13
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.1.0')
|
14
14
|
|
15
15
|
spec.metadata['homepage_uri'] = spec.homepage
|
16
16
|
spec.metadata['source_code_uri'] = 'https://github.com/serradura/kind'
|
data/lib/kind.rb
CHANGED
@@ -1,86 +1,4 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
4
|
-
require '
|
5
|
-
|
6
|
-
require 'kind/version'
|
7
|
-
require 'kind/core'
|
8
|
-
|
9
|
-
require 'kind/error'
|
10
|
-
require 'kind/empty'
|
11
|
-
require 'kind/dig'
|
12
|
-
require 'kind/try'
|
13
|
-
require 'kind/presence'
|
14
|
-
require 'kind/undefined'
|
15
|
-
require 'kind/type_checker'
|
16
|
-
|
17
|
-
require 'kind/type_checkers'
|
18
|
-
require 'kind/maybe'
|
19
|
-
|
20
|
-
require 'kind/deprecations/checker'
|
21
|
-
require 'kind/deprecations/of'
|
22
|
-
require 'kind/deprecations/is'
|
23
|
-
require 'kind/deprecations/types'
|
24
|
-
require 'kind/deprecations/built_in_type_checkers'
|
25
|
-
|
26
|
-
module Kind
|
27
|
-
def self.is?(kind, arg)
|
28
|
-
KIND.is?(kind, arg)
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.of?(kind, *args)
|
32
|
-
KIND.of?(kind, args)
|
33
|
-
end
|
34
|
-
|
35
|
-
def self.of_class?(value)
|
36
|
-
KIND.of_class?(value)
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.of_module?(value)
|
40
|
-
KIND.of_module?(value)
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.respond_to(value, *method_names)
|
44
|
-
method_names.each { |method_name| KIND.respond_to!(method_name, value) }
|
45
|
-
|
46
|
-
value
|
47
|
-
end
|
48
|
-
|
49
|
-
def self.of_module_or_class(value)
|
50
|
-
KIND.of_module_or_class!(value)
|
51
|
-
end
|
52
|
-
|
53
|
-
def self.is(expected = UNDEFINED, object = UNDEFINED)
|
54
|
-
if UNDEFINED == expected && UNDEFINED == object
|
55
|
-
DEPRECATION.warn('`Kind.is` without args is deprecated. This behavior will be removed in %{version}')
|
56
|
-
|
57
|
-
return Is
|
58
|
-
end
|
59
|
-
|
60
|
-
return is?(expected, object) if UNDEFINED != object
|
61
|
-
|
62
|
-
raise ArgumentError, 'wrong number of arguments (given 1, expected 2)'
|
63
|
-
end
|
64
|
-
|
65
|
-
def self.of(kind = UNDEFINED, object = UNDEFINED)
|
66
|
-
if UNDEFINED == kind && UNDEFINED == object
|
67
|
-
DEPRECATION.warn('`Kind.of` without args is deprecated. This behavior will be removed in %{version}')
|
68
|
-
|
69
|
-
Of
|
70
|
-
elsif UNDEFINED != object
|
71
|
-
KIND.of!(kind, object)
|
72
|
-
else
|
73
|
-
DEPRECATION.warn_method_replacement('Kind.of(<Kind>)', 'Kind::Of(<Kind>)')
|
74
|
-
|
75
|
-
Checker::Factory.create(kind)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def self.value(kind, value, default:)
|
80
|
-
KIND.value(kind, value, of(kind, default))
|
81
|
-
end
|
82
|
-
|
83
|
-
def self.Of(kind, opt = Empty::HASH)
|
84
|
-
TypeChecker::Object.new(kind, opt)
|
85
|
-
end
|
86
|
-
end
|
3
|
+
require 'kind/basic'
|
4
|
+
require 'kind/objects'
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kind
|
4
|
+
module ACTION_STEPS
|
5
|
+
private
|
6
|
+
|
7
|
+
def Check(mthod); ->(value) { __Check(thod, value) }; end
|
8
|
+
def Step(mthod); ->(value) { __Step(mthod, value) }; end
|
9
|
+
def Map(mthod); ->(value) { __Map(mthod, value) }; end
|
10
|
+
def Tee(mthod); ->(value) { __Tee(mthod, value) }; end
|
11
|
+
def Try(mthod, opt = Empty::HASH)
|
12
|
+
->(value) { __Try(mthod, value, opt) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def Check!(mthod, value); __Check(mthod, value); end
|
16
|
+
def Step!(mthod, value); __Step(mthod, value); end
|
17
|
+
def Map!(mthod, value); __Map(mthod, value); end
|
18
|
+
def Tee!(mthod, value); __Tee(mthod, value); end
|
19
|
+
def Try!(mthod, value, opt = Empty::HASH); __Try(mthod, value, opt); end
|
20
|
+
|
21
|
+
def __Check(mthod, value) # :nodoc:
|
22
|
+
__resolve_step(mthod, value) ? Success(mthod, value) : Failure(mthod, value)
|
23
|
+
end
|
24
|
+
|
25
|
+
def __Step(mthod, value) # :nodoc:
|
26
|
+
__resolve_step(mthod, value)
|
27
|
+
end
|
28
|
+
|
29
|
+
def __Map(mthod, value) # :nodoc:
|
30
|
+
Success(mthod, __resolve_step(mthod, value))
|
31
|
+
end
|
32
|
+
|
33
|
+
def __Tee(mthod, value) # :nodoc:
|
34
|
+
__resolve_step(mthod, value)
|
35
|
+
|
36
|
+
Success(mthod, value)
|
37
|
+
end
|
38
|
+
|
39
|
+
def __Try(mthod, value, opt = Empty::HASH) # :nodoc:
|
40
|
+
begin
|
41
|
+
Success(mthod, __resolve_step(mthod, value))
|
42
|
+
rescue opt.fetch(:catch, StandardError) => e
|
43
|
+
Failure(mthod, __map_step_exception(e))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def __resolve_step(mthod, value) # :nodoc:
|
48
|
+
send(mthod, value)
|
49
|
+
end
|
50
|
+
|
51
|
+
def __map_step_exception(value) # :nodoc:
|
52
|
+
value
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private_constant :ACTION_STEPS
|
57
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kind/__lib__/kind'
|
4
|
+
require 'kind/__lib__/undefined'
|
5
|
+
|
6
|
+
module Kind
|
7
|
+
module ATTRIBUTES
|
8
|
+
extend self
|
9
|
+
|
10
|
+
def name!(name)
|
11
|
+
STRICT.kind_of(::Symbol, name)
|
12
|
+
end
|
13
|
+
|
14
|
+
def value(kind, default, visibility = :private)
|
15
|
+
[kind, default, visibility]
|
16
|
+
end
|
17
|
+
|
18
|
+
def value_to_assign(kind, default, hash, name)
|
19
|
+
raw_value = hash[name]
|
20
|
+
|
21
|
+
return raw_value if kind.nil? && UNDEFINED == default
|
22
|
+
|
23
|
+
value = resolve_value_to_assign(kind, default, raw_value)
|
24
|
+
|
25
|
+
(kind.nil? || kind === value) ? value : nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def value!(kind, default)
|
29
|
+
return value(kind, default) unless kind.nil?
|
30
|
+
|
31
|
+
raise Error.new("kind expected to not be nil")
|
32
|
+
end
|
33
|
+
|
34
|
+
def value_to_assign!(kind, default, hash, name)
|
35
|
+
value = resolve_value_to_assign(kind, default, hash[name])
|
36
|
+
|
37
|
+
Kind.of(kind, value, label: name)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def resolve_value_to_assign(kind, default, value)
|
43
|
+
if kind == ::Proc
|
44
|
+
UNDEFINED == default ? value : KIND.value(kind, value, default)
|
45
|
+
else
|
46
|
+
default_is_a_callable = default.respond_to?(:call)
|
47
|
+
|
48
|
+
default_value =
|
49
|
+
if default_is_a_callable
|
50
|
+
default_fn = Proc === default ? default : default.method(:call)
|
51
|
+
|
52
|
+
default_fn.arity != 0 ? default_fn.call(value) : default_fn.call
|
53
|
+
else
|
54
|
+
default
|
55
|
+
end
|
56
|
+
|
57
|
+
return value if UNDEFINED == default_value
|
58
|
+
return default_value || value if kind.nil?
|
59
|
+
|
60
|
+
default_is_a_callable ? KIND.value(kind, default_value, value) : KIND.value(kind, value, default_value)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private_constant :ATTRIBUTES
|
66
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kind/__lib__/strict'
|
4
|
+
|
5
|
+
module Kind
|
6
|
+
module KIND
|
7
|
+
extend self
|
8
|
+
|
9
|
+
def nil_or_undefined?(value) # :nodoc:
|
10
|
+
value.nil? || Undefined == value
|
11
|
+
end
|
12
|
+
|
13
|
+
def of?(kind, values) # :nodoc:
|
14
|
+
of_kind = -> value { kind === value }
|
15
|
+
|
16
|
+
values.empty? ? of_kind : values.all?(&of_kind)
|
17
|
+
end
|
18
|
+
|
19
|
+
def respond_to!(method_name, value) # :nodoc:
|
20
|
+
return value if value.respond_to?(method_name)
|
21
|
+
|
22
|
+
raise Error.new("expected #{value} to respond to :#{method_name}")
|
23
|
+
end
|
24
|
+
|
25
|
+
def interface?(method_names, value) # :nodoc:
|
26
|
+
method_names.all? { |method_name| value.respond_to?(method_name) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def value(kind, arg, default) # :nodoc:
|
30
|
+
kind === arg ? arg : default
|
31
|
+
end
|
32
|
+
|
33
|
+
def is?(expected, value) # :nodoc:
|
34
|
+
is(STRICT.module_or_class(expected), value)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def is(expected_kind, value) # :nodoc:
|
40
|
+
kind = STRICT.module_or_class(value)
|
41
|
+
|
42
|
+
if OF.class?(kind)
|
43
|
+
kind <= expected_kind || expected_kind == ::Class
|
44
|
+
else
|
45
|
+
kind == expected_kind || kind.kind_of?(expected_kind)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private_constant :KIND
|
51
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kind
|
4
|
+
module OF
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def class?(value) # :nodoc:
|
8
|
+
value.kind_of?(::Class)
|
9
|
+
end
|
10
|
+
|
11
|
+
def module?(value) # :nodoc:
|
12
|
+
::Module == value || (value.kind_of?(::Module) && !class?(value))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private_constant :OF
|
17
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kind/__lib__/of'
|
4
|
+
|
5
|
+
module Kind
|
6
|
+
module STRICT
|
7
|
+
extend self
|
8
|
+
|
9
|
+
def error(kind_name, value, label = nil) # :nodoc:
|
10
|
+
raise Error.new(kind_name, value, label: label)
|
11
|
+
end
|
12
|
+
|
13
|
+
def object_is_a(kind, value, label = nil) # :nodoc:
|
14
|
+
return value if kind === value
|
15
|
+
|
16
|
+
error(kind.name, value, label)
|
17
|
+
end
|
18
|
+
|
19
|
+
def kind_of(kind, value, kind_name = nil) # :nodoc:
|
20
|
+
return value if kind === value
|
21
|
+
|
22
|
+
error(kind_name || kind.name, value)
|
23
|
+
end
|
24
|
+
|
25
|
+
def module_or_class(value) # :nodoc:
|
26
|
+
kind_of(::Module, value, 'Module/Class')
|
27
|
+
end
|
28
|
+
|
29
|
+
def class!(value) # :nodoc:
|
30
|
+
kind_of(::Class, value)
|
31
|
+
end
|
32
|
+
|
33
|
+
def module!(value) # :nodoc:
|
34
|
+
return value if OF.module?(value)
|
35
|
+
|
36
|
+
error('Module', value)
|
37
|
+
end
|
38
|
+
|
39
|
+
def not_nil(value, label) # :nodoc:
|
40
|
+
return value unless value.nil?
|
41
|
+
|
42
|
+
label_text = label ? "#{label}: " : ''
|
43
|
+
|
44
|
+
raise Error.new("#{label_text}expected to not be nil")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private_constant :STRICT
|
49
|
+
end
|
data/lib/kind/action.rb
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'kind/basic'
|
4
|
+
require 'kind/empty'
|
5
|
+
require 'kind/result'
|
6
|
+
require 'kind/immutable_attributes'
|
7
|
+
require 'kind/__lib__/action_steps'
|
8
|
+
|
9
|
+
module Kind
|
10
|
+
module Action
|
11
|
+
CALL_TMPL = [
|
12
|
+
'def self.call(arg)',
|
13
|
+
' new(Kind.of!(::Hash, arg)).call',
|
14
|
+
'end',
|
15
|
+
'',
|
16
|
+
'def call',
|
17
|
+
' result = call!',
|
18
|
+
'',
|
19
|
+
' return result if Kind::Result::Monad === result',
|
20
|
+
'',
|
21
|
+
' raise Kind::Error, "#{self.class.name}#call! must return a Success() or Failure()"',
|
22
|
+
'end'
|
23
|
+
].join("\n").freeze
|
24
|
+
|
25
|
+
private_constant :CALL_TMPL
|
26
|
+
|
27
|
+
module ClassMethods
|
28
|
+
include ImmutableAttributes::ClassMethods
|
29
|
+
|
30
|
+
def to_proc
|
31
|
+
@to_proc ||= ->(arg) { call(arg) }
|
32
|
+
end
|
33
|
+
|
34
|
+
ATTRIBUTE_METHODS = [
|
35
|
+
:attributes, :attribute,
|
36
|
+
:attribute?, :attribute!,
|
37
|
+
:with_attribute, :with_attributes,
|
38
|
+
:nil_attributes, :nil_attributes?
|
39
|
+
]
|
40
|
+
|
41
|
+
private_constant :ATTRIBUTE_METHODS
|
42
|
+
|
43
|
+
def kind_action!
|
44
|
+
return self if respond_to?(:call)
|
45
|
+
|
46
|
+
public_methods = self.public_instance_methods - ::Object.new.methods
|
47
|
+
|
48
|
+
remaining_methods = public_methods - (__attributes__.keys + ATTRIBUTE_METHODS)
|
49
|
+
|
50
|
+
unless remaining_methods.include?(:call!)
|
51
|
+
raise Kind::Error.new("expected #{self} to implement `#call!`")
|
52
|
+
end
|
53
|
+
|
54
|
+
if remaining_methods.size > 1
|
55
|
+
raise Kind::Error.new("#{self} can only have `#call!` as its public method")
|
56
|
+
end
|
57
|
+
|
58
|
+
call_parameters = public_instance_method(:call!).parameters
|
59
|
+
|
60
|
+
unless call_parameters.empty?
|
61
|
+
raise ArgumentError, "#{self.name}#call! must receive no arguments"
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.inherited(_)
|
65
|
+
raise RuntimeError, "#{self.name} is a Kind::Action and it can't be inherited"
|
66
|
+
end
|
67
|
+
|
68
|
+
self.send(:private_class_method, :new)
|
69
|
+
|
70
|
+
self.class_eval(CALL_TMPL)
|
71
|
+
|
72
|
+
self.send(:alias_method, :[], :call)
|
73
|
+
self.send(:alias_method, :===, :call)
|
74
|
+
self.send(:alias_method, :yield, :call)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
module StepAdapters
|
79
|
+
private
|
80
|
+
|
81
|
+
def Check!(mthod); __Check(mthod, Empty::HASH); end
|
82
|
+
def Step!(mthod); __Step(mthod, Empty::HASH); end
|
83
|
+
def Map!(mthod); __Map(mthod, Empty::HASH); end
|
84
|
+
def Tee!(_mthod); raise NotImplementedError; end
|
85
|
+
def Try!(mthod, opt = Empty::HASH); __Try(mthod, Empty::HASH, opt); end
|
86
|
+
|
87
|
+
def __resolve_step(method_name, value)
|
88
|
+
m = method(method_name)
|
89
|
+
m.arity > 0 ? m.call(value) : m.call
|
90
|
+
end
|
91
|
+
|
92
|
+
def __map_step_exception(value)
|
93
|
+
{ exception: value }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
private_constant :StepAdapters
|
98
|
+
|
99
|
+
def self.included(base)
|
100
|
+
Kind.of_class(base).extend(ClassMethods)
|
101
|
+
|
102
|
+
base.send(:include, ACTION_STEPS)
|
103
|
+
base.send(:include, StepAdapters)
|
104
|
+
base.send(:include, ImmutableAttributes::Reader)
|
105
|
+
end
|
106
|
+
|
107
|
+
include ImmutableAttributes::Initializer
|
108
|
+
|
109
|
+
def inspect
|
110
|
+
'#<%s attributes=%p nil_attributes=%p>' % [self.class.name, attributes, nil_attributes]
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
def Failure(arg1 = UNDEFINED, arg2 = UNDEFINED)
|
116
|
+
arg1 = Empty::HASH if UNDEFINED == arg1 && UNDEFINED == arg2
|
117
|
+
|
118
|
+
Result::Failure[arg1, arg2, value_must_be_a: ::Hash]
|
119
|
+
end
|
120
|
+
|
121
|
+
def Success(arg1 = UNDEFINED, arg2 = UNDEFINED)
|
122
|
+
arg1 = Empty::HASH if UNDEFINED == arg1 && UNDEFINED == arg2
|
123
|
+
|
124
|
+
Result::Success[arg1, arg2, value_must_be_a: ::Hash]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|