typ 0.0.6 → 0.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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/typ.rb +162 -128
  3. metadata +7 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a726dc4e0d96b4f5bdad9858d10063bf818af3e5bd1293135acffa040bbde236
4
- data.tar.gz: fbc8d499fb78954604a757593e2e46a9e2af7f5fba4102783d6011aa991a10f3
3
+ metadata.gz: a3d4190e37bd4aadc5b0d529256c441835cdf9f3673cbdb23a1d0b2e583926a7
4
+ data.tar.gz: edc5160b73a35c92c08d27ea5a13998f37e37f47838f4f986dc4c81d69045b72
5
5
  SHA512:
6
- metadata.gz: 2d3679f431008960d32befdaea22720e3a3cf49692c7a81f19463476b8cae6d67c8069d3920c1325a3c68d743058a348f2087295219f75bde0261bb780b95cdd
7
- data.tar.gz: 20af3243c88900e428928f2c770cb661ee69835187fb0834f55d7be701ab3cfbf0f848b2a854f8998e42cd85291c4551da5b6eaf7ceb7946d63f71aadc823bfb
6
+ metadata.gz: 2994b127d25415c59392d1561c7b067bb578a1fc62c4e3936e0c74184222c40621af22003e2fd901ef17671d93eb2db2015eafd34f7450ece569f36066ebf615
7
+ data.tar.gz: 26a90c3294320ee43b78b2c1a4c8ad9939060910b3d5265b400a30889c7e8bff6dd67e1955fb888ad0e41fd0c48e6602ecca62c39b3e4fbbdbfa189e08014230
data/lib/typ.rb CHANGED
@@ -1,15 +1,45 @@
1
1
  module Typ
2
2
  module Gate
3
- attr_reader :it
3
+ module DSLReaders
4
+ def dsl_method
5
+ self.class.dsl_method
6
+ end
7
+
8
+ def dsl_literal
9
+ self.class.dsl_literal
10
+ end
11
+ end
12
+
13
+ module New
14
+ def new
15
+ c = Class.new
16
+ c.include Gate
17
+ c.extend Singleton
18
+ c
19
+ end
20
+
21
+ end
22
+
23
+ module Singleton
24
+ attr_accessor :dsl_method, :dsl_literal
25
+ end
26
+
27
+ extend New
28
+ include DSLReaders
29
+
30
+ attr_reader :it, :error
4
31
 
5
32
  def initialize it
6
33
  @it = it
7
- check
34
+ @ok = begin
35
+ check
36
+ rescue => e
37
+ @error = e
38
+ false
39
+ end
8
40
  end
9
41
 
10
- # Should set @ok to be true or false
11
42
  def check
12
- @ok = self.class.check === it
13
43
  end
14
44
 
15
45
  def ok?
@@ -19,7 +49,7 @@ module Typ
19
49
 
20
50
  def self.included mod
21
51
  mod.extend DSL
22
- mod.extend PatternMatching
52
+ mod.extend Singleton
23
53
  end
24
54
 
25
55
  include Gate
@@ -29,165 +59,169 @@ module Typ
29
59
  def check
30
60
  @gates = self.class.gates.map { |gate| gate.new it }
31
61
  @fails = gates.reject &:ok?
32
- @ok = fails.empty?
62
+ fails.empty?
33
63
  end
34
64
 
35
65
  module DSL
36
- def gates
37
- @gates ||= []
38
- end
39
-
40
- def is type
41
- case type
42
- when Array
43
- gates << Is::Array.new(type)
44
- when Class
45
- if type.include? Typ
46
- gates << type
47
- else
48
- fail "don't know how to create a Gate from #{type}"
66
+ class Gate
67
+ module CheckMethod
68
+ def augment_gate_with_check test
69
+ check = Module.new do
70
+ define_method :check do
71
+ test[it]
72
+ end
73
+ end
74
+
75
+ gate.include check
49
76
  end
50
- else
51
- fail "don't know how to create a Gate from #{type}"
52
77
  end
53
- end
54
78
 
55
- def is_a type, params = {}
56
- case type
57
- when Module
58
- gates << IsA.new(type, params)
59
- else
60
- fail "don't know how to create a Gate from #{type}"
61
- end
62
- end
63
- end
64
-
65
- module Is
66
-
67
- module Array
68
- class Check
69
- def initialize array
70
- @array = array
71
- @check = if array[0].is_a?(Symbol)
72
- method, *arguments = array
73
- -> it { it.send method, *arguments }
74
- elsif array[1].is_a?(Symbol)
75
- receiver, method = array
76
- -> it { receiver.send method, it }
77
- else
78
- fail "not sure how to handle #{array} yet"
79
+ module TestFor
80
+ def test_for type
81
+ case type
82
+ when Symbol
83
+ -> it { it.send type or bad_assertion(it, type) }
84
+ when Array
85
+ cannot_create_gate type unless type.size == 2
86
+ unless type[0].is_a?(Symbol) || type[1].is_a?(Symbol)
87
+ cannot_create_gate type
88
+ end
89
+
90
+ if type[0].is_a? Symbol
91
+ method, argument = type
92
+ -> it { it.send method, argument or bad_assertion(it, type) }
93
+ else
94
+ receiver, method = type
95
+ -> it { receiver.send method, it or bad_assertion(it, type) }
96
+ end
97
+ when Class
98
+ type if type.include? Typ
79
99
  end
80
100
  end
81
-
82
- def === it
83
- @check === it
101
+
102
+ def cannot_create_gate type
103
+ fail Typ::Error::CannotCreateGate.new(type)
84
104
  end
85
-
86
- def to_a
87
- @array
105
+
106
+ def bad_assertion it, name
107
+ fail Typ::Error::BadAssertion.new(it, name)
88
108
  end
89
109
  end
90
-
91
- class << self
92
- def new array
93
- check = Check.new array
94
-
95
- gate = Class.new
96
- gate.include self
97
- gate.check = check
98
- gate
99
- end
110
+
111
+ def initialize method, literal, **kwargs
112
+ @method, @literal, @kwargs = method, literal, kwargs
113
+ make
100
114
  end
101
115
 
102
- def self.included gate
103
- gate.extend Singleton
116
+ def gate
117
+ @gate ||= Typ::Gate.new
104
118
  end
105
119
 
106
- module Singleton
107
- attr_accessor :check
120
+ def make
108
121
  end
109
122
 
110
- def to_a
111
- self.class.check.to_a
112
- end
123
+ include TestFor
124
+ include CheckMethod
113
125
 
114
- include Gate
126
+ def enrich_gate
127
+ augment_gate_with_check @test
128
+ gate.dsl_method = @method
129
+ gate.dsl_literal = @literal
130
+ end
131
+ end
132
+
133
+ def gates
134
+ @gates ||= []
115
135
  end
116
- end
117
-
118
- module IsA
119
- class << self
120
- def new type, params = {}
121
- type = Type.new type, params
122
136
 
123
- gate = Class.new
124
- gate.include self
125
- gate.check = type
126
- gate
127
- end
137
+ def is literal
138
+ gates << Is.new(__method__, literal).gate
128
139
  end
129
140
 
130
- def self.included gate
131
- gate.extend Singleton
141
+ def is_a literal
142
+ gates << IsA.new(__method__, literal).gate
132
143
  end
133
144
 
134
- module Singleton
135
- attr_accessor :check
145
+ def its name, literal
146
+ gates << Its.new(__method__, literal, name: name).gate
136
147
  end
137
148
 
138
- include Gate
149
+ def key name, literal
150
+ gates << Key.new(__method__, literal, name: name).gate
151
+ end
139
152
 
140
- class Type
141
- def initialize type, params = {}
142
- @type, @params = type, params
143
-
144
- @param = params[:of]
145
-
146
- @check = if @params.empty?
147
- -> it { it.is_a? @type }
148
- else
149
- if @param
150
- check_Array
151
- else
152
- check_Hash
153
- end
154
- end
155
- end
156
-
157
- def === it
158
- @check === it
153
+ class FetchGate < Gate
154
+ def make
155
+ type_check = test_for @literal
156
+ @test = fetch_check >> type_check
157
+ enrich_gate
159
158
  end
159
+ end
160
+
161
+ class Is < Gate
162
+ def make
163
+ @test = test_for @literal
160
164
 
161
- def to_s
162
- if @params.empty?
163
- @type.to_s
165
+ if @test
166
+ if Class === @literal
167
+ @gate = @literal
168
+ else
169
+ enrich_gate
170
+ end
164
171
  else
165
- "#{@type}, #{@params}"
172
+ cannot_create_gate @literal
166
173
  end
167
174
  end
168
-
169
- private
170
- def check_Array
171
- -> it {
172
- it.is_a?(@type) &&
173
- it.all? { |element| element.is_a? @param }
174
- }
175
- end
176
-
177
- def check_Hash
178
- key_type, value_type = @params.first
179
- -> it {
180
- it.is_a?(@type) &&
181
- it.keys.all? {|k| k.is_a? key_type } &&
182
- it.values.all? {|v| v.is_a? value_type }
183
- }
184
- end
175
+ end
176
+
177
+ class IsA < Gate
178
+ def make
179
+ @test = test_for [:is_a?, @literal]
180
+ enrich_gate
181
+ end
182
+ end
183
+
184
+ class Its < FetchGate
185
+ def fetch_check
186
+ @fetch_check ||= begin
187
+ name = @kwargs[:name]
188
+ -> it { it.send name }
189
+ end
190
+ end
191
+ end
192
+
193
+ class Key < FetchGate
194
+ def fetch_check
195
+ @fetch_check ||= begin
196
+ name = @kwargs[:name]
197
+ -> it { it[name] }
198
+ end
199
+ end
185
200
  end
186
201
  end
187
202
 
188
- module PatternMatching
189
- def === it
203
+ class Error < StandardError
204
+
205
+ class BadAssertion < self
206
+ def initialize it, method_name
207
+ message = "#{it} is #{method_name}"
208
+ super message
209
+ end
210
+ end
211
+
212
+ class CannotCreateGate < self
213
+ def initialize object
214
+ message = "Don't know how to create a gate from #{object.inspect}:#{object.class}."
215
+ super message
216
+ end
217
+ end
218
+ end
219
+
220
+ module Singleton
221
+ def call it
190
222
  new(it).ok?
191
223
  end
224
+
225
+ alias_method :===, :call
192
226
  end
193
227
  end
metadata CHANGED
@@ -1,17 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: typ
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
- - Anatoly Chernow
7
+ - Anatoly Chernov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-03 00:00:00.000000000 Z
11
+ date: 2023-08-01 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
- email:
14
+ email:
15
+ - chertoly@gmail.com
15
16
  executables: []
16
17
  extensions: []
17
18
  extra_rdoc_files: []
@@ -35,9 +36,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
35
36
  - !ruby/object:Gem::Version
36
37
  version: '0'
37
38
  requirements: []
38
- rubyforge_project:
39
- rubygems_version: 2.7.6
39
+ rubygems_version: 3.4.15
40
40
  signing_key:
41
41
  specification_version: 4
42
- summary: A tool for defining and enforcing types of Ruby objects.
42
+ summary: To type Ruby objects.
43
43
  test_files: []