typ 0.0.6 → 0.1.1

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 +198 -127
  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: 3292265f2d79043b1324f8221a43926863cb039233c48d5d989109fd712a9141
4
+ data.tar.gz: d81287849ec606b02f4710dcc9d86c822ad5f162fda839c23c5a84225fa91718
5
5
  SHA512:
6
- metadata.gz: 2d3679f431008960d32befdaea22720e3a3cf49692c7a81f19463476b8cae6d67c8069d3920c1325a3c68d743058a348f2087295219f75bde0261bb780b95cdd
7
- data.tar.gz: 20af3243c88900e428928f2c770cb661ee69835187fb0834f55d7be701ab3cfbf0f848b2a854f8998e42cd85291c4551da5b6eaf7ceb7946d63f71aadc823bfb
6
+ metadata.gz: 4f6fa03315316cf839a3560dfb10197879d673a88c42823ed55a8e4daecd3c66f09a3393fc33b9b240ef9fb9a142a617a46bf03d62ead3dc5b6de662d1b53495
7
+ data.tar.gz: eba82e7d4741e2f1b489f383b4ea0423b24348a218a1e858291e7855e472b3c07c9440bd84769bd63ff8e74f88a113ebbee19ce3ebee8eddbcbf65bddfede41f
data/lib/typ.rb CHANGED
@@ -1,15 +1,80 @@
1
1
  module Typ
2
+ module ArrayPredicate
3
+ refine Array do
4
+ def predicate?
5
+ (size == 2) &&
6
+ (self[0].is_a?(Symbol) || self[1].is_a?(Symbol))
7
+ end
8
+ end
9
+ end
10
+
11
+ module ArrayToTest
12
+ refine Object do
13
+ def bad_assertion it, name
14
+ fail Typ::Error::BadAssertion.new(it, name)
15
+ end
16
+ end
17
+
18
+ refine Array do
19
+ def to_test
20
+ type = self
21
+
22
+ if type[0].is_a? Symbol
23
+ method, argument = type
24
+ -> it { it.send method, argument or bad_assertion(it, type) }
25
+ else
26
+ receiver, method = type
27
+ -> it { receiver.send method, it or bad_assertion(it, type) }
28
+ end
29
+ end
30
+ end
31
+ end
32
+
2
33
  module Gate
3
- attr_reader :it
34
+ module DSLReaders
35
+ def dsl_method
36
+ self.class.dsl_method
37
+ end
38
+
39
+ def dsl_literal
40
+ self.class.dsl_literal
41
+ end
42
+
43
+ def dsl_key
44
+ self.class.dsl_key
45
+ end
46
+ end
47
+
48
+ module New
49
+ def new
50
+ c = Class.new
51
+ c.include Gate
52
+ c.extend Singleton
53
+ c
54
+ end
55
+
56
+ end
57
+
58
+ module Singleton
59
+ attr_accessor :dsl_method, :dsl_literal, :dsl_key
60
+ end
61
+
62
+ extend New
63
+ include DSLReaders
64
+
65
+ attr_reader :it, :error
4
66
 
5
67
  def initialize it
6
68
  @it = it
7
- check
69
+ @ok = begin
70
+ check
71
+ rescue => e
72
+ @error = e
73
+ false
74
+ end
8
75
  end
9
76
 
10
- # Should set @ok to be true or false
11
77
  def check
12
- @ok = self.class.check === it
13
78
  end
14
79
 
15
80
  def ok?
@@ -17,9 +82,12 @@ module Typ
17
82
  end
18
83
  end
19
84
 
85
+ using ArrayPredicate
86
+ using ArrayToTest
87
+
20
88
  def self.included mod
21
89
  mod.extend DSL
22
- mod.extend PatternMatching
90
+ mod.extend Singleton
23
91
  end
24
92
 
25
93
  include Gate
@@ -29,165 +97,168 @@ module Typ
29
97
  def check
30
98
  @gates = self.class.gates.map { |gate| gate.new it }
31
99
  @fails = gates.reject &:ok?
32
- @ok = fails.empty?
100
+ fails.empty?
33
101
  end
34
102
 
35
103
  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}"
104
+ class Gate
105
+ module CheckMethod
106
+ def augment_gate_with_check test
107
+ check = Module.new do
108
+ define_method :check do
109
+ test[it]
110
+ end
111
+ end
112
+
113
+ gate.include check
49
114
  end
50
- else
51
- fail "don't know how to create a Gate from #{type}"
52
115
  end
53
- end
54
116
 
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"
117
+ module TestFor
118
+ def test_for type
119
+ case type
120
+ when Symbol
121
+ -> it { it.send type or bad_assertion(it, type) }
122
+ when Array
123
+ type.predicate? ? type.to_test : (cannot_create_gate type)
124
+ when Class
125
+ type if type.include? Typ
79
126
  end
80
127
  end
81
-
82
- def === it
83
- @check === it
84
- end
85
-
86
- def to_a
87
- @array
128
+
129
+ def cannot_create_gate type
130
+ fail Typ::Error::CannotCreateGate.new(type)
88
131
  end
89
132
  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
133
+
134
+ def initialize method, literal, **kwargs
135
+ @method, @literal, @kwargs = method, literal, kwargs
136
+ make
100
137
  end
101
138
 
102
- def self.included gate
103
- gate.extend Singleton
139
+ def gate
140
+ @gate ||= Typ::Gate.new
104
141
  end
105
142
 
106
- module Singleton
107
- attr_accessor :check
143
+ def make
108
144
  end
109
145
 
110
- def to_a
111
- self.class.check.to_a
112
- end
146
+ include TestFor
147
+ include CheckMethod
113
148
 
114
- include Gate
149
+ def enrich_gate
150
+ augment_gate_with_check @test
151
+ gate.dsl_method = @method
152
+ gate.dsl_literal = @literal
153
+ gate.dsl_key = @kwargs[:name]
154
+ end
155
+ end
156
+
157
+ def gates
158
+ @gates ||= []
115
159
  end
116
- end
117
-
118
- module IsA
119
- class << self
120
- def new type, params = {}
121
- type = Type.new type, params
122
160
 
123
- gate = Class.new
124
- gate.include self
125
- gate.check = type
126
- gate
127
- end
161
+ def is literal
162
+ gates << Is.new(__method__, literal).gate
128
163
  end
129
164
 
130
- def self.included gate
131
- gate.extend Singleton
165
+ def is_a literal
166
+ gates << IsA.new(__method__, literal).gate
132
167
  end
133
168
 
134
- module Singleton
135
- attr_accessor :check
169
+ def its name, literal
170
+ gates << Its.new(__method__, literal, name: name).gate
136
171
  end
137
172
 
138
- include Gate
173
+ def key name, literal
174
+ gates << Key.new(__method__, literal, name: name).gate
175
+ end
139
176
 
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
177
+ class FetchGate < Gate
178
+ def make
179
+ type_check = test_for @literal
180
+ @test = fetch_check >> type_check
181
+ enrich_gate
155
182
  end
156
183
 
157
- def === it
158
- @check === it
159
- end
160
-
161
- def to_s
162
- if @params.empty?
163
- @type.to_s
184
+ def test_for literal
185
+ case literal
186
+ when Symbol
187
+ literal.end_with?(??) ? super : (super [:eql?, literal])
188
+ when Array
189
+ literal.predicate? ? literal.to_test : (super [:eql?, literal])
190
+ when Class
191
+ literal.include?(Typ) ? super : (super [:eql?, literal])
164
192
  else
165
- "#{@type}, #{@params}"
193
+ super [:eql?, literal]
166
194
  end
167
195
  end
196
+ end
197
+
198
+ class Is < Gate
199
+ def make
200
+ @test = test_for @literal
168
201
 
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
- }
202
+ if @test
203
+ if Class === @literal
204
+ @gate = @literal
205
+ else
206
+ enrich_gate
207
+ end
208
+ else
209
+ cannot_create_gate @literal
184
210
  end
211
+ end
212
+ end
213
+
214
+ class IsA < Gate
215
+ def make
216
+ @test = test_for [:is_a?, @literal]
217
+ enrich_gate
218
+ end
219
+ end
220
+
221
+ class Its < FetchGate
222
+ def fetch_check
223
+ @fetch_check ||= begin
224
+ name = @kwargs[:name]
225
+ -> it { it.send name }
226
+ end
227
+ end
228
+ end
229
+
230
+ class Key < FetchGate
231
+ def fetch_check
232
+ @fetch_check ||= begin
233
+ name = @kwargs[:name]
234
+ -> it { it[name] }
235
+ end
236
+ end
185
237
  end
186
238
  end
187
239
 
188
- module PatternMatching
189
- def === it
240
+ class Error < StandardError
241
+
242
+ class BadAssertion < self
243
+ def initialize it, method_name
244
+ message = "#{it.inspect} is #{method_name}"
245
+ super message
246
+ end
247
+ end
248
+
249
+ class CannotCreateGate < self
250
+ def initialize object
251
+ message = "Don't know how to create a gate from #{object.inspect}:#{object.class}."
252
+ super message
253
+ end
254
+ end
255
+ end
256
+
257
+ module Singleton
258
+ def call it
190
259
  new(it).ok?
191
260
  end
261
+
262
+ alias_method :===, :call
192
263
  end
193
264
  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.1
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-07 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: []