kind 4.1.0 → 5.4.0

Sign up to get free protection for your applications and to get access to all the features.
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