Skip to content

Commit 43aa6a1

Browse files
committed
Custom type for from_hash
1 parent 0320360 commit 43aa6a1

File tree

4 files changed

+41
-31
lines changed

4 files changed

+41
-31
lines changed

lib/type_struct.rb

Lines changed: 4 additions & 26 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"
@@ -94,6 +95,7 @@ def valid?(k, v)
9495

9596
private
9697

98+
class << self
9799
def try_convert(klass, key, value, errors)
98100
case klass
99101
when Union
@@ -107,32 +109,8 @@ def try_convert(klass, key, value, errors)
107109
end
108110

109111
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
112+
when TypeOf
113+
klass.try_convert(key, value, errors)
136114
else
137115
if klass.respond_to?(:ancestors)
138116
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)