kind 3.0.1 → 3.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 31c64b5797c2bc7b2b1da5a704af8f66ddd34773296a8f5b70fc92ffd8b66246
4
- data.tar.gz: ceac47580bc50b6f7b346193ec2c8d9429c7e26726219ee45ea8a5b56051a8e0
3
+ metadata.gz: 7b62da87ad8443fb4d3f1d96535bc69259addf767721db70288401d677733967
4
+ data.tar.gz: 995f0a3a34ed67a3244e181380d627e076d4576a2b6e0c7de2b34fa415c5f868
5
5
  SHA512:
6
- metadata.gz: b94da43b377655485792594548f3a8d2e321ce313cd88ef6ff7b9bca1fba2411a602eaba99b2fa6be0d28e4054242ca0bc19c51df8ea7c08898455a09c0b345a
7
- data.tar.gz: c1ac05bf6246d5a9f10f80bdec7adab1c62b87bc40bd0d9e57b9532e5de2c8598bf97de1f12d062d31e494543a87b4b68410c2581adb9ddbbf12088d2e100427
6
+ metadata.gz: 3398bbf2b67fe8b81023d9c781b14ac115f5749f45641a74fc1ff1c8d05f4fd1c4e2a4bc817d6c71e7f8dc96b245ec9f9c80a776ae11d22ba69dbc878dfaa847
7
+ data.tar.gz: 75c6c1e387548447edf601d4b73b18ff3e2700debf3f6715b2f772f582829d39a72e7bb9d8af61fe8bcd32e9f72aa8398f1703f2c706668a0ab5e59fc0612b05
data/README.md CHANGED
@@ -49,6 +49,7 @@ One of the goals of this project is to do simple type checking like `"some strin
49
49
  - [Kind::Maybe(<Type>)](#kindmaybetype)
50
50
  - [Kind::Maybe#try](#kindmaybetry)
51
51
  - [Kind::Maybe#try!](#kindmaybetry-1)
52
+ - [Kind::Maybe#dig](#kindmaybedig)
52
53
  - [Kind::Empty](#kindempty)
53
54
  - [Similar Projects](#similar-projects)
54
55
  - [Development](#development)
@@ -458,6 +459,7 @@ The list of types (classes and modules) available to use with `Kind.of.*` or `Ki
458
459
  - `Kind.of.Range`
459
460
  - `Kind.of.Hash`
460
461
  - `Kind.of.Struct`
462
+ - `Kind.of.OpenStruct`
461
463
  - `Kind.of.Enumerator`
462
464
  - `Kind.of.Set`
463
465
  - `Kind.of.Method`
@@ -1090,6 +1092,71 @@ Kind::Maybe[{}].try!(:upcase) # => NoMethodError (undefined method `upcase' for
1090
1092
 
1091
1093
  [⬆️ Back to Top](#table-of-contents-)
1092
1094
 
1095
+ ### Kind::Maybe#dig
1096
+
1097
+ Has the same behavior of Ruby dig methods ([Hash](https://ruby-doc.org/core-2.3.0/Hash.html#method-i-dig), [Array](https://ruby-doc.org/core-2.3.0/Array.html#method-i-dig), [Struct](https://ruby-doc.org/core-2.3.0/Struct.html#method-i-dig), [OpenStruct](https://ruby-doc.org/stdlib-2.3.0/libdoc/ostruct/rdoc/OpenStruct.html#method-i-dig)), but it will not raise an error if some value can't be digged.
1098
+
1099
+ ```ruby
1100
+ [nil, 1, '', /x/].each do |value|
1101
+ p Kind::Maybe[value].dig(:foo).value # nil
1102
+ end
1103
+
1104
+ # --
1105
+
1106
+ a = [1, 2, 3]
1107
+
1108
+ Kind::Maybe[a].dig(0).value # 1
1109
+
1110
+ Kind::Maybe[a].dig(3).value # nil
1111
+
1112
+ # --
1113
+
1114
+ h = { foo: {bar: {baz: 1}}}
1115
+
1116
+ Kind::Maybe[h].dig(:foo).value # {bar: {baz: 1}}
1117
+ Kind::Maybe[h].dig(:foo, :bar).value # {baz: 1}
1118
+ Kind::Maybe[h].dig(:foo, :bar, :baz).value # 1
1119
+
1120
+ Kind::Maybe[h].dig(:foo, :bar, 'baz').value # nil
1121
+
1122
+ # --
1123
+
1124
+ i = { foo: [{'bar' => [1, 2]}, {baz: [3, 4]}] }
1125
+
1126
+ Kind::Maybe[i].dig(:foo, 0, 'bar', 0).value # 1
1127
+ Kind::Maybe[i].dig(:foo, 0, 'bar', 1).value # 2
1128
+ Kind::Maybe[i].dig(:foo, 0, 'bar', -1).value # 2
1129
+
1130
+ Kind::Maybe[i].dig(:foo, 0, 'bar', 2).value # nil
1131
+
1132
+ # --
1133
+
1134
+ s = Struct.new(:a, :b).new(101, 102)
1135
+ o = OpenStruct.new(c: 103, d: 104)
1136
+ b = { struct: s, ostruct: o, data: [s, o]}
1137
+
1138
+ Kind::Maybe[s].dig(:a).value # 101
1139
+ Kind::Maybe[b].dig(:struct, :b).value # 102
1140
+ Kind::Maybe[b].dig(:data, 0, :b).value # 102
1141
+ Kind::Maybe[b].dig(:data, 0, 'b').value # 102
1142
+
1143
+ Kind::Maybe[o].dig(:c).value # 103
1144
+ Kind::Maybe[b].dig(:ostruct, :d).value # 104
1145
+ Kind::Maybe[b].dig(:data, 1, :d).value # 104
1146
+ Kind::Maybe[b].dig(:data, 1, 'd').value # 104
1147
+
1148
+ Kind::Maybe[s].dig(:f).value # nil
1149
+ Kind::Maybe[o].dig(:f).value # nil
1150
+ Kind::Maybe[b].dig(:struct, :f).value # nil
1151
+ Kind::Maybe[b].dig(:ostruct, :f).value # nil
1152
+ Kind::Maybe[b].dig(:data, 0, :f).value # nil
1153
+ Kind::Maybe[b].dig(:data, 1, :f).value # nil
1154
+ ```
1155
+
1156
+ > **Note:** You can also use the `#dig` method with `Kind::Optional` objects.
1157
+
1158
+ [⬆️ Back to Top](#table-of-contents-)
1159
+
1093
1160
  ## Kind::Empty
1094
1161
 
1095
1162
  When you define a method that has default arguments, for certain data types, you will always create a new object in memory. e.g:
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'kind/version'
4
4
 
5
+ require 'ostruct'
6
+
5
7
  require 'kind/empty'
6
8
  require 'kind/undefined'
7
9
  require 'kind/checker'
@@ -294,7 +296,7 @@ module Kind
294
296
  # -- Classes
295
297
  [
296
298
  String, Symbol, Numeric, Integer, Float, Regexp, Time,
297
- Array, Range, Hash, Struct, Enumerator, Set,
299
+ Array, Range, Hash, Struct, Enumerator, Set, OpenStruct,
298
300
  Method, Proc,
299
301
  IO, File
300
302
  ].each { |klass| Types.add(klass) }
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module Dig
5
+ extend self
6
+
7
+ def call(data, keys)
8
+ return unless keys.is_a?(Array)
9
+
10
+ keys.reduce(data) do |memo, key|
11
+ value = get(memo, key)
12
+
13
+ break if value.nil?
14
+
15
+ value
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def get(data, key)
22
+ return data[key] if Hash === data
23
+
24
+ case data
25
+ when Array
26
+ data[key] if key.respond_to?(:to_int)
27
+ when OpenStruct
28
+ data[key] if key.respond_to?(:to_sym)
29
+ when Struct
30
+ if key.respond_to?(:to_int) || key.respond_to?(:to_sym)
31
+ data[key] rescue nil
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'kind/dig'
4
+
3
5
  module Kind
4
6
  module Maybe
5
7
  class Typed
@@ -76,6 +78,10 @@ module Kind
76
78
 
77
79
  alias_method :try, :try!
78
80
 
81
+ def dig(*keys)
82
+ NONE_WITH_NIL_VALUE
83
+ end
84
+
79
85
  private_constant :INVALID_DEFAULT_ARG
80
86
  end
81
87
 
@@ -114,6 +120,10 @@ module Kind
114
120
  end
115
121
  end
116
122
 
123
+ def dig(*keys)
124
+ resolve(Kind::Dig.call(value, keys))
125
+ end
126
+
117
127
  private
118
128
 
119
129
  def __try__(method_name = Undefined, args, block)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kind
4
- VERSION = '3.0.1'
4
+ VERSION = '3.1.0'
5
5
  end
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.1
4
+ version: 3.1.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: 2020-07-08 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:
@@ -34,6 +34,7 @@ files:
34
34
  - lib/kind/checker.rb
35
35
  - lib/kind/checker/factory.rb
36
36
  - lib/kind/checker/protocol.rb
37
+ - lib/kind/dig.rb
37
38
  - lib/kind/empty.rb
38
39
  - lib/kind/error.rb
39
40
  - lib/kind/is.rb