type_struct 0.3.0 → 0.4.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 +4 -4
- data/README.md +12 -6
- data/lib/type_struct.rb +68 -66
- data/lib/type_struct/array_of_test.rb +2 -2
- data/lib/type_struct/ext.rb +37 -8
- data/lib/type_struct/hash_of_test.rb +2 -2
- data/lib/type_struct/union.rb +15 -8
- data/lib/type_struct/union_test.rb +1 -1
- data/lib/type_struct/version.rb +1 -1
- data/lib/type_struct_test.rb +20 -15
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7cb90a5e3baaac22f77fc721160e434f7d79a4fe
|
4
|
+
data.tar.gz: 5db1cae7790e5cc16b89f9d17a386e33958ad88f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0caefd5bf92dc35fc51774741a110b8a712a97ee333a7f7fd170b0a3e90675fe02050570cb2fc452865a92985fbe8b3189dcfa3c91d473f413935e55c4e267d2
|
7
|
+
data.tar.gz: 3d88d07143f6455aadab4723c1e761a49b8e152c905669a9250030cce67cce2cd324e0f6c79c419467aef3ba5445d7308c5ecb3c518eecceddda022320f46c7d
|
data/README.md
CHANGED
@@ -11,12 +11,12 @@ All type is checked by `===` method.
|
|
11
11
|
### Check type
|
12
12
|
|
13
13
|
```ruby
|
14
|
-
|
14
|
+
Sample = TypeStruct.new(
|
15
15
|
str: String,
|
16
16
|
reg: /exp/,
|
17
17
|
num: Integer,
|
18
18
|
any: Object,
|
19
|
-
)
|
19
|
+
)
|
20
20
|
|
21
21
|
sample = Sample.new(
|
22
22
|
str: "instance of String",
|
@@ -71,6 +71,8 @@ line.stort
|
|
71
71
|
|
72
72
|
Union is a object express class that some classes as one class like crystal `Union`.
|
73
73
|
|
74
|
+
`Union#===` check all object with `===` method.
|
75
|
+
|
74
76
|
```ruby
|
75
77
|
Foo = TypeStruct.new(
|
76
78
|
bar: TypeStruct::Union.new(TrueClass, FalseClass)
|
@@ -78,11 +80,11 @@ Foo = TypeStruct.new(
|
|
78
80
|
p Foo.new(bar: false) #=> #<Foo bar=false>
|
79
81
|
```
|
80
82
|
|
81
|
-
or
|
83
|
+
or add `Class#|` method by refinements
|
82
84
|
|
83
85
|
```ruby
|
84
86
|
require "type_struct/ext"
|
85
|
-
using
|
87
|
+
using TypeStruct::Union::Ext
|
86
88
|
Foo = TypeStruct.new(
|
87
89
|
bar: TrueClass | FalseClass,
|
88
90
|
)
|
@@ -92,6 +94,8 @@ Foo = TypeStruct.new(
|
|
92
94
|
|
93
95
|
ArrayOf is a object express array type.
|
94
96
|
|
97
|
+
`ArrayOf#===` check all item with `===` method.
|
98
|
+
|
95
99
|
```ruby
|
96
100
|
Bar = TypeStruct.new(
|
97
101
|
baz: TypeStruct::ArrayOf.new(Integer),
|
@@ -101,6 +105,8 @@ p Bar.new(baz: [1, 2, 3]) #=> #<Bar baz=[1, 2, 3]>
|
|
101
105
|
|
102
106
|
### HashOf
|
103
107
|
|
108
|
+
`HashOf#===` check all keys and values with `===` method.
|
109
|
+
|
104
110
|
```ruby
|
105
111
|
Baz = TypeStruct.new(
|
106
112
|
qux: TypeStruct::HashOf.new(String, TypeStruct::ArrayOf.new(Integer))
|
@@ -130,9 +136,9 @@ Foo.new(bar: 1) #=> TypeError
|
|
130
136
|
|
131
137
|
```ruby
|
132
138
|
require "type_struct/ext"
|
133
|
-
using
|
139
|
+
using TypeStruct::Union::Ext
|
134
140
|
Baz = TypeStruct.new(
|
135
|
-
qux: ArrayOf
|
141
|
+
qux: ArrayOf(Integer | TrueClass | FalseClass) | NilClass
|
136
142
|
)
|
137
143
|
p Baz.new(qux: [1]) #=> #<AAA::Baz qux=[1]>
|
138
144
|
p Baz.new(qux: [true, false]) #=> #<AAA::Baz qux=[true, false]>
|
data/lib/type_struct.rb
CHANGED
@@ -48,72 +48,6 @@ class TypeStruct
|
|
48
48
|
end
|
49
49
|
|
50
50
|
class << self
|
51
|
-
def try_convert(klass, value)
|
52
|
-
return nil unless !klass.nil? && !value.nil?
|
53
|
-
|
54
|
-
if Union === klass
|
55
|
-
errors = []
|
56
|
-
klass.each do |k|
|
57
|
-
t = begin
|
58
|
-
try_convert(k, value)
|
59
|
-
rescue TypeError => e
|
60
|
-
errors << e
|
61
|
-
nil
|
62
|
-
end
|
63
|
-
return t if !t.nil?
|
64
|
-
end
|
65
|
-
raise UnionNotFoundError, "#{klass} is not found with errors:\n#{errors.join("\n")}"
|
66
|
-
elsif ArrayOf === klass
|
67
|
-
value.map { |v| try_convert(klass.type, v) }
|
68
|
-
elsif HashOf === klass
|
69
|
-
return value unless Hash === value
|
70
|
-
new_hash = {}
|
71
|
-
value.each do |hk, hv|
|
72
|
-
new_hash[hk] = try_convert(klass.value_type, hv)
|
73
|
-
end
|
74
|
-
new_hash
|
75
|
-
elsif klass.respond_to?(:ancestors)
|
76
|
-
if klass.ancestors.include?(TypeStruct)
|
77
|
-
return nil unless Hash === value
|
78
|
-
klass.from_hash(value)
|
79
|
-
elsif klass.ancestors.include?(Struct)
|
80
|
-
struct = klass.new
|
81
|
-
value.each { |k, v| struct[k] = v }
|
82
|
-
struct
|
83
|
-
else
|
84
|
-
value
|
85
|
-
end
|
86
|
-
else
|
87
|
-
value
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def from_hash(h)
|
92
|
-
args = {}
|
93
|
-
h.each do |key, value|
|
94
|
-
key = key.to_sym
|
95
|
-
t = type(key)
|
96
|
-
args[key] = try_convert(t, value)
|
97
|
-
end
|
98
|
-
new(args)
|
99
|
-
end
|
100
|
-
|
101
|
-
def definition
|
102
|
-
const_get(:DEFINITION)
|
103
|
-
end
|
104
|
-
|
105
|
-
def members
|
106
|
-
definition.keys
|
107
|
-
end
|
108
|
-
|
109
|
-
def type(k)
|
110
|
-
definition[k]
|
111
|
-
end
|
112
|
-
|
113
|
-
def valid?(k, v)
|
114
|
-
definition[k] === v
|
115
|
-
end
|
116
|
-
|
117
51
|
alias original_new new
|
118
52
|
def new(**args, &block)
|
119
53
|
c = Class.new(TypeStruct) do
|
@@ -121,6 +55,74 @@ class TypeStruct
|
|
121
55
|
|
122
56
|
class << self
|
123
57
|
alias_method :new, :original_new
|
58
|
+
|
59
|
+
def from_hash(h)
|
60
|
+
args = {}
|
61
|
+
h.each do |key, value|
|
62
|
+
key = key.to_sym
|
63
|
+
t = type(key)
|
64
|
+
args[key] = try_convert(t, value)
|
65
|
+
end
|
66
|
+
new(args)
|
67
|
+
end
|
68
|
+
|
69
|
+
def definition
|
70
|
+
const_get(:DEFINITION)
|
71
|
+
end
|
72
|
+
|
73
|
+
def members
|
74
|
+
definition.keys
|
75
|
+
end
|
76
|
+
|
77
|
+
def type(k)
|
78
|
+
definition[k]
|
79
|
+
end
|
80
|
+
|
81
|
+
def valid?(k, v)
|
82
|
+
definition[k] === v
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def try_convert(klass, value)
|
88
|
+
return nil unless !klass.nil? && !value.nil?
|
89
|
+
|
90
|
+
if Union === klass
|
91
|
+
errors = []
|
92
|
+
klass.each do |k|
|
93
|
+
t = begin
|
94
|
+
try_convert(k, value)
|
95
|
+
rescue TypeError => e
|
96
|
+
errors << e
|
97
|
+
nil
|
98
|
+
end
|
99
|
+
return t if !t.nil?
|
100
|
+
end
|
101
|
+
raise UnionNotFoundError, "#{klass} is not found with errors:\n#{errors.join("\n")}"
|
102
|
+
elsif ArrayOf === klass
|
103
|
+
value.map { |v| try_convert(klass.type, v) }
|
104
|
+
elsif HashOf === klass
|
105
|
+
return value unless Hash === value
|
106
|
+
new_hash = {}
|
107
|
+
value.each do |hk, hv|
|
108
|
+
new_hash[hk] = try_convert(klass.value_type, hv)
|
109
|
+
end
|
110
|
+
new_hash
|
111
|
+
elsif klass.respond_to?(:ancestors)
|
112
|
+
if klass.ancestors.include?(TypeStruct)
|
113
|
+
return nil unless Hash === value
|
114
|
+
klass.from_hash(value)
|
115
|
+
elsif klass.ancestors.include?(Struct)
|
116
|
+
struct = klass.new
|
117
|
+
value.each { |k, v| struct[k] = v }
|
118
|
+
struct
|
119
|
+
else
|
120
|
+
value
|
121
|
+
end
|
122
|
+
else
|
123
|
+
value
|
124
|
+
end
|
125
|
+
end
|
124
126
|
end
|
125
127
|
|
126
128
|
args.each_key do |k|
|
@@ -30,8 +30,8 @@ module ArrayOfTest
|
|
30
30
|
|
31
31
|
def test_to_s(t)
|
32
32
|
array_of = ArrayOf.new(Symbol)
|
33
|
-
expect =
|
34
|
-
unless expect
|
33
|
+
expect = /ArrayOf\(Symbol\)/
|
34
|
+
unless expect =~ array_of.to_s
|
35
35
|
t.error("to_s string was break #{expect} != #{array_of}")
|
36
36
|
end
|
37
37
|
end
|
data/lib/type_struct/ext.rb
CHANGED
@@ -1,15 +1,44 @@
|
|
1
1
|
require "type_struct"
|
2
2
|
|
3
|
+
class Object
|
4
|
+
ArrayOf = TypeStruct::ArrayOf
|
5
|
+
HashOf = TypeStruct::HashOf
|
6
|
+
Union = TypeStruct::Union
|
7
|
+
Interface = TypeStruct::Interface
|
8
|
+
end
|
9
|
+
|
3
10
|
class TypeStruct
|
4
|
-
|
5
|
-
|
6
|
-
|
11
|
+
class ArrayOf
|
12
|
+
def to_s
|
13
|
+
"#{self.class.name.split('::').last}(#{@type})"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class HashOf
|
18
|
+
def to_s
|
19
|
+
"#{self.class.name.split('::').last}(#{@key_type}, #{@value_type})"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class Interface
|
24
|
+
def to_s
|
25
|
+
"#<#{self.class.name.split('::').last}(#{@methods.map(&:inspect).join(',')})>"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Union
|
30
|
+
def to_s
|
31
|
+
"#<#{self.class.name.split('::').last} #{@classes.join('|')}>"
|
7
32
|
end
|
8
33
|
end
|
9
34
|
end
|
10
35
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
36
|
+
module Kernel
|
37
|
+
def ArrayOf(klass)
|
38
|
+
ArrayOf.new(klass)
|
39
|
+
end
|
40
|
+
|
41
|
+
def HashOf(key_class, value_class)
|
42
|
+
HashOf.new(key_class, value_class)
|
43
|
+
end
|
44
|
+
end
|
@@ -33,8 +33,8 @@ module HashOfTest
|
|
33
33
|
|
34
34
|
def test_to_s(t)
|
35
35
|
hash_of = HashOf.new(Symbol, Integer)
|
36
|
-
expect =
|
37
|
-
unless expect
|
36
|
+
expect = /HashOf\(Symbol, Integer\)/
|
37
|
+
unless expect =~ hash_of.to_s
|
38
38
|
t.error("to_s string was break #{expect} != #{hash_of}")
|
39
39
|
end
|
40
40
|
end
|
data/lib/type_struct/union.rb
CHANGED
@@ -1,14 +1,21 @@
|
|
1
|
-
require "forwardable"
|
2
|
-
|
3
1
|
class TypeStruct
|
2
|
+
module Unionable
|
3
|
+
def |(other)
|
4
|
+
Union.new(self, other)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
4
8
|
class Union
|
5
|
-
extend Forwardable
|
6
|
-
def_delegators :@classes, :each
|
7
9
|
include Enumerable
|
10
|
+
|
8
11
|
def initialize(*classes)
|
9
12
|
@classes = classes
|
10
13
|
end
|
11
14
|
|
15
|
+
def each(*args, &block)
|
16
|
+
@classes.each(*args, &block)
|
17
|
+
end
|
18
|
+
|
12
19
|
def |(other)
|
13
20
|
Union.new(*@classes, other)
|
14
21
|
end
|
@@ -21,11 +28,11 @@ class TypeStruct
|
|
21
28
|
"#<#{self.class} #{@classes.join('|')}>"
|
22
29
|
end
|
23
30
|
alias inspect to_s
|
24
|
-
end
|
25
31
|
|
26
|
-
|
27
|
-
|
28
|
-
|
32
|
+
module Ext
|
33
|
+
refine Class do
|
34
|
+
include Unionable
|
35
|
+
end
|
29
36
|
end
|
30
37
|
end
|
31
38
|
end
|
data/lib/type_struct/version.rb
CHANGED
data/lib/type_struct_test.rb
CHANGED
@@ -2,13 +2,13 @@ require "type_struct"
|
|
2
2
|
require "type_struct/ext"
|
3
3
|
|
4
4
|
module TypeStructTest
|
5
|
-
using
|
5
|
+
using TypeStruct::Union::Ext
|
6
6
|
|
7
7
|
class Dummy < TypeStruct.new(
|
8
8
|
str: String,
|
9
9
|
num: Integer,
|
10
10
|
reg: /abc/,
|
11
|
-
ary: ArrayOf
|
11
|
+
ary: ArrayOf(Integer | Float) | NilClass,
|
12
12
|
any: Object,
|
13
13
|
); end
|
14
14
|
|
@@ -21,7 +21,7 @@ module TypeStructTest
|
|
21
21
|
); end
|
22
22
|
|
23
23
|
class Bar < TypeStruct.new(
|
24
|
-
baz: ArrayOf
|
24
|
+
baz: ArrayOf(Integer | NilClass),
|
25
25
|
); end
|
26
26
|
|
27
27
|
class Foo < TypeStruct.new(
|
@@ -31,22 +31,22 @@ module TypeStructTest
|
|
31
31
|
|
32
32
|
BoolClass = TrueClass | FalseClass
|
33
33
|
C = TypeStruct.new(
|
34
|
-
a: ArrayOf
|
34
|
+
a: ArrayOf(BoolClass),
|
35
35
|
)
|
36
36
|
B = TypeStruct.new(
|
37
37
|
a: Integer,
|
38
38
|
b: BoolClass,
|
39
|
-
c: ArrayOf
|
40
|
-
d: ArrayOf
|
39
|
+
c: ArrayOf(Integer),
|
40
|
+
d: ArrayOf(BoolClass),
|
41
41
|
e: C,
|
42
42
|
)
|
43
43
|
A = TypeStruct.new(
|
44
|
-
a: ArrayOf
|
45
|
-
b: ArrayOf
|
44
|
+
a: ArrayOf(Integer),
|
45
|
+
b: ArrayOf(BoolClass),
|
46
46
|
c: BoolClass,
|
47
47
|
d: B,
|
48
|
-
e: ArrayOf
|
49
|
-
f: HashOf
|
48
|
+
e: ArrayOf(B),
|
49
|
+
f: HashOf(String, Integer),
|
50
50
|
)
|
51
51
|
|
52
52
|
def test_s_from_hash_a(t)
|
@@ -92,7 +92,7 @@ module TypeStructTest
|
|
92
92
|
def test_hash_of(t)
|
93
93
|
b = TypeStruct.new(b: Integer)
|
94
94
|
hc = TypeStruct.new(
|
95
|
-
a: HashOf
|
95
|
+
a: HashOf(Symbol, b),
|
96
96
|
)
|
97
97
|
|
98
98
|
h = hc.new(
|
@@ -102,7 +102,6 @@ module TypeStructTest
|
|
102
102
|
t.error("assign failed")
|
103
103
|
end
|
104
104
|
|
105
|
-
p HashOf.new(Symbol, b) === []
|
106
105
|
begin
|
107
106
|
hc.new(
|
108
107
|
a: [],
|
@@ -129,7 +128,7 @@ module TypeStructTest
|
|
129
128
|
|
130
129
|
def test_array_of(t)
|
131
130
|
a = TypeStruct.new(a: Integer)
|
132
|
-
b = TypeStruct.new(a: ArrayOf
|
131
|
+
b = TypeStruct.new(a: ArrayOf(a))
|
133
132
|
bb = b.new(a: [a.new(a: 1), a.new(a: 2), a.new(a: 3)])
|
134
133
|
unless b === bb
|
135
134
|
t.error("type error")
|
@@ -191,14 +190,20 @@ module TypeStructTest
|
|
191
190
|
|
192
191
|
begin
|
193
192
|
d.from_hash(d: [b: 1])
|
194
|
-
rescue TypeStruct::UnionNotFoundError
|
193
|
+
rescue TypeStruct::UnionNotFoundError => err
|
194
|
+
unless /is not found with errors/ =~ err.message
|
195
|
+
t.error("error message was changed")
|
196
|
+
end
|
195
197
|
else
|
196
198
|
t.error("error dose not raised")
|
197
199
|
end
|
198
200
|
|
199
201
|
begin
|
200
202
|
d.from_hash(d: { b: "a" })
|
201
|
-
rescue TypeStruct::UnionNotFoundError
|
203
|
+
rescue TypeStruct::UnionNotFoundError => err
|
204
|
+
unless /is not found with errors/ =~ err.message
|
205
|
+
t.error("error message was changed")
|
206
|
+
end
|
202
207
|
else
|
203
208
|
t.error("error dose not raised")
|
204
209
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: type_struct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ksss
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -98,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
98
|
version: '0'
|
99
99
|
requirements: []
|
100
100
|
rubyforge_project:
|
101
|
-
rubygems_version: 2.
|
101
|
+
rubygems_version: 2.6.1
|
102
102
|
signing_key:
|
103
103
|
specification_version: 4
|
104
104
|
summary: Imitating static typed struct.
|