typ 0.0.6 → 0.1.0

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