32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
# File 'lib/pocolog/upgrade.rb', line 32
def self.build_deep_cast(time, from_type, to_type, registered_converters, relax: false)
if from_type < Typelib::NumericType
if !(to_type < Typelib::NumericType)
raise InvalidCast, "cannot automatically cast a numeric type into a non-numeric type"
end
Ops::NumericCast.new(from_type, to_type)
elsif from_type < Typelib::ArrayType || from_type < Typelib::ContainerType
if to_type < Typelib::ArrayType
if from_type < Typelib::ArrayType
if from_type.length != to_type.length
raise ArraySizeMismatch, "cannot convert between arrays of different sizes"
end
end
element_conversion =
compute(time, from_type.deference, to_type.deference, registered_converters, relax: relax)
Ops::ArrayCast.new(to_type, element_conversion)
elsif to_type < Typelib::ContainerType
element_conversion =
compute(time, from_type.deference, to_type.deference, registered_converters)
Ops::ContainerCast.new(to_type, element_conversion)
else
raise InvalidCast, "cannot automatically cast an array/container to a non-array/container"
end
elsif from_type < Typelib::EnumType
if !(to_type < Typelib::EnumType)
raise InvalidCast, "cannot automatically cast an enum to a non-enum"
end
Ops::EnumCast.new(from_type, to_type)
elsif from_type < Typelib::CompoundType
if !(to_type < Typelib::CompoundType)
raise InvalidCast, "cannot automatically cast a compound to a non-compound"
end
field_convertions = Array.new
from_type.each_field do |field_name, field_type|
if to_type.has_field?(field_name)
begin
field_ops = compute(time, field_type, to_type[field_name], registered_converters, relax: true)
field_convertions << [field_name, field_ops]
rescue InvalidCast
raise if !relax
end
end
end
if !relax
to_type.each_field do |field_name, field_type|
if !from_type.has_field?(field_name) && !(field_type <= Typelib::ContainerType)
raise CannotAddNonContainerField.new(to_type, field_name), "cannot automatically convert to a compound that adds a non-container field, #{to_type.name} adds #{field_name} of type #{field_type.name}"
end
end
end
Ops::CompoundCast.new(field_convertions, to_type)
end
end
|