kind 5.0.0 → 5.4.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.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.tool-versions +1 -1
  3. data/.travis.sh +39 -7
  4. data/.travis.yml +1 -0
  5. data/CHANGELOG.md +506 -28
  6. data/Gemfile +13 -6
  7. data/README.md +50 -42
  8. data/kind.gemspec +3 -3
  9. data/lib/kind.rb +2 -60
  10. data/lib/kind/__lib__/action_steps.rb +57 -0
  11. data/lib/kind/__lib__/attributes.rb +66 -0
  12. data/lib/kind/__lib__/kind.rb +51 -0
  13. data/lib/kind/__lib__/of.rb +17 -0
  14. data/lib/kind/__lib__/strict.rb +49 -0
  15. data/lib/kind/__lib__/undefined.rb +14 -0
  16. data/lib/kind/action.rb +127 -0
  17. data/lib/kind/active_model/validation.rb +3 -4
  18. data/lib/kind/basic.rb +79 -0
  19. data/lib/kind/basic/error.rb +29 -0
  20. data/lib/kind/{undefined.rb → basic/undefined.rb} +6 -1
  21. data/lib/kind/dig.rb +21 -5
  22. data/lib/kind/either.rb +30 -0
  23. data/lib/kind/either/left.rb +29 -0
  24. data/lib/kind/either/methods.rb +17 -0
  25. data/lib/kind/either/monad.rb +65 -0
  26. data/lib/kind/either/monad/wrapper.rb +19 -0
  27. data/lib/kind/either/right.rb +38 -0
  28. data/lib/kind/empty.rb +2 -0
  29. data/lib/kind/enum.rb +63 -0
  30. data/lib/kind/enum/item.rb +40 -0
  31. data/lib/kind/enum/methods.rb +72 -0
  32. data/lib/kind/function.rb +45 -0
  33. data/lib/kind/functional.rb +89 -0
  34. data/lib/kind/functional/action.rb +87 -0
  35. data/lib/kind/functional/steps.rb +22 -0
  36. data/lib/kind/immutable_attributes.rb +34 -0
  37. data/lib/kind/immutable_attributes/initializer.rb +70 -0
  38. data/lib/kind/immutable_attributes/reader.rb +38 -0
  39. data/lib/kind/maybe.rb +37 -12
  40. data/lib/kind/maybe/methods.rb +21 -0
  41. data/lib/kind/maybe/monad.rb +82 -0
  42. data/lib/kind/maybe/monad/wrapper.rb +19 -0
  43. data/lib/kind/maybe/none.rb +12 -19
  44. data/lib/kind/maybe/some.rb +68 -26
  45. data/lib/kind/maybe/typed.rb +11 -5
  46. data/lib/kind/maybe/{wrappable.rb → wrapper.rb} +8 -4
  47. data/lib/kind/monad.rb +22 -0
  48. data/lib/kind/monads.rb +5 -0
  49. data/lib/kind/objects.rb +17 -0
  50. data/lib/kind/objects/basic_object.rb +43 -0
  51. data/lib/kind/objects/modules.rb +32 -0
  52. data/lib/kind/{type_checkers → objects/modules}/core/array.rb +3 -1
  53. data/lib/kind/{type_checkers → objects/modules}/core/class.rb +1 -1
  54. data/lib/kind/{type_checkers → objects/modules}/core/comparable.rb +1 -1
  55. data/lib/kind/{type_checkers → objects/modules}/core/enumerable.rb +1 -1
  56. data/lib/kind/{type_checkers → objects/modules}/core/enumerator.rb +1 -1
  57. data/lib/kind/{type_checkers → objects/modules}/core/file.rb +1 -1
  58. data/lib/kind/{type_checkers → objects/modules}/core/float.rb +1 -1
  59. data/lib/kind/{type_checkers → objects/modules}/core/hash.rb +3 -1
  60. data/lib/kind/{type_checkers → objects/modules}/core/integer.rb +1 -1
  61. data/lib/kind/{type_checkers → objects/modules}/core/io.rb +1 -1
  62. data/lib/kind/{type_checkers → objects/modules}/core/method.rb +1 -1
  63. data/lib/kind/{type_checkers → objects/modules}/core/module.rb +1 -1
  64. data/lib/kind/{type_checkers → objects/modules}/core/numeric.rb +1 -1
  65. data/lib/kind/{type_checkers → objects/modules}/core/proc.rb +1 -1
  66. data/lib/kind/{type_checkers → objects/modules}/core/queue.rb +1 -1
  67. data/lib/kind/{type_checkers → objects/modules}/core/range.rb +1 -1
  68. data/lib/kind/{type_checkers → objects/modules}/core/regexp.rb +1 -1
  69. data/lib/kind/{type_checkers → objects/modules}/core/string.rb +3 -1
  70. data/lib/kind/{type_checkers → objects/modules}/core/struct.rb +1 -1
  71. data/lib/kind/{type_checkers → objects/modules}/core/symbol.rb +1 -1
  72. data/lib/kind/{type_checkers → objects/modules}/core/time.rb +1 -1
  73. data/lib/kind/{type_checkers → objects/modules}/custom/boolean.rb +2 -2
  74. data/lib/kind/{type_checkers → objects/modules}/custom/callable.rb +1 -1
  75. data/lib/kind/{type_checkers → objects/modules}/custom/lambda.rb +1 -1
  76. data/lib/kind/{type_checkers → objects/modules}/stdlib/open_struct.rb +3 -1
  77. data/lib/kind/{type_checkers → objects/modules}/stdlib/set.rb +3 -1
  78. data/lib/kind/objects/nil.rb +17 -0
  79. data/lib/kind/objects/not_nil.rb +9 -0
  80. data/lib/kind/objects/object.rb +56 -0
  81. data/lib/kind/objects/respond_to.rb +30 -0
  82. data/lib/kind/objects/union_type.rb +44 -0
  83. data/lib/kind/presence.rb +4 -2
  84. data/lib/kind/result.rb +31 -0
  85. data/lib/kind/result/abstract.rb +53 -0
  86. data/lib/kind/result/failure.rb +33 -0
  87. data/lib/kind/result/methods.rb +17 -0
  88. data/lib/kind/result/monad.rb +74 -0
  89. data/lib/kind/result/monad/wrapper.rb +19 -0
  90. data/lib/kind/result/success.rb +53 -0
  91. data/lib/kind/strict/disabled.rb +34 -0
  92. data/lib/kind/try.rb +22 -10
  93. data/lib/kind/validator.rb +111 -0
  94. data/lib/kind/version.rb +1 -1
  95. metadata +83 -42
  96. data/lib/kind/active_model/kind_validator.rb +0 -103
  97. data/lib/kind/core.rb +0 -8
  98. data/lib/kind/core/kind.rb +0 -61
  99. data/lib/kind/core/undefined.rb +0 -7
  100. data/lib/kind/error.rb +0 -15
  101. data/lib/kind/maybe/result.rb +0 -51
  102. data/lib/kind/type_checker.rb +0 -87
  103. data/lib/kind/type_checkers.rb +0 -30
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Class
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Class; end
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Comparable
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Comparable; end
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Enumerable
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Enumerable; end
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Enumerator
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Enumerator; end
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module File
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::File; end
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Float
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Float; end
8
8
  end
@@ -2,13 +2,15 @@
2
2
 
3
3
  module Kind
4
4
  module Hash
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Hash; end
8
8
 
9
9
  def value_or_empty(arg)
10
10
  KIND.value(self, arg, Empty::HASH)
11
11
  end
12
+
13
+ alias empty_or value_or_empty
12
14
  end
13
15
 
14
16
  def self.Hash?(*values)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Integer
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Integer; end
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module IO
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::IO; end
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Method
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Method; end
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Module
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Module; end
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Numeric
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Numeric; end
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Proc
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Proc; end
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Queue
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Queue; end
8
8
  def name; 'Queue'; end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Range
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Range; end
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Regexp
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Regexp; end
8
8
  end
@@ -2,13 +2,15 @@
2
2
 
3
3
  module Kind
4
4
  module String
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::String; end
8
8
 
9
9
  def value_or_empty(arg)
10
10
  KIND.value(self, arg, Empty::STRING)
11
11
  end
12
+
13
+ alias empty_or value_or_empty
12
14
  end
13
15
 
14
16
  def self.String?(*values)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Struct
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Struct; end
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Symbol
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Symbol; end
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Time
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Time; end
8
8
  end
@@ -2,9 +2,9 @@
2
2
 
3
3
  module Kind
4
4
  module Boolean
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
- def kind; [TrueClass, FalseClass].freeze; end
7
+ def kind; [TrueClass, FalseClass]; end
8
8
 
9
9
  def name; 'Boolean'; end
10
10
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Callable
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; raise NotImplementedError; end
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Lambda
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Proc; end
8
8
 
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'ostruct'
4
+
3
5
  module Kind
4
6
  module OpenStruct
5
- extend self, TypeChecker
7
+ extend self, ::Kind::Object
6
8
 
7
9
  def kind; ::OpenStruct; end
8
10
  end
@@ -2,13 +2,15 @@
2
2
 
3
3
  module Kind
4
4
  module Set
5
- extend self, TypeChecker
5
+ extend self, ::Kind::Object
6
6
 
7
7
  def kind; ::Set; end
8
8
 
9
9
  def value_or_empty(arg)
10
10
  KIND.value(self, arg, Empty::SET)
11
11
  end
12
+
13
+ alias empty_or value_or_empty
12
14
  end
13
15
 
14
16
  def self.Set?(*values)
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module Nil
5
+ def self.|(another_kind)
6
+ UnionType[self] | another_kind
7
+ end
8
+
9
+ def self.name
10
+ 'nil'
11
+ end
12
+
13
+ def self.===(value)
14
+ value.nil?
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module NotNil
5
+ def self.[](value, label: nil)
6
+ STRICT.not_nil(value, label)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'kind/maybe'
4
+
5
+ module Kind
6
+ module Object
7
+ include Kind::BasicObject
8
+ include Maybe::Buildable
9
+ include UnionType::Buildable
10
+
11
+ def name
12
+ kind.name
13
+ end
14
+
15
+ def ===(value)
16
+ kind === value
17
+ end
18
+
19
+ def inspect
20
+ "Kind::Object<#{name}>"
21
+ end
22
+ end
23
+
24
+ class Object::Instance # :nodoc: all
25
+ include ::Kind::Object
26
+
27
+ ResolveKindName = ->(kind, opt) do
28
+ name = Try.call!(opt, :[], :name)
29
+ name || Try.call!(kind, :name)
30
+ end
31
+
32
+ attr_reader :kind, :name
33
+
34
+ def initialize(kind, opt)
35
+ name = ResolveKindName.(kind, opt)
36
+
37
+ @name = STRICT.kind_of(::String, name)
38
+ @kind = KIND.respond_to!(:===, kind)
39
+ end
40
+
41
+ private_constant :ResolveKindName
42
+ end
43
+
44
+ # Kind[]
45
+ def self.[](kind, opt = Empty::HASH)
46
+ Object::Instance.new(kind, opt)
47
+ end
48
+
49
+ # Kind::Of()
50
+ def self.Of(*args)
51
+ warn '[DEPRECATION] Kind::Of() is deprecated; use Kind[] instead. ' \
52
+ 'It will be removed on next major release.'
53
+
54
+ self[*args]
55
+ end
56
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ class RespondTo
5
+ include Kind::BasicObject
6
+
7
+ def self.[](*args)
8
+ args.each { |arg| STRICT.kind_of(::Symbol, arg) }
9
+
10
+ new(args)
11
+ end
12
+
13
+ private_class_method :new
14
+
15
+ attr_reader :inspect
16
+
17
+ def initialize(method_names)
18
+ @method_names = method_names
19
+ @inspect = "Kind::RespondTo#{@method_names}"
20
+ end
21
+
22
+ def ===(value)
23
+ KIND.interface?(@method_names, value)
24
+ end
25
+
26
+ alias_method :call, :===
27
+
28
+ alias_method :name, :inspect
29
+ end
30
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ class UnionType
5
+ include Kind::BasicObject
6
+
7
+ Interface = Kind::RespondTo[:name, :===]
8
+
9
+ singleton_class.send(:alias_method, :[], :new)
10
+
11
+ attr_reader :inspect
12
+
13
+ def initialize(kind)
14
+ @kinds = Array(kind)
15
+ @inspect = "(#{@kinds.map(&:name).join(' | ')})"
16
+ end
17
+
18
+ def |(kind)
19
+ self.class.new(@kinds + [Interface[kind]])
20
+ end
21
+
22
+ def ===(value)
23
+ @kinds.any? { |kind| kind === value }
24
+ end
25
+
26
+ alias_method :name, :inspect
27
+
28
+ module Buildable
29
+ def |(another_kind)
30
+ __union_type | another_kind
31
+ end
32
+
33
+ private
34
+
35
+ def __union_type
36
+ @__union_type ||= UnionType[self]
37
+ end
38
+ end
39
+
40
+ private_constant :Interface
41
+ end
42
+
43
+ RespondTo.send(:include, UnionType::Buildable)
44
+ end