kind 3.0.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.tool-versions +1 -0
  3. data/.travis.sh +37 -12
  4. data/.travis.yml +6 -5
  5. data/CHANGELOG.md +1295 -0
  6. data/Gemfile +10 -2
  7. data/README.md +985 -490
  8. data/lib/kind.rb +35 -287
  9. data/lib/kind/active_model/kind_validator.rb +20 -13
  10. data/lib/kind/core.rb +8 -0
  11. data/lib/kind/core/kind.rb +61 -0
  12. data/lib/kind/core/undefined.rb +7 -0
  13. data/lib/kind/dig.rb +40 -0
  14. data/lib/kind/empty.rb +4 -12
  15. data/lib/kind/empty/constant.rb +7 -0
  16. data/lib/kind/error.rb +2 -6
  17. data/lib/kind/maybe.rb +14 -153
  18. data/lib/kind/maybe/none.rb +57 -0
  19. data/lib/kind/maybe/result.rb +51 -0
  20. data/lib/kind/maybe/some.rb +90 -0
  21. data/lib/kind/maybe/typed.rb +29 -0
  22. data/lib/kind/maybe/wrappable.rb +33 -0
  23. data/lib/kind/presence.rb +33 -0
  24. data/lib/kind/try.rb +34 -0
  25. data/lib/kind/type_checker.rb +87 -0
  26. data/lib/kind/type_checkers.rb +30 -0
  27. data/lib/kind/type_checkers/core/array.rb +17 -0
  28. data/lib/kind/type_checkers/core/class.rb +13 -0
  29. data/lib/kind/type_checkers/core/comparable.rb +13 -0
  30. data/lib/kind/type_checkers/core/enumerable.rb +13 -0
  31. data/lib/kind/type_checkers/core/enumerator.rb +13 -0
  32. data/lib/kind/type_checkers/core/file.rb +13 -0
  33. data/lib/kind/type_checkers/core/float.rb +13 -0
  34. data/lib/kind/type_checkers/core/hash.rb +17 -0
  35. data/lib/kind/type_checkers/core/integer.rb +13 -0
  36. data/lib/kind/type_checkers/core/io.rb +13 -0
  37. data/lib/kind/type_checkers/core/method.rb +13 -0
  38. data/lib/kind/type_checkers/core/module.rb +17 -0
  39. data/lib/kind/type_checkers/core/numeric.rb +13 -0
  40. data/lib/kind/type_checkers/core/proc.rb +13 -0
  41. data/lib/kind/type_checkers/core/queue.rb +14 -0
  42. data/lib/kind/type_checkers/core/range.rb +13 -0
  43. data/lib/kind/type_checkers/core/regexp.rb +13 -0
  44. data/lib/kind/type_checkers/core/string.rb +17 -0
  45. data/lib/kind/type_checkers/core/struct.rb +13 -0
  46. data/lib/kind/type_checkers/core/symbol.rb +13 -0
  47. data/lib/kind/type_checkers/core/time.rb +13 -0
  48. data/lib/kind/type_checkers/custom/boolean.rb +19 -0
  49. data/lib/kind/type_checkers/custom/callable.rb +19 -0
  50. data/lib/kind/type_checkers/custom/lambda.rb +19 -0
  51. data/lib/kind/type_checkers/stdlib/open_struct.rb +13 -0
  52. data/lib/kind/type_checkers/stdlib/set.rb +17 -0
  53. data/lib/kind/undefined.rb +4 -2
  54. data/lib/kind/validator.rb +1 -1
  55. data/lib/kind/version.rb +1 -1
  56. data/test.sh +4 -4
  57. metadata +45 -9
  58. data/lib/kind/checker.rb +0 -15
  59. data/lib/kind/checker/factory.rb +0 -35
  60. data/lib/kind/checker/protocol.rb +0 -73
  61. data/lib/kind/is.rb +0 -19
  62. data/lib/kind/of.rb +0 -11
  63. data/lib/kind/types.rb +0 -115
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module Numeric
5
+ extend self, TypeChecker
6
+
7
+ def kind; ::Numeric; end
8
+ end
9
+
10
+ def self.Numeric?(*values)
11
+ KIND.of?(::Numeric, values)
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module Proc
5
+ extend self, TypeChecker
6
+
7
+ def kind; ::Proc; end
8
+ end
9
+
10
+ def self.Proc?(*values)
11
+ KIND.of?(::Proc, values)
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module Queue
5
+ extend self, TypeChecker
6
+
7
+ def kind; ::Queue; end
8
+ def name; 'Queue'; end
9
+ end
10
+
11
+ def self.Queue?(*values)
12
+ KIND.of?(::Queue, values)
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module Range
5
+ extend self, TypeChecker
6
+
7
+ def kind; ::Range; end
8
+ end
9
+
10
+ def self.Range?(*values)
11
+ KIND.of?(::Range, values)
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module Regexp
5
+ extend self, TypeChecker
6
+
7
+ def kind; ::Regexp; end
8
+ end
9
+
10
+ def self.Regexp?(*values)
11
+ KIND.of?(::Regexp, values)
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module String
5
+ extend self, TypeChecker
6
+
7
+ def kind; ::String; end
8
+
9
+ def value_or_empty(arg)
10
+ KIND.value(self, arg, Empty::STRING)
11
+ end
12
+ end
13
+
14
+ def self.String?(*values)
15
+ KIND.of?(::String, values)
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module Struct
5
+ extend self, TypeChecker
6
+
7
+ def kind; ::Struct; end
8
+ end
9
+
10
+ def self.Struct?(*values)
11
+ KIND.of?(::Struct, values)
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module Symbol
5
+ extend self, TypeChecker
6
+
7
+ def kind; ::Symbol; end
8
+ end
9
+
10
+ def self.Symbol?(*values)
11
+ KIND.of?(::Symbol, values)
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module Time
5
+ extend self, TypeChecker
6
+
7
+ def kind; ::Time; end
8
+ end
9
+
10
+ def self.Time?(*values)
11
+ KIND.of?(::Time, values)
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module Boolean
5
+ extend self, TypeChecker
6
+
7
+ def kind; [TrueClass, FalseClass].freeze; end
8
+
9
+ def name; 'Boolean'; end
10
+
11
+ def ===(value)
12
+ ::TrueClass === value || ::FalseClass === value
13
+ end
14
+ end
15
+
16
+ def self.Boolean?(*values)
17
+ KIND.of?(Boolean, values)
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module Callable
5
+ extend self, TypeChecker
6
+
7
+ def kind; raise NotImplementedError; end
8
+
9
+ def name; 'Callable'; end
10
+
11
+ def ===(value)
12
+ value.respond_to?(:call)
13
+ end
14
+ end
15
+
16
+ def self.Callable?(*values)
17
+ KIND.of?(Callable, values)
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module Lambda
5
+ extend self, TypeChecker
6
+
7
+ def kind; ::Proc; end
8
+
9
+ def name; 'Lambda'; end
10
+
11
+ def ===(value)
12
+ value.kind_of?(::Proc) && value.lambda?
13
+ end
14
+ end
15
+
16
+ def self.Lambda?(*values)
17
+ KIND.of?(Lambda, values)
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module OpenStruct
5
+ extend self, TypeChecker
6
+
7
+ def kind; ::OpenStruct; end
8
+ end
9
+
10
+ def self.OpenStruct?(*values)
11
+ KIND.of?(::OpenStruct, values)
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module Set
5
+ extend self, TypeChecker
6
+
7
+ def kind; ::Set; end
8
+
9
+ def value_or_empty(arg)
10
+ KIND.value(self, arg, Empty::SET)
11
+ end
12
+ end
13
+
14
+ def self.Set?(*values)
15
+ KIND.of?(::Set, values)
16
+ end
17
+ end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
-
3
2
  module Kind
4
3
  Undefined = Object.new.tap do |undefined|
5
4
  def undefined.inspect
@@ -19,9 +18,12 @@ module Kind
19
18
  end
20
19
 
21
20
  def undefined.default(value, default)
22
- return self if self != value
21
+ return value if self != value
23
22
 
24
23
  default.respond_to?(:call) ? default.call : default
25
24
  end
25
+
26
+ undefined.inspect
27
+ undefined.freeze
26
28
  end
27
29
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Kind
4
4
  module Validator
5
- DEFAULT_STRATEGIES = Set.new(%w[instance_of kind_of]).freeze
5
+ DEFAULT_STRATEGIES = ::Set.new(%w[instance_of kind_of]).freeze
6
6
 
7
7
  class InvalidDefinition < ArgumentError
8
8
  OPTIONS = 'Options to define one: :of, :is, :respond_to, :instance_of, :array_of or :array_with'.freeze
data/lib/kind/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kind
4
- VERSION = '3.0.0'
4
+ VERSION = '5.0.0'
5
5
  end
data/test.sh CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/bin/bash
2
2
 
3
- bundle
4
-
5
- rm Gemfile.lock
6
-
7
3
  source $(dirname $0)/.travis.sh
8
4
 
5
+ echo ''
6
+ echo 'Resetting Gemfile'
7
+ echo ''
8
+
9
9
  rm Gemfile.lock
10
10
 
11
11
  bundle
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kind
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-06-25 00:00:00.000000000 Z
11
+ date: 2021-02-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A simple type system (at runtime) for Ruby - free of dependencies.
14
14
  email:
@@ -18,8 +18,10 @@ extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
20
  - ".gitignore"
21
+ - ".tool-versions"
21
22
  - ".travis.sh"
22
23
  - ".travis.yml"
24
+ - CHANGELOG.md
23
25
  - CODE_OF_CONDUCT.md
24
26
  - Gemfile
25
27
  - LICENSE.txt
@@ -31,15 +33,49 @@ files:
31
33
  - lib/kind.rb
32
34
  - lib/kind/active_model/kind_validator.rb
33
35
  - lib/kind/active_model/validation.rb
34
- - lib/kind/checker.rb
35
- - lib/kind/checker/factory.rb
36
- - lib/kind/checker/protocol.rb
36
+ - lib/kind/core.rb
37
+ - lib/kind/core/kind.rb
38
+ - lib/kind/core/undefined.rb
39
+ - lib/kind/dig.rb
37
40
  - lib/kind/empty.rb
41
+ - lib/kind/empty/constant.rb
38
42
  - lib/kind/error.rb
39
- - lib/kind/is.rb
40
43
  - lib/kind/maybe.rb
41
- - lib/kind/of.rb
42
- - lib/kind/types.rb
44
+ - lib/kind/maybe/none.rb
45
+ - lib/kind/maybe/result.rb
46
+ - lib/kind/maybe/some.rb
47
+ - lib/kind/maybe/typed.rb
48
+ - lib/kind/maybe/wrappable.rb
49
+ - lib/kind/presence.rb
50
+ - lib/kind/try.rb
51
+ - lib/kind/type_checker.rb
52
+ - lib/kind/type_checkers.rb
53
+ - lib/kind/type_checkers/core/array.rb
54
+ - lib/kind/type_checkers/core/class.rb
55
+ - lib/kind/type_checkers/core/comparable.rb
56
+ - lib/kind/type_checkers/core/enumerable.rb
57
+ - lib/kind/type_checkers/core/enumerator.rb
58
+ - lib/kind/type_checkers/core/file.rb
59
+ - lib/kind/type_checkers/core/float.rb
60
+ - lib/kind/type_checkers/core/hash.rb
61
+ - lib/kind/type_checkers/core/integer.rb
62
+ - lib/kind/type_checkers/core/io.rb
63
+ - lib/kind/type_checkers/core/method.rb
64
+ - lib/kind/type_checkers/core/module.rb
65
+ - lib/kind/type_checkers/core/numeric.rb
66
+ - lib/kind/type_checkers/core/proc.rb
67
+ - lib/kind/type_checkers/core/queue.rb
68
+ - lib/kind/type_checkers/core/range.rb
69
+ - lib/kind/type_checkers/core/regexp.rb
70
+ - lib/kind/type_checkers/core/string.rb
71
+ - lib/kind/type_checkers/core/struct.rb
72
+ - lib/kind/type_checkers/core/symbol.rb
73
+ - lib/kind/type_checkers/core/time.rb
74
+ - lib/kind/type_checkers/custom/boolean.rb
75
+ - lib/kind/type_checkers/custom/callable.rb
76
+ - lib/kind/type_checkers/custom/lambda.rb
77
+ - lib/kind/type_checkers/stdlib/open_struct.rb
78
+ - lib/kind/type_checkers/stdlib/set.rb
43
79
  - lib/kind/undefined.rb
44
80
  - lib/kind/validator.rb
45
81
  - lib/kind/version.rb
@@ -65,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
101
  - !ruby/object:Gem::Version
66
102
  version: '0'
67
103
  requirements: []
68
- rubygems_version: 3.0.6
104
+ rubygems_version: 3.1.4
69
105
  signing_key:
70
106
  specification_version: 4
71
107
  summary: A simple type system (at runtime) for Ruby.
data/lib/kind/checker.rb DELETED
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'kind/checker/factory'
4
- require 'kind/checker/protocol'
5
- module Kind
6
- class Checker
7
- include Protocol
8
-
9
- attr_reader :__kind
10
-
11
- def initialize(kind)
12
- @__kind = kind
13
- end
14
- end
15
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'singleton'
4
-
5
- module Kind
6
- class Checker
7
- class Factory
8
- include Singleton
9
-
10
- def self.create(kind)
11
- instance.create(kind)
12
- end
13
-
14
- def initialize
15
- @__checkers__ = {}
16
- end
17
-
18
- MODULE_OR_CLASS = 'Module/Class'.freeze
19
-
20
- private_constant :MODULE_OR_CLASS
21
-
22
- def create(kind)
23
- @__checkers__[kind] ||= begin
24
- kind_name = kind.name
25
-
26
- if Kind::Of.const_defined?(kind_name, false)
27
- Kind::Of.const_get(kind_name)
28
- else
29
- Kind::Checker.new(Kind::Of.(Module, kind, MODULE_OR_CLASS))
30
- end
31
- end
32
- end
33
- end
34
- end
35
- end
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kind
4
- class Checker
5
- module Protocol
6
- def class?(value)
7
- Kind::Is.__call__(__kind, value)
8
- end
9
-
10
- def instance(value, options = Empty::HASH)
11
- default = options[:or]
12
-
13
- return Kind::Of.(__kind, value) if ::Kind::Maybe::Value.none?(default)
14
-
15
- Kind::Undefined != value && instance?(value) ? value : Kind::Of.(__kind, default)
16
- end
17
-
18
- def [](value, options = options = Empty::HASH)
19
- instance(value, options)
20
- end
21
-
22
- def to_proc
23
- @to_proc ||=
24
- -> checker { -> value { checker.instance(value) } }.call(self)
25
- end
26
-
27
- def __is_instance__(value)
28
- value.kind_of?(__kind)
29
- end
30
-
31
- def is_instance_to_proc
32
- @is_instance_to_proc ||=
33
- -> checker { -> value { checker.__is_instance__(value) } }.call(self)
34
- end
35
-
36
- def instance?(*args)
37
- return is_instance_to_proc if args.empty?
38
-
39
- return args.all? { |object| __is_instance__(object) } if args.size > 1
40
-
41
- arg = args[0]
42
- Kind::Undefined == arg ? is_instance_to_proc : __is_instance__(arg)
43
- end
44
-
45
- def or_nil(value)
46
- return value if instance?(value)
47
- end
48
-
49
- def or_undefined(value)
50
- or_nil(value) || Kind::Undefined
51
- end
52
-
53
- def __as_maybe__(value)
54
- Kind::Maybe.new(or_nil(value))
55
- end
56
-
57
- def as_maybe_to_proc
58
- @as_maybe_to_proc ||=
59
- -> checker { -> value { checker.__as_maybe__(value) } }.call(self)
60
- end
61
-
62
- def as_maybe(value = Kind::Undefined)
63
- return __as_maybe__(value) if Kind::Undefined != value
64
-
65
- as_maybe_to_proc
66
- end
67
-
68
- def as_optional(value = Kind::Undefined)
69
- as_maybe(value)
70
- end
71
- end
72
- end
73
- end