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
 
| 
         @@ -2,13 +2,15 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module Kind
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Set
         
     | 
| 
       5 
     | 
    
         
            -
                extend self,  
     | 
| 
      
 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,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
         
     | 
    
        data/lib/kind/presence.rb
    CHANGED
    
    | 
         @@ -1,13 +1,15 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            require 'kind/basic'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
       3 
5 
     | 
    
         
             
            module Kind
         
     | 
| 
       4 
6 
     | 
    
         
             
              module Presence
         
     | 
| 
       5 
7 
     | 
    
         
             
                extend self
         
     | 
| 
       6 
8 
     | 
    
         | 
| 
       7 
9 
     | 
    
         
             
                def call(object)
         
     | 
| 
       8 
     | 
    
         
            -
                  return  
     | 
| 
      
 10 
     | 
    
         
            +
                  return if KIND.nil_or_undefined?(object)
         
     | 
| 
       9 
11 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                  return object  
     | 
| 
      
 12 
     | 
    
         
            +
                  return object.blank? ? nil : object if object.respond_to?(:blank?)
         
     | 
| 
       11 
13 
     | 
    
         | 
| 
       12 
14 
     | 
    
         
             
                  return blank_str?(object) ? nil : object if String === object
         
     | 
| 
       13 
15 
     | 
    
         | 
    
        data/lib/kind/result.rb
    ADDED
    
    | 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'kind/basic'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module Kind
         
     | 
| 
      
 6 
     | 
    
         
            +
              module Result
         
     | 
| 
      
 7 
     | 
    
         
            +
                require 'kind/result/abstract'
         
     | 
| 
      
 8 
     | 
    
         
            +
                require 'kind/result/monad'
         
     | 
| 
      
 9 
     | 
    
         
            +
                require 'kind/result/failure'
         
     | 
| 
      
 10 
     | 
    
         
            +
                require 'kind/result/success'
         
     | 
| 
      
 11 
     | 
    
         
            +
                require 'kind/result/methods'
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                extend self
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                def new(value)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  Success[value]
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                alias_method :[], :new
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def self.from
         
     | 
| 
      
 22 
     | 
    
         
            +
                  result = yield
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  Result::Monad === result ? result : Result::Success[result]
         
     | 
| 
      
 25 
     | 
    
         
            +
                rescue StandardError => e
         
     | 
| 
      
 26 
     | 
    
         
            +
                  Result::Failure[:exception, e]
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              extend Result::Methods
         
     | 
| 
      
 31 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,53 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Kind
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Result::Abstract
         
     | 
| 
      
 5 
     | 
    
         
            +
                def failure?
         
     | 
| 
      
 6 
     | 
    
         
            +
                  false
         
     | 
| 
      
 7 
     | 
    
         
            +
                end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                def failed?
         
     | 
| 
      
 10 
     | 
    
         
            +
                  failure?
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                def success?
         
     | 
| 
      
 14 
     | 
    
         
            +
                  false
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                def succeeded?
         
     | 
| 
      
 18 
     | 
    
         
            +
                  success?
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def on(&block)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  raise NotImplementedError
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                def on_success(types = Undefined, matcher = Undefined)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  raise NotImplementedError
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                def on_failure(types = Undefined, matcher = Undefined)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  raise NotImplementedError
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                def result?(types, matcher)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  undef_t = Undefined == (t = types)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  undef_m = Undefined == (m = matcher)
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  return true if undef_t && undef_m
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  if !undef_t && undef_m && !(Array === types || Symbol === types)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    m, t = types, matcher
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                    undef_m, undef_t = false, true
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  is_type = undef_t || (::Array === t ? t.empty? || t.include?(type) : t == type)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  is_type && (undef_m || m === value)
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                def to_ary
         
     | 
| 
      
 50 
     | 
    
         
            +
                  [type, value]
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Kind
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Result::Failure < Result::Monad
         
     | 
| 
      
 5 
     | 
    
         
            +
                DEFAULT_TYPE = :error
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def failure?
         
     | 
| 
      
 8 
     | 
    
         
            +
                  true
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def value_or(default = UNDEFINED, &block)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  Error.invalid_default_arg! if UNDEFINED == default && !block
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  UNDEFINED != default ? default : block.call
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                def map(_ = UNDEFINED, &_fn)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  self
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                alias_method :|, :map
         
     | 
| 
      
 22 
     | 
    
         
            +
                alias_method :>>, :map
         
     | 
| 
      
 23 
     | 
    
         
            +
                alias_method :map!, :map
         
     | 
| 
      
 24 
     | 
    
         
            +
                alias_method :then, :map
         
     | 
| 
      
 25 
     | 
    
         
            +
                alias_method :then!, :map
         
     | 
| 
      
 26 
     | 
    
         
            +
                alias_method :and_then, :map
         
     | 
| 
      
 27 
     | 
    
         
            +
                alias_method :and_then!, :map
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                def inspect
         
     | 
| 
      
 30 
     | 
    
         
            +
                  '#<%s type=%p value=%p>' % ['Kind::Failure', type, value]
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Kind
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Result::Methods
         
     | 
| 
      
 5 
     | 
    
         
            +
                def Failure(arg1 = UNDEFINED, arg2 = UNDEFINED)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  Result::Failure[arg1, arg2]
         
     | 
| 
      
 7 
     | 
    
         
            +
                end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                def Success(arg1 = UNDEFINED, arg2 = UNDEFINED)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  Result::Success[arg1, arg2]
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                def self.included(base)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  base.send(:private, :Success, :Failure)
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,74 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Kind
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Result::Monad
         
     | 
| 
      
 5 
     | 
    
         
            +
                include Result::Abstract
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                require 'kind/empty'
         
     | 
| 
      
 8 
     | 
    
         
            +
                require 'kind/result/monad/wrapper'
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                attr_reader :type, :value
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def self.[](arg1 = UNDEFINED, arg2 = UNDEFINED, opt = Empty::HASH) # :nodoc:
         
     | 
| 
      
 13 
     | 
    
         
            +
                  value_must_be_a = opt[:value_must_be_a]
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  type = UNDEFINED == arg2 ? self::DEFAULT_TYPE : STRICT.kind_of(::Symbol, arg1)
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  Error.wrong_number_of_args!(given: 0, expected: '1 or 2') if UNDEFINED == arg1
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  value = UNDEFINED == arg2 ? arg1 : arg2
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  new(type, (value_must_be_a ? STRICT.kind_of(value_must_be_a, value) : value))
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                private_class_method :new
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                def initialize(type, value)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  @type = type
         
     | 
| 
      
 28 
     | 
    
         
            +
                  @value = value
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                def value_or(_method_name = UNDEFINED, &block)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  raise NotImplementedError
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                def map(_ = UNDEFINED, &_fn)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  raise NotImplementedError
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                alias_method :|, :map
         
     | 
| 
      
 40 
     | 
    
         
            +
                alias_method :>>, :map
         
     | 
| 
      
 41 
     | 
    
         
            +
                alias_method :map!, :map
         
     | 
| 
      
 42 
     | 
    
         
            +
                alias_method :then, :map
         
     | 
| 
      
 43 
     | 
    
         
            +
                alias_method :then!, :map
         
     | 
| 
      
 44 
     | 
    
         
            +
                alias_method :and_then, :map
         
     | 
| 
      
 45 
     | 
    
         
            +
                alias_method :and_then!, :map
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                def on
         
     | 
| 
      
 48 
     | 
    
         
            +
                  monad = Wrapper.new(self)
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  yield(monad)
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                  monad.output
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                def on_success(types = Undefined, matcher = Undefined)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  yield(value) if success? && result?(types, matcher)
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                  self
         
     | 
| 
      
 59 
     | 
    
         
            +
                end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                def on_failure(types = Undefined, matcher = Undefined)
         
     | 
| 
      
 62 
     | 
    
         
            +
                  yield(value) if failure? && result?(types, matcher)
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  self
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                def ===(m)
         
     | 
| 
      
 68 
     | 
    
         
            +
                  return false unless Result::Abstract === m
         
     | 
| 
      
 69 
     | 
    
         
            +
                  return false unless (self.success? && m.success?) || (self.failure? && m.failure?)
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                  self.type == m.type && self.value === m.value
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
            end
         
     |