kind 2.1.0 → 2.2.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/README.md +193 -169
- data/lib/kind.rb +18 -18
- data/lib/kind/active_model/kind_validator.rb +2 -2
- data/lib/kind/checker.rb +3 -3
- data/lib/kind/error.rb +1 -1
- data/lib/kind/maybe.rb +7 -7
- data/lib/kind/types.rb +2 -2
- data/lib/kind/undefined.rb +1 -1
- data/lib/kind/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3bb8430c79ca97835ebdf6604e0c5afc4301f912db778e5f930fb9e699ae08c1
|
4
|
+
data.tar.gz: 0557c3df900513e5ec7d45fec79fdf7502f0cb06a8e1538ff935e0228ef11136
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0ad03f0d27484914f45607d9e1fd7cfdaf8000d700e31f069b274b5f977f42a8736a3d03d0cba1f3d06679f0f5a05b56d7c3b4acfd2a90cce20e524de6f9154a
|
7
|
+
data.tar.gz: 6f8e54590261939a43a52895921d80fb693a0e16361d011f53a80f1d7269aaade1e8871ae44374586ec488c026a02fced9057fdfcb300c532bd3a018498e954a
|
data/README.md
CHANGED
@@ -31,6 +31,10 @@ One of the goals of this project is to do simple type checking like `"some strin
|
|
31
31
|
- [Classes' type checkers](#classes-type-checkers)
|
32
32
|
- [Modules' type checkers](#modules-type-checkers)
|
33
33
|
- [Specials' type checkers](#specials-type-checkers)
|
34
|
+
- [Kind::Validator (ActiveModel::Validations)](#kindvalidator-activemodelvalidations)
|
35
|
+
- [Usage](#usage-1)
|
36
|
+
- [Defining the default validation strategy](#defining-the-default-validation-strategy)
|
37
|
+
- [Using the `allow_nil` and `strict` options](#using-the-allow_nil-and-strict-options)
|
34
38
|
- [Kind::Undefined](#kindundefined)
|
35
39
|
- [Kind.of.\<Type\>.or_undefined()](#kindoftypeor_undefined)
|
36
40
|
- [Kind::Maybe](#kindmaybe)
|
@@ -43,10 +47,6 @@ One of the goals of this project is to do simple type checking like `"some strin
|
|
43
47
|
- [Replacing blocks by lambdas](#replacing-blocks-by-lambdas-2)
|
44
48
|
- [Kind.of.\<Type\>.as_optional](#kindoftypeas_optional)
|
45
49
|
- [Kind::Maybe#try](#kindmaybetry)
|
46
|
-
- [Kind::Validator (ActiveModel::Validations)](#kindvalidator-activemodelvalidations)
|
47
|
-
- [Usage](#usage-1)
|
48
|
-
- [Defining the default validation strategy](#defining-the-default-validation-strategy)
|
49
|
-
- [Using the `allow_nil` and `strict` options](#using-the-allow_nil-and-strict-options)
|
50
50
|
- [Kind::Empty](#kindempty)
|
51
51
|
- [Similar Projects](#similar-projects)
|
52
52
|
- [Development](#development)
|
@@ -163,13 +163,19 @@ Kind.of.Boolean.or_nil(true) # true
|
|
163
163
|
Use the method `.instance?` to verify if the given object has the expected type.
|
164
164
|
|
165
165
|
```ruby
|
166
|
-
Kind.of.Hash.instance?(
|
166
|
+
Kind.of.Hash.instance?({}) # true
|
167
|
+
Kind.of.Hash.instance?({}, HashWithIndifferentAccess.new) # true
|
168
|
+
|
169
|
+
Kind.of.Hash.instance?('') # false
|
170
|
+
Kind.of.Hash.instance?({}, '') # false
|
167
171
|
|
168
172
|
# ---
|
169
173
|
|
170
|
-
Kind.of.Boolean.instance?(
|
171
|
-
Kind.of.Boolean.instance?(true)
|
172
|
-
|
174
|
+
Kind.of.Boolean.instance?(true) # true
|
175
|
+
Kind.of.Boolean.instance?(true, false) # true
|
176
|
+
|
177
|
+
Kind.of.Boolean.instance?(nil) # false
|
178
|
+
Kind.of.Boolean.instance?(false, true, nil) # false
|
173
179
|
```
|
174
180
|
|
175
181
|
> **Note:** When `.instance?` is called without an argument,
|
@@ -186,6 +192,22 @@ collection
|
|
186
192
|
> To do this, use Kind.of.\<Type\>?()
|
187
193
|
|
188
194
|
```ruby
|
195
|
+
Kind.of.Hash?({}) # true
|
196
|
+
Kind.of.Hash?({}, HashWithIndifferentAccess.new) # true
|
197
|
+
|
198
|
+
Kind.of.Hash?('') # false
|
199
|
+
Kind.of.Hash?({}, '') # false
|
200
|
+
|
201
|
+
# ---
|
202
|
+
|
203
|
+
Kind.of.Boolean?(true) # true
|
204
|
+
Kind.of.Boolean?(false, true) # true
|
205
|
+
|
206
|
+
Kind.of.Boolean?(nil) # false
|
207
|
+
Kind.of.Boolean?(false, true, nil) # false
|
208
|
+
|
209
|
+
# ---
|
210
|
+
|
189
211
|
collection = [ {number: 1}, 'number 2', {number: 3}, :number_4 ]
|
190
212
|
|
191
213
|
collection.select(&Kind.of.Hash?) # [{:number=>1}, {:number=>3}]
|
@@ -459,6 +481,158 @@ The list of types (classes and modules) available to use with `Kind.of.*` or `Ki
|
|
459
481
|
|
460
482
|
[⬆️ Back to Top](#table-of-contents-)
|
461
483
|
|
484
|
+
## Kind::Validator (ActiveModel::Validations)
|
485
|
+
|
486
|
+
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
|
487
|
+
|
488
|
+
```ruby
|
489
|
+
class Person
|
490
|
+
include ActiveModel::Validations
|
491
|
+
|
492
|
+
attr_accessor :first_name, :last_name
|
493
|
+
|
494
|
+
validates :first_name, :last_name, kind: String
|
495
|
+
end
|
496
|
+
```
|
497
|
+
|
498
|
+
And to make use of it, you will need to do an explicitly require. e.g:
|
499
|
+
|
500
|
+
```ruby
|
501
|
+
# In some Gemfile
|
502
|
+
gem 'kind', require: 'kind/active_model/validation'
|
503
|
+
|
504
|
+
# In some .rb file
|
505
|
+
require 'kind/active_model/validation'
|
506
|
+
```
|
507
|
+
|
508
|
+
### Usage
|
509
|
+
|
510
|
+
**[Object#kind_of?](https://ruby-doc.org/core-2.6.4/Object.html#method-i-kind_of-3F)**
|
511
|
+
|
512
|
+
```ruby
|
513
|
+
validates :name, kind: { of: String }
|
514
|
+
|
515
|
+
# Use an array to verify if the attribute
|
516
|
+
# is an instance of one of the classes/modules.
|
517
|
+
|
518
|
+
validates :status, kind: { of: [String, Symbol]}
|
519
|
+
```
|
520
|
+
|
521
|
+
**[Kind.is](#verifying-the-kind-of-some-classmodule)**
|
522
|
+
|
523
|
+
```ruby
|
524
|
+
#
|
525
|
+
# Verifying if the attribute value is the class or a subclass.
|
526
|
+
#
|
527
|
+
class Human; end
|
528
|
+
class Person < Human; end
|
529
|
+
class User < Human; end
|
530
|
+
|
531
|
+
validates :human_kind, kind: { is: Human }
|
532
|
+
|
533
|
+
#
|
534
|
+
# Verifying if the attribute value is the module or if it is a class that includes the module
|
535
|
+
#
|
536
|
+
module Human; end
|
537
|
+
class Person; include Human; end
|
538
|
+
class User; include Human; end
|
539
|
+
|
540
|
+
validates :human_kind, kind: { is: Human }
|
541
|
+
|
542
|
+
#
|
543
|
+
# Verifying if the attribute value is the module or if it is a module that extends the module
|
544
|
+
#
|
545
|
+
module Human; end
|
546
|
+
module Person; extend Human; end
|
547
|
+
module User; extend Human; end
|
548
|
+
|
549
|
+
validates :human_kind, kind: { is: Human }
|
550
|
+
|
551
|
+
# or use an array to verify if the attribute
|
552
|
+
# is a kind of one those classes/modules.
|
553
|
+
|
554
|
+
validates :human_kind, kind: { is: [Person, User] }
|
555
|
+
```
|
556
|
+
|
557
|
+
**[Object#instance_of?](https://ruby-doc.org/core-2.6.4/Object.html#method-i-instance_of-3F)**
|
558
|
+
|
559
|
+
```ruby
|
560
|
+
validates :name, kind: { instance_of: String }
|
561
|
+
|
562
|
+
# or use an array to verify if the attribute
|
563
|
+
# is an instance of one of the classes/modules.
|
564
|
+
|
565
|
+
validates :name, kind: { instance_of: [String, Symbol] }
|
566
|
+
```
|
567
|
+
|
568
|
+
|
569
|
+
**[Object#respond_to?](https://ruby-doc.org/core-2.6.4/Object.html#method-i-respond_to-3F)**
|
570
|
+
|
571
|
+
```ruby
|
572
|
+
validates :handler, kind: { respond_to: :call }
|
573
|
+
```
|
574
|
+
|
575
|
+
**Array.new.all? { |item| item.kind_of?(Class) }**
|
576
|
+
|
577
|
+
```ruby
|
578
|
+
validates :account_types, kind: { array_of: String }
|
579
|
+
|
580
|
+
# or use an array to verify if the attribute
|
581
|
+
# is an instance of one of the classes
|
582
|
+
|
583
|
+
validates :account_types, kind: { array_of: [String, Symbol] }
|
584
|
+
```
|
585
|
+
|
586
|
+
**Array.new.all? { |item| expected_values.include?(item) }**
|
587
|
+
|
588
|
+
```ruby
|
589
|
+
# Verifies if the attribute value
|
590
|
+
# is an array with some or all the expected values.
|
591
|
+
|
592
|
+
validates :account_types, kind: { array_with: ['foo', 'bar'] }
|
593
|
+
```
|
594
|
+
|
595
|
+
#### Defining the default validation strategy
|
596
|
+
|
597
|
+
By default, you can define the attribute type directly (without a hash). e.g.
|
598
|
+
|
599
|
+
```ruby
|
600
|
+
validates :name, kind: String
|
601
|
+
# or
|
602
|
+
validates :name, kind: [String, Symbol]
|
603
|
+
```
|
604
|
+
|
605
|
+
To changes this behavior you can set another strategy to validates the attributes types:
|
606
|
+
|
607
|
+
```ruby
|
608
|
+
Kind::Validator.default_strategy = :instance_of
|
609
|
+
|
610
|
+
# Tip: Create an initializer if you are in a Rails application.
|
611
|
+
```
|
612
|
+
|
613
|
+
And these are the available options to define the default strategy:
|
614
|
+
- `kind_of` *(default)*
|
615
|
+
- `instance_of`
|
616
|
+
|
617
|
+
#### Using the `allow_nil` and `strict` options
|
618
|
+
|
619
|
+
You can use the `allow_nil` option with any of the kind validations. e.g.
|
620
|
+
|
621
|
+
```ruby
|
622
|
+
validates :name, kind: String, allow_nil: true
|
623
|
+
```
|
624
|
+
|
625
|
+
And as any active model validation, kind validations works with the `strict: true`
|
626
|
+
option and with the `validates!` method. e.g.
|
627
|
+
|
628
|
+
```ruby
|
629
|
+
validates :first_name, kind: String, strict: true
|
630
|
+
# or
|
631
|
+
validates! :last_name, kind: String
|
632
|
+
```
|
633
|
+
|
634
|
+
[⬆️ Back to Top](#table-of-contents-)
|
635
|
+
|
462
636
|
## Kind::Undefined
|
463
637
|
|
464
638
|
The [`Kind::Undefined`](https://github.com/serradura/kind/blob/834f6b8ebdc737de8e5628986585f30c1a5aa41b/lib/kind/undefined.rb) constant is used as the default argument of type checkers. This is necessary [to know if no arguments were passed to the type check methods](https://github.com/serradura/kind/blob/834f6b8ebdc737de8e5628986585f30c1a5aa41b/lib/kind.rb#L45-L48). But, you can use it in your codebase too, especially if you need to distinguish the usage of `nil` as a method argument.
|
@@ -586,7 +760,7 @@ you could use the methods `Kind::None` and `Kind::Some` to do this. e.g:
|
|
586
760
|
Add = -> params do
|
587
761
|
a, b = Kind.of.Hash(params, or: Empty::HASH).values_at(:a, :b)
|
588
762
|
|
589
|
-
return Kind::None unless Kind.of.Numeric
|
763
|
+
return Kind::None unless Kind.of.Numeric?(a, b)
|
590
764
|
|
591
765
|
Kind::Some(a + b)
|
592
766
|
end
|
@@ -721,7 +895,7 @@ def person_name(params)
|
|
721
895
|
end
|
722
896
|
```
|
723
897
|
|
724
|
-
> Note: You could use the `.as_optional` method (or it alias
|
898
|
+
> Note: You could use the `.as_optional` method (or it alias `.as_maybe`) with any [type checker](https://github.com/serradura/kind/blob/b177fed9cc2b3347d63963a2a2fd99f989c51a9a/README.md#type-checkers).
|
725
899
|
|
726
900
|
Let's see another example using a collection and how the method `.as_optional` works when it receives no argument.
|
727
901
|
|
@@ -802,13 +976,13 @@ If you don't want to use a map to access the value, you could use the `#try` met
|
|
802
976
|
```ruby
|
803
977
|
object = 'foo'
|
804
978
|
|
805
|
-
|
979
|
+
Kind::Maybe[object].try(:upcase) # "FOO"
|
806
980
|
|
807
|
-
|
981
|
+
Kind::Maybe[{}].try(:fetch, :number, 0) # 0
|
808
982
|
|
809
|
-
|
983
|
+
Kind::Maybe[{number: 1}].try(:fetch, :number) # 1
|
810
984
|
|
811
|
-
|
985
|
+
Kind::Maybe[object].try { |value| value.upcase } # "FOO"
|
812
986
|
|
813
987
|
#############
|
814
988
|
# Nil value #
|
@@ -816,9 +990,9 @@ p Kind::Maybe[object].try { |value| value.upcase } # "FOO"
|
|
816
990
|
|
817
991
|
object = nil
|
818
992
|
|
819
|
-
|
993
|
+
Kind::Maybe[object].try(:upcase) # nil
|
820
994
|
|
821
|
-
|
995
|
+
Kind::Maybe[object].try { |value| value.upcase } # nil
|
822
996
|
|
823
997
|
#########################
|
824
998
|
# Kind::Undefined value #
|
@@ -826,162 +1000,12 @@ p Kind::Maybe[object].try { |value| value.upcase } # nil
|
|
826
1000
|
|
827
1001
|
object = Kind::Undefined
|
828
1002
|
|
829
|
-
|
830
|
-
|
831
|
-
p Kind::Maybe[object].try { |value| value.upcase } # nil
|
832
|
-
```
|
833
|
-
|
834
|
-
[⬆️ Back to Top](#table-of-contents-)
|
835
|
-
|
836
|
-
## Kind::Validator (ActiveModel::Validations)
|
837
|
-
|
838
|
-
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
|
839
|
-
|
840
|
-
```ruby
|
841
|
-
class Person
|
842
|
-
include ActiveModel::Validations
|
843
|
-
|
844
|
-
attr_accessor :first_name, :last_name
|
845
|
-
|
846
|
-
validates :first_name, :last_name, kind: String
|
847
|
-
end
|
848
|
-
```
|
849
|
-
|
850
|
-
And to make use of it, you will need to do an explicitly require. e.g:
|
851
|
-
|
852
|
-
```ruby
|
853
|
-
# In some Gemfile
|
854
|
-
gem 'kind', require: 'kind/active_model/validation'
|
855
|
-
|
856
|
-
# In some .rb file
|
857
|
-
require 'kind/active_model/validation'
|
858
|
-
```
|
859
|
-
|
860
|
-
### Usage
|
861
|
-
|
862
|
-
**[Object#kind_of?](https://ruby-doc.org/core-2.6.4/Object.html#method-i-kind_of-3F)**
|
863
|
-
|
864
|
-
```ruby
|
865
|
-
validates :name, kind: { of: String }
|
866
|
-
|
867
|
-
# Use an array to verify if the attribute
|
868
|
-
# is an instance of one of the classes/modules.
|
869
|
-
|
870
|
-
validates :status, kind: { of: [String, Symbol]}
|
871
|
-
```
|
872
|
-
|
873
|
-
**[Kind.is](#verifying-the-kind-of-some-classmodule)**
|
874
|
-
|
875
|
-
```ruby
|
876
|
-
#
|
877
|
-
# Verifying if the attribute value is the class or a subclass.
|
878
|
-
#
|
879
|
-
class Human; end
|
880
|
-
class Person < Human; end
|
881
|
-
class User < Human; end
|
882
|
-
|
883
|
-
validates :human_kind, kind: { is: Human }
|
884
|
-
|
885
|
-
#
|
886
|
-
# Verifying if the attribute value is the module or if it is a class that includes the module
|
887
|
-
#
|
888
|
-
module Human; end
|
889
|
-
class Person; include Human; end
|
890
|
-
class User; include Human; end
|
891
|
-
|
892
|
-
validates :human_kind, kind: { is: Human }
|
893
|
-
|
894
|
-
#
|
895
|
-
# Verifying if the attribute value is the module or if it is a module that extends the module
|
896
|
-
#
|
897
|
-
module Human; end
|
898
|
-
module Person; extend Human; end
|
899
|
-
module User; extend Human; end
|
900
|
-
|
901
|
-
validates :human_kind, kind: { is: Human }
|
902
|
-
|
903
|
-
# or use an array to verify if the attribute
|
904
|
-
# is a kind of one those classes/modules.
|
905
|
-
|
906
|
-
validates :human_kind, kind: { is: [Person, User] }
|
907
|
-
```
|
908
|
-
|
909
|
-
**[Object#instance_of?](https://ruby-doc.org/core-2.6.4/Object.html#method-i-instance_of-3F)**
|
910
|
-
|
911
|
-
```ruby
|
912
|
-
validates :name, kind: { instance_of: String }
|
913
|
-
|
914
|
-
# or use an array to verify if the attribute
|
915
|
-
# is an instance of one of the classes/modules.
|
916
|
-
|
917
|
-
validates :name, kind: { instance_of: [String, Symbol] }
|
918
|
-
```
|
919
|
-
|
920
|
-
|
921
|
-
**[Object#respond_to?](https://ruby-doc.org/core-2.6.4/Object.html#method-i-respond_to-3F)**
|
922
|
-
|
923
|
-
```ruby
|
924
|
-
validates :handler, kind: { respond_to: :call }
|
925
|
-
```
|
926
|
-
|
927
|
-
**Array.new.all? { |item| item.kind_of?(Class) }**
|
928
|
-
|
929
|
-
```ruby
|
930
|
-
validates :account_types, kind: { array_of: String }
|
931
|
-
|
932
|
-
# or use an array to verify if the attribute
|
933
|
-
# is an instance of one of the classes
|
934
|
-
|
935
|
-
validates :account_types, kind: { array_of: [String, Symbol] }
|
936
|
-
```
|
937
|
-
|
938
|
-
**Array.new.all? { |item| expected_values.include?(item) }**
|
939
|
-
|
940
|
-
```ruby
|
941
|
-
# Verifies if the attribute value
|
942
|
-
# is an array with some or all the expected values.
|
943
|
-
|
944
|
-
validates :account_types, kind: { array_with: ['foo', 'bar'] }
|
945
|
-
```
|
946
|
-
|
947
|
-
#### Defining the default validation strategy
|
948
|
-
|
949
|
-
By default, you can define the attribute type directly (without a hash). e.g.
|
950
|
-
|
951
|
-
```ruby
|
952
|
-
validates :name, kind: String
|
953
|
-
# or
|
954
|
-
validates :name, kind: [String, Symbol]
|
955
|
-
```
|
956
|
-
|
957
|
-
To changes this behavior you can set another strategy to validates the attributes types:
|
958
|
-
|
959
|
-
```ruby
|
960
|
-
Kind::Validator.default_strategy = :instance_of
|
961
|
-
|
962
|
-
# Tip: Create an initializer if you are in a Rails application.
|
963
|
-
```
|
964
|
-
|
965
|
-
And these are the available options to define the default strategy:
|
966
|
-
- `kind_of` *(default)*
|
967
|
-
- `instance_of`
|
968
|
-
|
969
|
-
#### Using the `allow_nil` and `strict` options
|
970
|
-
|
971
|
-
You can use the `allow_nil` option with any of the kind validations. e.g.
|
1003
|
+
Kind::Maybe[object].try(:upcase) # nil
|
972
1004
|
|
973
|
-
|
974
|
-
validates :name, kind: String, allow_nil: true
|
1005
|
+
Kind::Maybe[object].try { |value| value.upcase } # nil
|
975
1006
|
```
|
976
1007
|
|
977
|
-
|
978
|
-
option and with the `validates!` method. e.g.
|
979
|
-
|
980
|
-
```ruby
|
981
|
-
validates :first_name, kind: String, strict: true
|
982
|
-
# or
|
983
|
-
validates! :last_name, kind: String
|
984
|
-
```
|
1008
|
+
> **Note:** You can use the try method with the `Kind::Optional`.
|
985
1009
|
|
986
1010
|
[⬆️ Back to Top](#table-of-contents-)
|
987
1011
|
|
data/lib/kind.rb
CHANGED
@@ -18,9 +18,9 @@ module Kind
|
|
18
18
|
private_constant :WRONG_NUMBER_OF_ARGUMENTS
|
19
19
|
|
20
20
|
def self.is(expected = Undefined, object = Undefined)
|
21
|
-
return Is if
|
21
|
+
return Is if Undefined == expected && Undefined == object
|
22
22
|
|
23
|
-
return Kind::Is.(expected, object) if
|
23
|
+
return Kind::Is.(expected, object) if Undefined != object
|
24
24
|
|
25
25
|
raise ArgumentError, WRONG_NUMBER_OF_ARGUMENTS
|
26
26
|
end
|
@@ -36,9 +36,9 @@ module Kind
|
|
36
36
|
__checkers__
|
37
37
|
|
38
38
|
def self.of(kind = Undefined, object = Undefined)
|
39
|
-
return Of if
|
39
|
+
return Of if Undefined == kind && Undefined == object
|
40
40
|
|
41
|
-
return Kind::Of.(kind, object) if
|
41
|
+
return Kind::Of.(kind, object) if Undefined != object
|
42
42
|
|
43
43
|
__checkers__[kind] ||= begin
|
44
44
|
kind_name = kind.name
|
@@ -65,7 +65,7 @@ module Kind
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def self.Module(value)
|
68
|
-
|
68
|
+
::Module == value || (value.is_a?(::Module) && !self.Class(value))
|
69
69
|
end
|
70
70
|
|
71
71
|
def self.Boolean(value)
|
@@ -81,7 +81,7 @@ module Kind
|
|
81
81
|
# -- Class
|
82
82
|
|
83
83
|
def self.Class(object = Undefined)
|
84
|
-
return Class if
|
84
|
+
return Class if Undefined == object
|
85
85
|
|
86
86
|
self.call(::Class, object)
|
87
87
|
end
|
@@ -103,7 +103,7 @@ module Kind
|
|
103
103
|
# -- Module
|
104
104
|
|
105
105
|
def self.Module(object = Undefined)
|
106
|
-
return Module if
|
106
|
+
return Module if Undefined == object
|
107
107
|
|
108
108
|
self.call(::Module, object)
|
109
109
|
end
|
@@ -112,7 +112,7 @@ module Kind
|
|
112
112
|
extend Checkable
|
113
113
|
|
114
114
|
def self.__kind_undefined(value)
|
115
|
-
__kind_error(Kind::Undefined) if
|
115
|
+
__kind_error(Kind::Undefined) if Kind::Undefined == value
|
116
116
|
|
117
117
|
yield
|
118
118
|
end
|
@@ -137,7 +137,7 @@ module Kind
|
|
137
137
|
if ::Kind::Maybe::Value.none?(default)
|
138
138
|
__kind_undefined(value) { __kind_of(value) }
|
139
139
|
else
|
140
|
-
return value if
|
140
|
+
return value if Kind::Undefined != value && instance?(value)
|
141
141
|
|
142
142
|
__kind_undefined(default) { __kind_of(default) }
|
143
143
|
end
|
@@ -155,7 +155,7 @@ module Kind
|
|
155
155
|
def self.Boolean(object = Undefined, options = Empty::HASH)
|
156
156
|
default = options[:or]
|
157
157
|
|
158
|
-
return Kind::Of::Boolean if
|
158
|
+
return Kind::Of::Boolean if Undefined == object && default.nil?
|
159
159
|
|
160
160
|
bool = object.nil? ? default : object
|
161
161
|
|
@@ -177,14 +177,14 @@ module Kind
|
|
177
177
|
if ::Kind::Maybe::Value.none?(default)
|
178
178
|
__kind_undefined(value) { Kind::Of::Boolean(value) }
|
179
179
|
else
|
180
|
-
return value if
|
180
|
+
return value if Kind::Undefined != value && instance?(value)
|
181
181
|
|
182
182
|
__kind_undefined(default) { Kind::Of::Boolean(default) }
|
183
183
|
end
|
184
184
|
end
|
185
185
|
|
186
186
|
def self.__kind_undefined(value)
|
187
|
-
if
|
187
|
+
if Kind::Undefined == value
|
188
188
|
raise Kind::Error.new('Boolean'.freeze, Kind::Undefined)
|
189
189
|
else
|
190
190
|
yield
|
@@ -210,7 +210,7 @@ module Kind
|
|
210
210
|
def self.Lambda(object = Undefined, options = Empty::HASH)
|
211
211
|
default = options[:or]
|
212
212
|
|
213
|
-
return Kind::Of::Lambda if
|
213
|
+
return Kind::Of::Lambda if Undefined == object && default.nil?
|
214
214
|
|
215
215
|
func = object || default
|
216
216
|
|
@@ -230,14 +230,14 @@ module Kind
|
|
230
230
|
if ::Kind::Maybe::Value.none?(default)
|
231
231
|
__kind_undefined(value) { Kind::Of::Lambda(value) }
|
232
232
|
else
|
233
|
-
return value if
|
233
|
+
return value if Kind::Undefined != value && instance?(value)
|
234
234
|
|
235
235
|
__kind_undefined(default) { Kind::Of::Lambda(default) }
|
236
236
|
end
|
237
237
|
end
|
238
238
|
|
239
239
|
def self.__kind_undefined(value)
|
240
|
-
if
|
240
|
+
if Kind::Undefined == value
|
241
241
|
raise Kind::Error.new('Lambda'.freeze, Kind::Undefined)
|
242
242
|
else
|
243
243
|
yield
|
@@ -258,7 +258,7 @@ module Kind
|
|
258
258
|
def self.Callable(object = Undefined, options = Empty::HASH)
|
259
259
|
default = options[:or]
|
260
260
|
|
261
|
-
return Kind::Of::Callable if
|
261
|
+
return Kind::Of::Callable if Undefined == object && default.nil?
|
262
262
|
|
263
263
|
callable = object || default
|
264
264
|
|
@@ -282,14 +282,14 @@ module Kind
|
|
282
282
|
if ::Kind::Maybe::Value.none?(default)
|
283
283
|
__kind_undefined(value) { Kind::Of::Callable(value) }
|
284
284
|
else
|
285
|
-
return value if
|
285
|
+
return value if Kind::Undefined != value && instance?(value)
|
286
286
|
|
287
287
|
__kind_undefined(default) { Kind::Of::Callable(default) }
|
288
288
|
end
|
289
289
|
end
|
290
290
|
|
291
291
|
def self.__kind_undefined(value)
|
292
|
-
if
|
292
|
+
if Kind::Undefined == value
|
293
293
|
raise Kind::Error.new('Callable'.freeze, Kind::Undefined)
|
294
294
|
else
|
295
295
|
yield
|
@@ -53,12 +53,12 @@ class KindValidator < ActiveModel::EachValidator
|
|
53
53
|
def kind_is_not(expected, value)
|
54
54
|
case expected
|
55
55
|
when Class
|
56
|
-
return if Kind.of.Class(value)
|
56
|
+
return if expected == Kind.of.Class(value) || value < expected
|
57
57
|
|
58
58
|
"must be the class or a subclass of `#{expected.name}`"
|
59
59
|
when Module
|
60
60
|
return if value.kind_of?(Class) && value <= expected
|
61
|
-
return if Kind.of.Module(value)
|
61
|
+
return if expected == Kind.of.Module(value) || value.kind_of?(expected)
|
62
62
|
|
63
63
|
"must include the `#{expected.name}` module"
|
64
64
|
else
|
data/lib/kind/checker.rb
CHANGED
@@ -11,7 +11,7 @@ module Kind
|
|
11
11
|
|
12
12
|
return Kind::Of.(__kind, value) if ::Kind::Maybe::Value.none?(default)
|
13
13
|
|
14
|
-
|
14
|
+
Kind::Undefined != value && instance?(value) ? value : Kind::Of.(__kind, default)
|
15
15
|
end
|
16
16
|
|
17
17
|
def [](value, options = options = Empty::HASH)
|
@@ -38,7 +38,7 @@ module Kind
|
|
38
38
|
return args.all? { |object| __is_instance__(object) } if args.size > 1
|
39
39
|
|
40
40
|
arg = args[0]
|
41
|
-
|
41
|
+
Kind::Undefined == arg ? is_instance_to_proc : __is_instance__(arg)
|
42
42
|
end
|
43
43
|
|
44
44
|
def or_nil(value)
|
@@ -59,7 +59,7 @@ module Kind
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def as_maybe(value = Kind::Undefined)
|
62
|
-
return __as_maybe__(value) if
|
62
|
+
return __as_maybe__(value) if Kind::Undefined != value
|
63
63
|
|
64
64
|
as_maybe_to_proc
|
65
65
|
end
|
data/lib/kind/error.rb
CHANGED
@@ -7,7 +7,7 @@ module Kind
|
|
7
7
|
private_constant :UNDEFINED_OBJECT
|
8
8
|
|
9
9
|
def initialize(arg, object = UNDEFINED_OBJECT)
|
10
|
-
if
|
10
|
+
if UNDEFINED_OBJECT == object
|
11
11
|
# Will be used when the exception was raised with a message. e.g:
|
12
12
|
# raise Kind::Error, "some message"
|
13
13
|
super(arg)
|
data/lib/kind/maybe.rb
CHANGED
@@ -4,7 +4,7 @@ module Kind
|
|
4
4
|
module Maybe
|
5
5
|
module Value
|
6
6
|
def self.none?(value)
|
7
|
-
value
|
7
|
+
value.nil? || Undefined == value
|
8
8
|
end
|
9
9
|
|
10
10
|
def self.some?(value)
|
@@ -42,9 +42,9 @@ module Kind
|
|
42
42
|
INVALID_DEFAULT_ARG = 'the default value must be defined as an argument or block'.freeze
|
43
43
|
|
44
44
|
def value_or(default = Undefined, &block)
|
45
|
-
raise ArgumentError, INVALID_DEFAULT_ARG if
|
45
|
+
raise ArgumentError, INVALID_DEFAULT_ARG if Undefined == default && !block
|
46
46
|
|
47
|
-
|
47
|
+
Undefined != default ? default : block.call
|
48
48
|
end
|
49
49
|
|
50
50
|
def none?; true; end
|
@@ -56,7 +56,7 @@ module Kind
|
|
56
56
|
alias_method :then, :map
|
57
57
|
|
58
58
|
def try(method_name = Undefined, &block)
|
59
|
-
Kind.of.Symbol(method_name) if
|
59
|
+
Kind.of.Symbol(method_name) if Undefined != method_name
|
60
60
|
|
61
61
|
nil
|
62
62
|
end
|
@@ -80,8 +80,8 @@ module Kind
|
|
80
80
|
result = fn.call(@value)
|
81
81
|
|
82
82
|
return result if Maybe::None === result
|
83
|
-
return NONE_WITH_NIL_VALUE if result
|
84
|
-
return NONE_WITH_UNDEFINED_VALUE if
|
83
|
+
return NONE_WITH_NIL_VALUE if result.nil?
|
84
|
+
return NONE_WITH_UNDEFINED_VALUE if Undefined == result
|
85
85
|
|
86
86
|
Some.new(result)
|
87
87
|
end
|
@@ -89,7 +89,7 @@ module Kind
|
|
89
89
|
alias_method :then, :map
|
90
90
|
|
91
91
|
def try(method_name = Undefined, *args, &block)
|
92
|
-
fn =
|
92
|
+
fn = Undefined == method_name ? block : Kind.of.Symbol(method_name).to_proc
|
93
93
|
|
94
94
|
result = args.empty? ? fn.call(value) : fn.call(*args.unshift(value))
|
95
95
|
|
data/lib/kind/types.rb
CHANGED
@@ -10,7 +10,7 @@ module Kind
|
|
10
10
|
def self.%{method_name}(object = Undefined, options = Empty::HASH)
|
11
11
|
default = options[:or]
|
12
12
|
|
13
|
-
return Kind::Of::%{kind_name} if
|
13
|
+
return Kind::Of::%{kind_name} if Undefined == object && default.nil?
|
14
14
|
|
15
15
|
is_instance = Kind::Of::%{kind_name}.__is_instance__(object)
|
16
16
|
|
@@ -28,7 +28,7 @@ module Kind
|
|
28
28
|
|
29
29
|
KIND_IS = <<-RUBY
|
30
30
|
def self.%{method_name}(value = Undefined)
|
31
|
-
return Kind::Is::%{kind_name} if
|
31
|
+
return Kind::Is::%{kind_name} if Undefined == value
|
32
32
|
|
33
33
|
Kind::Is.__call__(::%{kind_name_to_check}, value)
|
34
34
|
end
|
data/lib/kind/undefined.rb
CHANGED
data/lib/kind/version.rb
CHANGED
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: 2.
|
4
|
+
version: 2.2.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-
|
11
|
+
date: 2020-06-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:
|