lib/kind.rb in kind-3.1.0 vs lib/kind.rb in kind-4.0.0

- old
+ new

@@ -1,316 +1,86 @@ # frozen_string_literal: true -require 'kind/version' - +require 'set' require 'ostruct' +require 'kind/version' +require 'kind/core' + +require 'kind/error' require 'kind/empty' +require 'kind/dig' +require 'kind/try' +require 'kind/presence' require 'kind/undefined' -require 'kind/checker' +require 'kind/type_checker' + +require 'kind/type_checkers' require 'kind/maybe' -require 'kind/error' -require 'kind/of' -require 'kind/is' -require 'kind/types' +require 'kind/deprecations/checker' +require 'kind/deprecations/of' +require 'kind/deprecations/is' +require 'kind/deprecations/types' +require 'kind/deprecations/built_in_type_checkers' module Kind - WRONG_NUMBER_OF_ARGUMENTS = 'wrong number of arguments (given 1, expected 2)'.freeze + def self.is?(kind, arg) + KIND.is?(kind, arg) + end - private_constant :WRONG_NUMBER_OF_ARGUMENTS + def self.of?(kind, *args) + KIND.of?(kind, args) + end - def self.is(expected = Undefined, object = Undefined) - return Is if Undefined == expected && Undefined == object + def self.of_class?(value) + KIND.of_class?(value) + end - return Kind::Is.(expected, object) if Undefined != object - - raise ArgumentError, WRONG_NUMBER_OF_ARGUMENTS + def self.of_module?(value) + KIND.of_module?(value) end - def self.of(kind = Undefined, object = Undefined) - return Of if Undefined == kind && Undefined == object + def self.respond_to(value, *method_names) + method_names.each { |method_name| KIND.respond_to!(method_name, value) } - return Kind::Of.(kind, object) if Undefined != object - - Kind::Checker::Factory.create(kind) + value end - def self.of?(kind, *args) - Kind.of(kind).instance?(*args) + def self.of_module_or_class(value) + KIND.of_module_or_class!(value) end - # --------------------- # - # Special type checkers # - # --------------------- # + def self.is(expected = UNDEFINED, object = UNDEFINED) + if UNDEFINED == expected && UNDEFINED == object + DEPRECATION.warn('`Kind.is` without args is deprecated. This behavior will be removed in %{version}') - module Is - def self.Class(value) - value.kind_of?(::Class) + return Is end - def self.Module(value) - ::Module == value || (value.is_a?(::Module) && !self.Class(value)) - end + return is?(expected, object) if UNDEFINED != object - def self.Boolean(value) - Kind.of.Class(value) <= TrueClass || value <= FalseClass - end - - def self.Callable(value) - value.respond_to?(:call) - end + raise ArgumentError, 'wrong number of arguments (given 1, expected 2)' end - module Of - # -- Class + def self.of(kind = UNDEFINED, object = UNDEFINED) + if UNDEFINED == kind && UNDEFINED == object + DEPRECATION.warn('`Kind.of` without args is deprecated. This behavior will be removed in %{version}') - def self.Class(object = Undefined) - return Class if Undefined == object + Of + elsif UNDEFINED != object + KIND.of!(kind, object) + else + DEPRECATION.warn_method_replacement('Kind.of(<Kind>)', 'Kind::Of(<Kind>)') - self.call(::Class, object) + Checker::Factory.create(kind) end + end - const_set(:Class, ::Module.new do - extend Checker::Protocol + def self.value(kind, value, default:) + KIND.value(kind, value, of(kind, default)) + end - def self.__kind; ::Class; end - - def self.class?(value); Kind::Is.Class(value); end - - def self.__is_instance__(value); class?(value); end - end) - - def self.Class?(*args) - Kind::Of::Class.instance?(*args) - end - - # -- Module - - def self.Module(object = Undefined) - return Module if Undefined == object - - self.call(::Module, object) - end - - const_set(:Module, ::Module.new do - extend Checker::Protocol - - def self.__kind_undefined(value) - __kind_error(Kind::Undefined) if Kind::Undefined == value - - yield - end - - def self.__kind_error(value) - raise Kind::Error.new('Module'.freeze, value) - end - - def self.__kind_of(value) - return value if Kind::Is.Module(value) - - __kind_error(value) - end - - def self.__kind; ::Module; end - - def self.class?(value); Kind::Is.Module(value); end - - def self.instance(value, options = Empty::HASH) - default = options[:or] - - if ::Kind::Maybe::Value.none?(default) - __kind_undefined(value) { __kind_of(value) } - else - return value if Kind::Undefined != value && instance?(value) - - __kind_undefined(default) { __kind_of(default) } - end - end - - def self.__is_instance__(value); class?(value); end - end) - - def self.Module?(*args) - Kind::Of::Module.instance?(*args) - end - - # -- Boolean - - def self.Boolean(object = Undefined, options = Empty::HASH) - default = options[:or] - - return Kind::Of::Boolean if Undefined == object && default.nil? - - bool = object.nil? ? default : object - - return bool if bool.is_a?(::TrueClass) || bool.is_a?(::FalseClass) - - raise Kind::Error.new('Boolean'.freeze, bool) - end - - const_set(:Boolean, ::Module.new do - extend Checker::Protocol - - def self.__kind; [TrueClass, FalseClass].freeze; end - - def self.class?(value); Kind.is.Boolean(value); end - - def self.instance(value, options= Empty::HASH) - default = options[:or] - - if ::Kind::Maybe::Value.none?(default) - __kind_undefined(value) { Kind::Of::Boolean(value) } - else - return value if Kind::Undefined != value && instance?(value) - - __kind_undefined(default) { Kind::Of::Boolean(default) } - end - end - - def self.__kind_undefined(value) - if Kind::Undefined == value - raise Kind::Error.new('Boolean'.freeze, Kind::Undefined) - else - yield - end - end - - def self.__is_instance__(value); - value.is_a?(TrueClass) || value.is_a?(FalseClass) - end - - def self.or_undefined(value) - result = or_nil(value) - result.nil? ? Kind::Undefined : result - end - end) - - def self.Boolean?(*args) - Kind::Of::Boolean.instance?(*args) - end - - # -- Lambda - - def self.Lambda(object = Undefined, options = Empty::HASH) - default = options[:or] - - return Kind::Of::Lambda if Undefined == object && default.nil? - - func = object || default - - return func if func.is_a?(::Proc) && func.lambda? - - raise Kind::Error.new('Lambda'.freeze, func) - end - - const_set(:Lambda, ::Module.new do - extend Checker::Protocol - - def self.__kind; ::Proc; end - - def self.instance(value, options = Empty::HASH) - default = options[:or] - - if ::Kind::Maybe::Value.none?(default) - __kind_undefined(value) { Kind::Of::Lambda(value) } - else - return value if Kind::Undefined != value && instance?(value) - - __kind_undefined(default) { Kind::Of::Lambda(default) } - end - end - - def self.__kind_undefined(value) - if Kind::Undefined == value - raise Kind::Error.new('Lambda'.freeze, Kind::Undefined) - else - yield - end - end - - def self.__is_instance__(value) - value.is_a?(__kind) && value.lambda? - end - end) - - def self.Lambda?(*args) - Kind::Of::Lambda.instance?(*args) - end - - # -- Callable - - def self.Callable(object = Undefined, options = Empty::HASH) - default = options[:or] - - return Kind::Of::Callable if Undefined == object && default.nil? - - callable = object || default - - return callable if callable.respond_to?(:call) - - raise Kind::Error.new('Callable'.freeze, callable) - end - - const_set(:Callable, ::Module.new do - extend Checker::Protocol - - def self.__kind; Object; end - - def self.class?(value) - Kind::Is::Callable(value) - end - - def self.instance(value, options = Empty::HASH) - default = options[:or] - - if ::Kind::Maybe::Value.none?(default) - __kind_undefined(value) { Kind::Of::Callable(value) } - else - return value if Kind::Undefined != value && instance?(value) - - __kind_undefined(default) { Kind::Of::Callable(default) } - end - end - - def self.__kind_undefined(value) - if Kind::Undefined == value - raise Kind::Error.new('Callable'.freeze, Kind::Undefined) - else - yield - end - end - - def self.__is_instance__(value); - value.respond_to?(:call) - end - end) - - def self.Callable?(*args) - Kind::Of::Callable.instance?(*args) - end - - # ---------------------- # - # Built-in type checkers # - # ---------------------- # - - # -- Classes - [ - String, Symbol, Numeric, Integer, Float, Regexp, Time, - Array, Range, Hash, Struct, Enumerator, Set, OpenStruct, - Method, Proc, - IO, File - ].each { |klass| Types.add(klass) } - - Types.add(Queue, name: 'Queue'.freeze) - - # -- Modules - [ - Enumerable, Comparable - ].each { |klass| Types.add(klass) } - - # -- Kind::Of::Maybe - - Types.add(Kind::Maybe::Result, name: 'Maybe'.freeze) - Types.add(Kind::Maybe::Result, name: 'Optional'.freeze) + def self.Of(kind, opt = Empty::HASH) + TypeChecker::Object.new(kind, opt) end end