generated from athena-framework/component-template
-
Notifications
You must be signed in to change notification settings - Fork 2
/
deserialization_navigator.cr
48 lines (40 loc) · 1.63 KB
/
deserialization_navigator.cr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
module Athena::Serializer::Navigators::DeserializationNavigatorInterface
abstract def accept(type : T.class, data : ASR::Any) forall T
end
struct Athena::Serializer::Navigators::DeserializationNavigator
include Athena::Serializer::Navigators::DeserializationNavigatorInterface
def initialize(
@visitor : ASR::Visitors::DeserializationVisitorInterface,
@context : ASR::DeserializationContext,
@object_constructor : ASR::ObjectConstructorInterface
); end
def accept(type : T.class, data : ASR::Any) forall T
{% unless T.instance <= ASR::Model %}
{% if T.class.has_method? :deserialize %}
@visitor.visit type, data
{% end %}
{% else %}
{% if ann = T.instance.annotation(ASRA::Discriminator) %}
if key = data[{{ann[:key]}}]?
type = case key
{% for k, t in ann[:map] %}
when {{k.id.stringify}} then {{t}}
{% end %}
else
raise ASR::Exceptions::PropertyException.new "Unknown '#{{{ann[:key]}}}' discriminator value: '#{key}'.", {{ann[:key].id.stringify}}
end
else
raise ASR::Exceptions::PropertyException.new "Missing discriminator field '#{{{ann[:key]}}}'.", {{ann[:key].id.stringify}}
end
{% end %}
properties = type.deserialization_properties
# Apply exclusion strategies if one is defined
if strategy = @context.exclusion_strategy
properties.reject! { |property| strategy.skip_property? property, @context }
end
object = @object_constructor.construct self, properties, data, type
object.run_postdeserialize
object
{% end %}
end
end