kind 4.1.0 → 5.4.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.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/.tool-versions +1 -1
  3. data/.travis.sh +39 -7
  4. data/.travis.yml +1 -2
  5. data/CHANGELOG.md +524 -29
  6. data/Gemfile +13 -6
  7. data/README.md +57 -43
  8. data/kind.gemspec +3 -3
  9. data/lib/kind.rb +2 -84
  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 -2
  29. data/lib/kind/empty/constant.rb +7 -0
  30. data/lib/kind/enum.rb +63 -0
  31. data/lib/kind/enum/item.rb +40 -0
  32. data/lib/kind/enum/methods.rb +72 -0
  33. data/lib/kind/function.rb +45 -0
  34. data/lib/kind/functional.rb +89 -0
  35. data/lib/kind/functional/action.rb +87 -0
  36. data/lib/kind/functional/steps.rb +22 -0
  37. data/lib/kind/immutable_attributes.rb +34 -0
  38. data/lib/kind/immutable_attributes/initializer.rb +70 -0
  39. data/lib/kind/immutable_attributes/reader.rb +38 -0
  40. data/lib/kind/maybe.rb +37 -12
  41. data/lib/kind/maybe/methods.rb +21 -0
  42. data/lib/kind/maybe/monad.rb +82 -0
  43. data/lib/kind/maybe/monad/wrapper.rb +19 -0
  44. data/lib/kind/maybe/none.rb +12 -19
  45. data/lib/kind/maybe/some.rb +68 -26
  46. data/lib/kind/maybe/typed.rb +11 -5
  47. data/lib/kind/maybe/{wrappable.rb → wrapper.rb} +8 -4
  48. data/lib/kind/monad.rb +22 -0
  49. data/lib/kind/monads.rb +5 -0
  50. data/lib/kind/objects.rb +17 -0
  51. data/lib/kind/objects/basic_object.rb +43 -0
  52. data/lib/kind/objects/modules.rb +32 -0
  53. data/lib/kind/{type_checkers → objects/modules}/core/array.rb +3 -1
  54. data/lib/kind/{type_checkers → objects/modules}/core/class.rb +1 -1
  55. data/lib/kind/{type_checkers → objects/modules}/core/comparable.rb +1 -1
  56. data/lib/kind/{type_checkers → objects/modules}/core/enumerable.rb +1 -1
  57. data/lib/kind/{type_checkers → objects/modules}/core/enumerator.rb +1 -1
  58. data/lib/kind/{type_checkers → objects/modules}/core/file.rb +1 -1
  59. data/lib/kind/{type_checkers → objects/modules}/core/float.rb +1 -1
  60. data/lib/kind/{type_checkers → objects/modules}/core/hash.rb +3 -1
  61. data/lib/kind/{type_checkers → objects/modules}/core/integer.rb +1 -1
  62. data/lib/kind/{type_checkers → objects/modules}/core/io.rb +1 -1
  63. data/lib/kind/{type_checkers → objects/modules}/core/method.rb +1 -1
  64. data/lib/kind/{type_checkers → objects/modules}/core/module.rb +1 -1
  65. data/lib/kind/{type_checkers → objects/modules}/core/numeric.rb +1 -1
  66. data/lib/kind/{type_checkers → objects/modules}/core/proc.rb +1 -1
  67. data/lib/kind/{type_checkers → objects/modules}/core/queue.rb +1 -1
  68. data/lib/kind/{type_checkers → objects/modules}/core/range.rb +1 -1
  69. data/lib/kind/{type_checkers → objects/modules}/core/regexp.rb +1 -1
  70. data/lib/kind/{type_checkers → objects/modules}/core/string.rb +3 -1
  71. data/lib/kind/{type_checkers → objects/modules}/core/struct.rb +1 -1
  72. data/lib/kind/{type_checkers → objects/modules}/core/symbol.rb +1 -1
  73. data/lib/kind/{type_checkers → objects/modules}/core/time.rb +1 -1
  74. data/lib/kind/{type_checkers → objects/modules}/custom/boolean.rb +2 -2
  75. data/lib/kind/{type_checkers → objects/modules}/custom/callable.rb +1 -1
  76. data/lib/kind/{type_checkers → objects/modules}/custom/lambda.rb +1 -1
  77. data/lib/kind/{type_checkers → objects/modules}/stdlib/open_struct.rb +3 -1
  78. data/lib/kind/{type_checkers → objects/modules}/stdlib/set.rb +3 -1
  79. data/lib/kind/objects/nil.rb +17 -0
  80. data/lib/kind/objects/not_nil.rb +9 -0
  81. data/lib/kind/objects/object.rb +56 -0
  82. data/lib/kind/objects/respond_to.rb +30 -0
  83. data/lib/kind/objects/union_type.rb +44 -0
  84. data/lib/kind/presence.rb +4 -2
  85. data/lib/kind/result.rb +31 -0
  86. data/lib/kind/result/abstract.rb +53 -0
  87. data/lib/kind/result/failure.rb +33 -0
  88. data/lib/kind/result/methods.rb +17 -0
  89. data/lib/kind/result/monad.rb +74 -0
  90. data/lib/kind/result/monad/wrapper.rb +19 -0
  91. data/lib/kind/result/success.rb +53 -0
  92. data/lib/kind/strict/disabled.rb +34 -0
  93. data/lib/kind/try.rb +22 -10
  94. data/lib/kind/validator.rb +111 -0
  95. data/lib/kind/version.rb +1 -1
  96. metadata +84 -51
  97. data/lib/kind/active_model/kind_validator.rb +0 -103
  98. data/lib/kind/core.rb +0 -10
  99. data/lib/kind/core/deprecation.rb +0 -29
  100. data/lib/kind/core/kind.rb +0 -61
  101. data/lib/kind/core/undefined.rb +0 -7
  102. data/lib/kind/core/wrong_number_of_args.rb +0 -9
  103. data/lib/kind/deprecations/built_in_type_checkers.rb +0 -23
  104. data/lib/kind/deprecations/checker.rb +0 -16
  105. data/lib/kind/deprecations/checker/factory.rb +0 -31
  106. data/lib/kind/deprecations/checker/protocol.rb +0 -73
  107. data/lib/kind/deprecations/is.rb +0 -35
  108. data/lib/kind/deprecations/of.rb +0 -258
  109. data/lib/kind/deprecations/types.rb +0 -121
  110. data/lib/kind/error.rb +0 -15
  111. data/lib/kind/maybe/result.rb +0 -51
  112. data/lib/kind/type_checker.rb +0 -87
  113. data/lib/kind/type_checkers.rb +0 -30
data/Gemfile CHANGED
@@ -18,24 +18,31 @@ activemodel = case activemodel_version
18
18
 
19
19
  simplecov_version =
20
20
  case RUBY_VERSION
21
- when /\A2.[23]/ then '0.17.1'
21
+ when /\A2.[123]/ then '0.17.1'
22
22
  when /\A2.4/ then '~> 0.18.5'
23
23
  else '~> 0.19'
24
24
  end
25
25
 
26
+ is_ruby_2_1 = RUBY_VERSION <= '2.2.0'
27
+
28
+ minitest_version =
29
+ if activemodel_version
30
+ activemodel_version < '4.1' ? '~> 4.2' : '~> 5.0'
31
+ else
32
+ is_ruby_2_1 ? '~> 4.2' : '~> 5.0'
33
+ end
34
+
26
35
  group :test do
27
36
  if activemodel_version
28
37
  gem 'activesupport', activemodel, require: false
29
- gem 'activemodel', activemodel, require: false
30
- gem 'minitest', activemodel_version < '4.1' ? '~> 4.2' : '~> 5.0'
31
- else
32
- gem 'minitest', '~> 5.0'
38
+ gem 'activemodel' , activemodel, require: false
33
39
  end
34
40
 
41
+ gem 'minitest' , minitest_version
35
42
  gem 'simplecov', simplecov_version, require: false
36
43
  end
37
44
 
38
- gem 'rake', '~> 13.0'
45
+ gem 'rake', is_ruby_2_1 ? '~> 12.3' : '~> 13.0'
39
46
 
40
47
  # Specify your gem's dependencies in type_validator.gemspec
41
48
  gemspec
data/README.md CHANGED
@@ -1,12 +1,9 @@
1
1
  <p align="center">
2
2
  <h1 align="center">🤷 kind</h1>
3
- <p align="center"><i>A simple type system (at runtime) for Ruby - free of dependencies.</i></p>
4
- <br>
3
+ <p align="center"><i>A development toolkit for Ruby with several small/cohesive abstractions to empower your development workflow - It's totally free of dependencies.</i></p>
5
4
  </p>
6
5
 
7
6
  <p align="center">
8
- <img src="https://img.shields.io/badge/ruby->%3D%202.2.0-ruby.svg?colorA=99004d&colorB=cc0066" alt="Ruby">
9
-
10
7
  <a href="https://rubygems.org/gems/kind">
11
8
  <img alt="Gem" src="https://img.shields.io/gem/v/kind.svg?style=flat-square">
12
9
  </a>
@@ -15,6 +12,14 @@
15
12
  <img alt="Build Status" src="https://travis-ci.com/serradura/kind.svg?branch=master">
16
13
  </a>
17
14
 
15
+ <br />
16
+
17
+ <img src="https://img.shields.io/badge/ruby%20%3E=%202.1,%20%3C%203.1-ruby.svg?colorA=99004d&colorB=cc0066" alt="Ruby">
18
+
19
+ <img src="https://img.shields.io/badge/rails%20%3E=%203.2.0,%20%3C%207.0-rails.svg?colorA=8B0000&colorB=FF0000" alt="Rails">
20
+
21
+ <br />
22
+
18
23
  <a href="https://codeclimate.com/github/serradura/kind/maintainability">
19
24
  <img alt="Maintainability" src="https://api.codeclimate.com/v1/badges/711329decb2806ccac95/maintainability">
20
25
  </a>
@@ -26,19 +31,22 @@
26
31
 
27
32
  **Motivation:**
28
33
 
29
- As a creator of Ruby gems, I have a common need that I have to handle in many of my projects: type checking of method arguments.
34
+ This project was born to help me with a simple task, create a light and fast type checker (at runtime) for Ruby. The initial idea was to have something to raise an exception when a method or function (procs) received a wrong input.
35
+
36
+ But through time it was natural the addition of more features to improve the development workflow, like monads ([`Kind::Maybe`](#kindmaybe), `Kind::Either` / `Kind::Result`), enums (`Kind::Enum`), immutable objects (`Kind::ImmutableAttributes`), [type validation via ActiveModel::Validation](#kindvalidator-activemodelvalidations), and several abstractions to help the implementation of business logic (`Kind::Functional::Steps`, `Kind::Functional::Action`, `Kind::Action`).
30
37
 
31
- One of the goals of this project is to do simple type checking like `"some string".is_a?(String)`, but, exposing useful abstractions around this. e.g: [Kind.\<Type\> methods](#verifying-the-kind-of-some-object), [active model validations](#kindvalidator-activemodelvalidations), [maybe monad](#kindmaybe).
38
+ So, I invite you to check out these features to see how they could be useful for you. Enjoy!
32
39
 
33
40
  ## Documentation <!-- omit in toc -->
34
41
 
35
42
  Version | Documentation
36
43
  ---------- | -------------
37
- unreleased | https://github.com/serradura/u-case/blob/main/README.md
38
- 4.1.0 | https://github.com/serradura/u-case/blob/v4.x/README.md
39
- 3.1.0 | https://github.com/serradura/u-case/blob/v3.x/README.md
40
- 2.3.0 | https://github.com/serradura/u-case/blob/v2.x/README.md
41
- 1.9.0 | https://github.com/serradura/u-case/blob/v1.x/README.md
44
+ unreleased | https://github.com/serradura/kind/blob/main/README.md
45
+ 5.4.0 | https://github.com/serradura/kind/blob/v5.x/README.md
46
+ 4.1.0 | https://github.com/serradura/kind/blob/v4.x/README.md
47
+ 3.1.0 | https://github.com/serradura/kind/blob/v3.x/README.md
48
+ 2.3.0 | https://github.com/serradura/kind/blob/v2.x/README.md
49
+ 1.9.0 | https://github.com/serradura/kind/blob/v1.x/README.md
42
50
 
43
51
  ## Table of Contents <!-- omit in toc -->
44
52
  - [Compatibility](#compatibility)
@@ -53,16 +61,16 @@ unreleased | https://github.com/serradura/u-case/blob/main/README.md
53
61
  - [Kind::\<Type\>.value()](#kindtypevalue-1)
54
62
  - [Kind::\<Type\>.maybe](#kindtypemaybe)
55
63
  - [Kind::\<Type\>?](#kindtype-2)
56
- - [Kind::{Array,Hash,String,Set}.value_or_empty()](#kindarrayhashstringsetvalue_or_empty)
57
- - [List of all type checkers](#list-of-all-type-checkers)
64
+ - [Kind::{Array,Hash,String,Set}.empty_or()](#kindarrayhashstringsetempty_or)
65
+ - [List of all type handlers](#list-of-all-type-handlers)
58
66
  - [Core](#core)
59
67
  - [Stdlib](#stdlib)
60
68
  - [Custom](#custom)
61
- - [Creating type checkers](#creating-type-checkers)
69
+ - [Creating type handlers](#creating-type-handlers)
62
70
  - [Dynamic creation](#dynamic-creation)
63
71
  - [Using a class or a module](#using-a-class-or-a-module)
64
72
  - [Using an object which responds to ===](#using-an-object-which-responds-to-)
65
- - [Kind::<Type> module](#kindtype-module)
73
+ - [Kind::<Type> object](#kindtype-object)
66
74
  - [Utility methods](#utility-methods)
67
75
  - [Kind.of_class?()](#kindof_class)
68
76
  - [Kind.of_module?()](#kindof_module)
@@ -95,6 +103,7 @@ unreleased | https://github.com/serradura/u-case/blob/main/README.md
95
103
  - [Kind::Maybe#check](#kindmaybecheck)
96
104
  - [Kind::Maybe#presence](#kindmaybepresence)
97
105
  - [Kind::Empty](#kindempty)
106
+ - [Defining Empty as Kind::Empty an alias](#defining-empty-as-kindempty-an-alias)
98
107
  - [Kind::Validator (ActiveModel::Validations)](#kindvalidator-activemodelvalidations)
99
108
  - [Usage](#usage-1)
100
109
  - [Object#===](#object)
@@ -113,13 +122,14 @@ unreleased | https://github.com/serradura/u-case/blob/main/README.md
113
122
 
114
123
  ## Compatibility
115
124
 
116
- | u-case | branch | ruby | activemodel |
117
- | -------------- | ------- | -------- | -------------- |
118
- | unreleased | main | >= 2.2.0 | >= 3.2, <= 6.1 |
119
- | 4.1.0 | v4.x | >= 2.2.0 | >= 3.2, <= 6.1 |
120
- | 3.1.0 | v3.x | >= 2.2.0 | >= 3.2, <= 6.1 |
121
- | 2.3.0 | v2.x | >= 2.2.0 | >= 3.2, <= 6.0 |
122
- | 1.9.0 | v1.x | >= 2.2.0 | >= 3.2, <= 6.0 |
125
+ | kind | branch | ruby | activemodel |
126
+ | -------------- | ------- | ------------------ | -------------- |
127
+ | unreleased | main | >= 2.1.0, <= 3.0.0 | >= 3.2, < 7.0 |
128
+ | 5.4.0 | v5.x | >= 2.1.0, <= 3.0.0 | >= 3.2, < 7.0 |
129
+ | 4.1.0 | v4.x | >= 2.2.0, <= 3.0.0 | >= 3.2, < 7.0 |
130
+ | 3.1.0 | v3.x | >= 2.2.0, <= 2.7 | >= 3.2, < 7.0 |
131
+ | 2.3.0 | v2.x | >= 2.2.0, <= 2.7 | >= 3.2, <= 6.0 |
132
+ | 1.9.0 | v1.x | >= 2.2.0, <= 2.7 | >= 3.2, <= 6.0 |
123
133
 
124
134
  > Note: The activemodel is an optional dependency, it is related with the [Kind::Validator](#kindvalidator-activemodelvalidations).
125
135
 
@@ -320,17 +330,17 @@ collection.select(&Kind::Enumerable?) # [{:number=>1}, {:number=>3}, [:number, 5
320
330
 
321
331
  [⬆️ &nbsp;Back to Top](#table-of-contents-)
322
332
 
323
- ### Kind::{Array,Hash,String,Set}.value_or_empty()
333
+ ### Kind::{Array,Hash,String,Set}.empty_or()
324
334
 
325
- This method is available for some type checkers (`Kind::Array`, `Kind::Hash`, `Kind::String`, `Kind::Set`), and it will return an empty frozen value if the given one hasn't the expected kind.
335
+ This method is available for some type handlers (`Kind::Array`, `Kind::Hash`, `Kind::String`, `Kind::Set`), and it will return an empty frozen value if the given one hasn't the expected kind.
326
336
  ```ruby
327
- Kind::Array.value_or_empty({}) # []
328
- Kind::Array.value_or_empty({}).frozen? # true
337
+ Kind::Array.empty_or({}) # []
338
+ Kind::Array.empty_or({}).frozen? # true
329
339
  ```
330
340
 
331
341
  [⬆️ &nbsp;Back to Top](#table-of-contents-)
332
342
 
333
- ### List of all type checkers
343
+ ### List of all type handlers
334
344
 
335
345
  #### Core
336
346
 
@@ -369,9 +379,9 @@ Kind::Array.value_or_empty({}).frozen? # true
369
379
 
370
380
  [⬆️ &nbsp;Back to Top](#table-of-contents-)
371
381
 
372
- ### Creating type checkers
382
+ ### Creating type handlers
373
383
 
374
- There are two ways to do this, you can create type checkers dynamically or defining a module.
384
+ There are two ways to do this, you can create type handlers dynamically or defining a module.
375
385
 
376
386
  #### Dynamic creation
377
387
 
@@ -387,7 +397,7 @@ kind_of_user = Kind::Of(User)
387
397
 
388
398
  # kind_of_user.name
389
399
  # kind_of_user.kind
390
- # The type checker can return its kind and its name
400
+ # The type handler can return its kind and its name
391
401
  kind_of_user.name # "User"
392
402
  kind_of_user.kind # User
393
403
 
@@ -457,7 +467,7 @@ PositiveInteger = Kind::Of(
457
467
 
458
468
  # PositiveInteger.name
459
469
  # PositiveInteger.kind
460
- # The type checker can return its kind and its name
470
+ # The type handler can return its kind and its name
461
471
  PositiveInteger.name # "PositiveInteger"
462
472
  PositiveInteger.kind # #<Proc:0x0000.... >
463
473
 
@@ -518,9 +528,9 @@ PositiveInteger.maybe(2).value_or(1) # 2
518
528
 
519
529
  [⬆️ &nbsp;Back to Top](#table-of-contents-)
520
530
 
521
- #### Kind::<Type> module
531
+ #### Kind::<Type> object
522
532
 
523
- The idea here is to create a type checker inside of the `Kind` namespace, so to do this, you will only need to use pure Ruby. e.g:
533
+ The idea here is to create a type handler inside of the `Kind` namespace and to do this you will only need to use pure Ruby. e.g:
524
534
 
525
535
  ```ruby
526
536
  class User
@@ -528,9 +538,9 @@ end
528
538
 
529
539
  module Kind
530
540
  module User
531
- extend self, TypeChecker
541
+ extend self, ::Kind::Object
532
542
 
533
- # Define the expected kind of this type checker.
543
+ # Define the expected kind of this type handler.
534
544
  def kind; ::User; end
535
545
  end
536
546
 
@@ -540,7 +550,7 @@ module Kind
540
550
  end
541
551
  end
542
552
 
543
- # Doing this you will have the same methods of a standard type checker (like: `Kind::Symbol`).
553
+ # Doing this you will have the same methods of a standard type handler (like: `Kind::Symbol`).
544
554
 
545
555
  user = User.new
546
556
 
@@ -558,7 +568,7 @@ The advantages of this approach are:
558
568
 
559
569
  The disadvantage is:
560
570
 
561
- 1. You could overwrite some standard type checker or constant. I believe that this will be hard to happen, but must be your concern if you decide to use this kind of approach.
571
+ 1. You could overwrite some standard type handler or constant. I believe that this will be hard to happen, but must be your concern if you decide to use this kind of approach.
562
572
 
563
573
  [⬆️ &nbsp;Back to Top](#table-of-contents-)
564
574
 
@@ -1429,7 +1439,11 @@ def do_something(value, with_options: Kind::Empty::HASH)
1429
1439
  end
1430
1440
  ```
1431
1441
 
1432
- One last thing, if there is no constant declared as Empty, the `kind` gem will define `Empty` as an alias for `Kind::Empty`. Knowing this, the previous example could be written like this:
1442
+ ### Defining Empty as Kind::Empty an alias
1443
+
1444
+ You can require `kind/empty/constant` to define `Empty` as a `Kind::Empty` alias. But, a `LoadError` will be raised if there is an already defined constant `Empty`.
1445
+
1446
+ So if you required this file, the previous example could be written like this:
1433
1447
 
1434
1448
  ```ruby
1435
1449
  def do_something(value, with_options: Empty::HASH)
@@ -1437,7 +1451,7 @@ def do_something(value, with_options: Empty::HASH)
1437
1451
  end
1438
1452
  ```
1439
1453
 
1440
- Follows the list of constants, if the alias is available to be created:
1454
+ Follows the list of constants if the alias was defined:
1441
1455
 
1442
1456
  - `Empty::SET`
1443
1457
  - `Empty::HASH`
@@ -1448,7 +1462,7 @@ Follows the list of constants, if the alias is available to be created:
1448
1462
 
1449
1463
  ## Kind::Validator (ActiveModel::Validations)
1450
1464
 
1451
- This module enables the capability to validate types via [`ActiveModel::Validations >= 3.2, < 6.1.0`](https://api.rubyonrails.org/classes/ActiveModel/Validations.html). e.g
1465
+ This module enables the capability to validate types via [`ActiveModel::Validations >= 3.2, < 7.0`](https://api.rubyonrails.org/classes/ActiveModel/Validations.html). e.g
1452
1466
 
1453
1467
  ```ruby
1454
1468
  class Person
@@ -1464,10 +1478,10 @@ And to make use of it, you will need to do an explicitly require. e.g:
1464
1478
 
1465
1479
  ```ruby
1466
1480
  # In some Gemfile
1467
- gem 'kind', require: 'kind/active_model/validation'
1481
+ gem 'kind', require: 'kind/validator'
1468
1482
 
1469
1483
  # In some .rb file
1470
- require 'kind/active_model/validation'
1484
+ require 'kind/validator'
1471
1485
  ```
1472
1486
 
1473
1487
  [⬆️ &nbsp;Back to Top](#table-of-contents-)
@@ -1486,7 +1500,7 @@ Use an array to verify if the attribute is an instance of one of the classes/mod
1486
1500
  validates :status, kind: { of: [String, Symbol]}
1487
1501
  ```
1488
1502
 
1489
- Because of kind verification be made via `===` you can use type checkers as the expected kinds.
1503
+ Because of kind verification be made via `===` you can use type handlers as the expected kinds.
1490
1504
 
1491
1505
  ```ruby
1492
1506
  validates :alive, kind: Kind::Boolean
data/kind.gemspec CHANGED
@@ -6,11 +6,11 @@ Gem::Specification.new do |spec|
6
6
  spec.authors = ['Rodrigo Serradura']
7
7
  spec.email = ['rodrigo.serradura@gmail.com']
8
8
 
9
- spec.summary = %q{A simple type system (at runtime) for Ruby.}
10
- spec.description = %q{A simple type system (at runtime) for Ruby - free of dependencies.}
9
+ spec.summary = %q{A development toolkit for Ruby with several small/cohesive abstractions to empower your development workflow.}
10
+ spec.description = %q{A development toolkit for Ruby with several small/cohesive abstractions (monads, enums, business logic, data validation...) to empower your development workflow - It's totally 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.2.0')
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 'set'
4
- require 'ostruct'
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/maybe'
16
-
17
- require 'kind/type_checker'
18
- require 'kind/type_checkers'
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
- WRONG_NUMBER_OF_ARGS.error!(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