generated from athena-framework/component-template
/
serializer.cr
84 lines (68 loc) · 3.13 KB
/
serializer.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
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
# Default implementation of `ASR::SerializerInterface`.
#
# Provides the main API used to (de)serialize objects.
#
# Custom formats can be implemented by creating the required visitors for that type, then overriding `#get_deserialization_visitor_class` and `#get_serialization_visitor_class`.
#
# ```
# # Redefine the visitor class getters in order to first check for custom formats.
# # This assumes these visitor types are defined, with the proper logic to handle
# # the (de)serialization process.
# struct Athena::Serializer::Serializer
# protected def get_deserialization_visitor_class(format : ASR::Format | String)
# return MessagePackDeserializationVisitor if format == "message_pack"
#
# previous_def
# end
#
# protected def get_serialization_visitor_class(format : ASR::Format | String)
# return MessagePackSerializationVisitor if format == "message_pack"
#
# previous_def
# end
# end
# ```
struct Athena::Serializer::Serializer
include Athena::Serializer::SerializerInterface
def initialize(@navigator_factory : ASR::Navigators::NavigatorFactoryInterface = ASR::Navigators::NavigatorFactory.new); end
# :inherit:
def deserialize(type : _, data : String | IO, format : ASR::Format | String, context : ASR::DeserializationContext = ASR::DeserializationContext.new)
# Initialize the context. Currently just used to apply default exclusion strategies
context.init
visitor = self.get_deserialization_visitor_class(format).new
navigator = @navigator_factory.get_deserialization_navigator visitor, context
visitor.navigator = navigator
navigator.accept type, visitor.prepare data
end
# :inherit:
def serialize(data : _, format : ASR::Format | String, context : ASR::SerializationContext = ASR::SerializationContext.new, **named_args) : String
String.build do |str|
serialize data, format, str, context, **named_args
end
end
# :inherit:
def serialize(data : _, format : ASR::Format | String, io : IO, context : ASR::SerializationContext = ASR::SerializationContext.new, **named_args) : Nil
# Initialize the context. Currently just used to apply default exclusion strategies
context.init
visitor = self.get_serialization_visitor_class(format).new(io, named_args)
navigator = @navigator_factory.get_serialization_navigator visitor, context
visitor.navigator = navigator
visitor.prepare
navigator.accept data
visitor.finish
end
# Returns the `ASR::Visitors::DeserializationVisitorInterface.class` for the given *format*.
#
# Can be redefined in order to allow resolving custom formats.
protected def get_deserialization_visitor_class(format : ASR::Format | String)
return format.deserialization_visitor if format.is_a? ASR::Format
ASR::Format.parse(format).deserialization_visitor
end
# Returns the `ASR::Visitors::SerializationVisitorInterface.class` for the given *format*.
#
# Can be redefined in order to allow resolving custom formats.
protected def get_serialization_visitor_class(format : ASR::Format | String)
return format.serialization_visitor if format.is_a? ASR::Format
ASR::Format.parse(format).serialization_visitor
end
end