Skip to content

Commit ebe0e6f

Browse files
committed
Custom type for from_hash
1 parent 749dea4 commit ebe0e6f

File tree

4 files changed

+43
-32
lines changed

4 files changed

+43
-32
lines changed

lib/type_struct.rb

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
class TypeStruct
44
require "type_struct/union"
5+
require "type_struct/type_of"
56
require "type_struct/array_of"
67
require "type_struct/hash_of"
78
require "type_struct/interface"
@@ -91,9 +92,11 @@ def type(k)
9192
def valid?(k, v)
9293
definition[k] === v
9394
end
95+
end
9496

95-
private
97+
private
9698

99+
class << self
97100
def try_convert(klass, key, value, errors)
98101
case klass
99102
when Union
@@ -107,32 +110,8 @@ def try_convert(klass, key, value, errors)
107110
end
108111

109112
raise UnionNotFoundError, "#{klass} is not found with value `#{value}'\nerrors:\n#{union_errors.join("\n")}"
110-
when ArrayOf
111-
unless Array === value
112-
begin
113-
raise TypeError, "#{self}##{key} expect #{klass.inspect} got #{value.inspect}"
114-
rescue TypeError => e
115-
raise unless errors
116-
errors << e
117-
end
118-
return value
119-
end
120-
value.map { |v| try_convert(klass.type, key, v, errors) }
121-
when HashOf
122-
unless Hash === value
123-
begin
124-
raise TypeError, "#{self}##{key} expect #{klass.inspect} got #{value.inspect}"
125-
rescue TypeError => e
126-
raise unless errors
127-
errors << e
128-
end
129-
return value
130-
end
131-
new_hash = {}
132-
value.each do |hk, hv|
133-
new_hash[hk] = try_convert(klass.value_type, key, hv, errors)
134-
end
135-
new_hash
113+
when TypeOf
114+
klass.try_convert(key, value, errors)
136115
else
137116
if klass.respond_to?(:ancestors)
138117
if klass.ancestors.include?(TypeStruct)

lib/type_struct/array_of.rb

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
require "type_struct/union"
22

33
class TypeStruct
4-
class ArrayOf
5-
include Unionable
4+
class ArrayOf < TypeOf
65
attr_reader :type
76
def initialize(type)
87
@type = type
@@ -17,5 +16,18 @@ def ===(other)
1716
return false unless Array === other
1817
other.all? { |o| @type === o }
1918
end
19+
20+
def try_convert(key, value, errors)
21+
unless Array === value
22+
begin
23+
raise TypeError, "#{self}##{key} expect #{inspect} got #{value.inspect}"
24+
rescue TypeError => e
25+
raise unless errors
26+
errors << e
27+
end
28+
return value
29+
end
30+
value.map { |v| TypeStruct.try_convert(@type, key, v, errors) }
31+
end
2032
end
2133
end

lib/type_struct/hash_of.rb

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
require "type_struct/union"
22

33
class TypeStruct
4-
class HashOf
5-
include Unionable
6-
4+
class HashOf < TypeOf
75
attr_reader :key_type, :value_type
86
def initialize(key_type, value_type)
97
@key_type = key_type
@@ -21,5 +19,22 @@ def to_s
2119
"#{self.class}(#{@key_type}, #{@value_type})"
2220
end
2321
alias inspect to_s
22+
23+
def try_convert(key, value, errors)
24+
unless Hash === value
25+
begin
26+
raise TypeError, "#{self}##{key} expect #{inspect} got #{value.inspect}"
27+
rescue TypeError => e
28+
raise unless errors
29+
errors << e
30+
end
31+
return value
32+
end
33+
new_hash = {}
34+
value.each do |hk, hv|
35+
new_hash[hk] = TypeStruct.try_convert(@value_type, key, hv, errors)
36+
end
37+
new_hash
38+
end
2439
end
2540
end

lib/type_struct/type_of.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class TypeStruct
2+
class TypeOf
3+
include Unionable
4+
end
5+
end

0 commit comments

Comments
 (0)