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.
- checksums.yaml +4 -4
- data/lib/typ.rb +198 -127
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3292265f2d79043b1324f8221a43926863cb039233c48d5d989109fd712a9141
|
4
|
+
data.tar.gz: d81287849ec606b02f4710dcc9d86c822ad5f162fda839c23c5a84225fa91718
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
100
|
+
fails.empty?
|
33
101
|
end
|
34
102
|
|
35
103
|
module DSL
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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
|
83
|
-
|
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
|
-
|
92
|
-
|
93
|
-
|
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
|
103
|
-
gate.
|
139
|
+
def gate
|
140
|
+
@gate ||= Typ::Gate.new
|
104
141
|
end
|
105
142
|
|
106
|
-
|
107
|
-
attr_accessor :check
|
143
|
+
def make
|
108
144
|
end
|
109
145
|
|
110
|
-
|
111
|
-
|
112
|
-
end
|
146
|
+
include TestFor
|
147
|
+
include CheckMethod
|
113
148
|
|
114
|
-
|
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
|
-
|
124
|
-
|
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
|
131
|
-
|
165
|
+
def is_a literal
|
166
|
+
gates << IsA.new(__method__, literal).gate
|
132
167
|
end
|
133
168
|
|
134
|
-
|
135
|
-
|
169
|
+
def its name, literal
|
170
|
+
gates << Its.new(__method__, literal, name: name).gate
|
136
171
|
end
|
137
172
|
|
138
|
-
|
173
|
+
def key name, literal
|
174
|
+
gates << Key.new(__method__, literal, name: name).gate
|
175
|
+
end
|
139
176
|
|
140
|
-
class
|
141
|
-
def
|
142
|
-
|
143
|
-
|
144
|
-
|
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
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
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
|
-
|
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
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
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
|
-
|
189
|
-
|
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.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Anatoly
|
7
|
+
- Anatoly Chernov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
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
|
-
|
39
|
-
rubygems_version: 2.7.6
|
39
|
+
rubygems_version: 3.4.15
|
40
40
|
signing_key:
|
41
41
|
specification_version: 4
|
42
|
-
summary:
|
42
|
+
summary: To type Ruby objects.
|
43
43
|
test_files: []
|