Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 6 additions & 27 deletions lib/type_struct.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

class TypeStruct
require "type_struct/union"
require "type_struct/type_of"
require "type_struct/array_of"
require "type_struct/hash_of"
require "type_struct/interface"
Expand Down Expand Up @@ -91,9 +92,11 @@ def type(k)
def valid?(k, v)
definition[k] === v
end
end

private
private

class << self
def try_convert(klass, key, value, errors)
case klass
when Union
Expand All @@ -107,32 +110,8 @@ def try_convert(klass, key, value, errors)
end

raise UnionNotFoundError, "#{klass} is not found with value `#{value}'\nerrors:\n#{union_errors.join("\n")}"
when ArrayOf
unless Array === value
begin
raise TypeError, "#{self}##{key} expect #{klass.inspect} got #{value.inspect}"
rescue TypeError => e
raise unless errors
errors << e
end
return value
end
value.map { |v| try_convert(klass.type, key, v, errors) }
when HashOf
unless Hash === value
begin
raise TypeError, "#{self}##{key} expect #{klass.inspect} got #{value.inspect}"
rescue TypeError => e
raise unless errors
errors << e
end
return value
end
new_hash = {}
value.each do |hk, hv|
new_hash[hk] = try_convert(klass.value_type, key, hv, errors)
end
new_hash
when TypeOf
klass.try_convert(key, value, errors)
else
if klass.respond_to?(:ancestors)
if klass.ancestors.include?(TypeStruct)
Expand Down
16 changes: 14 additions & 2 deletions lib/type_struct/array_of.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
require "type_struct/union"

class TypeStruct
class ArrayOf
include Unionable
class ArrayOf < TypeOf
attr_reader :type
def initialize(type)
@type = type
Expand All @@ -17,5 +16,18 @@ def ===(other)
return false unless Array === other
other.all? { |o| @type === o }
end

def try_convert(key, value, errors)
unless Array === value
begin
raise TypeError, "#{self}##{key} expect #{inspect} got #{value.inspect}"
rescue TypeError => e
raise unless errors
errors << e
end
return value
end
value.map { |v| TypeStruct.try_convert(@type, key, v, errors) }
end
end
end
21 changes: 18 additions & 3 deletions lib/type_struct/hash_of.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
require "type_struct/union"

class TypeStruct
class HashOf
include Unionable

class HashOf < TypeOf
attr_reader :key_type, :value_type
def initialize(key_type, value_type)
@key_type = key_type
Expand All @@ -21,5 +19,22 @@ def to_s
"#{self.class}(#{@key_type}, #{@value_type})"
end
alias inspect to_s

def try_convert(key, value, errors)
unless Hash === value
begin
raise TypeError, "#{self}##{key} expect #{inspect} got #{value.inspect}"
rescue TypeError => e
raise unless errors
errors << e
end
return value
end
new_hash = {}
value.each do |hk, hv|
new_hash[hk] = TypeStruct.try_convert(@value_type, key, hv, errors)
end
new_hash
end
end
end
5 changes: 5 additions & 0 deletions lib/type_struct/type_of.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class TypeStruct
class TypeOf
include Unionable
end
end