master
py 112 lines 4.1 KB
Raw
1 # SPDX-License-Identifier: MIT
2
3 __all__ = ['Serializer', 'SerializerError']
4
5 from .error import YAMLError
6 from .events import *
7 from .nodes import *
8
9 class SerializerError(YAMLError):
10 pass
11
12 class Serializer:
13
14 ANCHOR_TEMPLATE = 'id%03d'
15
16 def __init__(self, encoding=None,
17 explicit_start=None, explicit_end=None, version=None, tags=None):
18 self.use_encoding = encoding
19 self.use_explicit_start = explicit_start
20 self.use_explicit_end = explicit_end
21 self.use_version = version
22 self.use_tags = tags
23 self.serialized_nodes = {}
24 self.anchors = {}
25 self.last_anchor_id = 0
26 self.closed = None
27
28 def open(self):
29 if self.closed is None:
30 self.emit(StreamStartEvent(encoding=self.use_encoding))
31 self.closed = False
32 elif self.closed:
33 raise SerializerError("serializer is closed")
34 else:
35 raise SerializerError("serializer is already opened")
36
37 def close(self):
38 if self.closed is None:
39 raise SerializerError("serializer is not opened")
40 elif not self.closed:
41 self.emit(StreamEndEvent())
42 self.closed = True
43
44 #def __del__(self):
45 # self.close()
46
47 def serialize(self, node):
48 if self.closed is None:
49 raise SerializerError("serializer is not opened")
50 elif self.closed:
51 raise SerializerError("serializer is closed")
52 self.emit(DocumentStartEvent(explicit=self.use_explicit_start,
53 version=self.use_version, tags=self.use_tags))
54 self.anchor_node(node)
55 self.serialize_node(node, None, None)
56 self.emit(DocumentEndEvent(explicit=self.use_explicit_end))
57 self.serialized_nodes = {}
58 self.anchors = {}
59 self.last_anchor_id = 0
60
61 def anchor_node(self, node):
62 if node in self.anchors:
63 if self.anchors[node] is None:
64 self.anchors[node] = self.generate_anchor(node)
65 else:
66 self.anchors[node] = None
67 if isinstance(node, SequenceNode):
68 for item in node.value:
69 self.anchor_node(item)
70 elif isinstance(node, MappingNode):
71 for key, value in node.value:
72 self.anchor_node(key)
73 self.anchor_node(value)
74
75 def generate_anchor(self, node):
76 self.last_anchor_id += 1
77 return self.ANCHOR_TEMPLATE % self.last_anchor_id
78
79 def serialize_node(self, node, parent, index):
80 alias = self.anchors[node]
81 if node in self.serialized_nodes:
82 self.emit(AliasEvent(alias))
83 else:
84 self.serialized_nodes[node] = True
85 self.descend_resolver(parent, index)
86 if isinstance(node, ScalarNode):
87 detected_tag = self.resolve(ScalarNode, node.value, (True, False))
88 default_tag = self.resolve(ScalarNode, node.value, (False, True))
89 implicit = (node.tag == detected_tag), (node.tag == default_tag)
90 self.emit(ScalarEvent(alias, node.tag, implicit, node.value,
91 style=node.style))
92 elif isinstance(node, SequenceNode):
93 implicit = (node.tag
94 == self.resolve(SequenceNode, node.value, True))
95 self.emit(SequenceStartEvent(alias, node.tag, implicit,
96 flow_style=node.flow_style))
97 index = 0
98 for item in node.value:
99 self.serialize_node(item, node, index)
100 index += 1
101 self.emit(SequenceEndEvent())
102 elif isinstance(node, MappingNode):
103 implicit = (node.tag
104 == self.resolve(MappingNode, node.value, True))
105 self.emit(MappingStartEvent(alias, node.tag, implicit,
106 flow_style=node.flow_style))
107 for key, value in node.value:
108 self.serialize_node(key, node, None)
109 self.serialize_node(value, node, key)
110 self.emit(MappingEndEvent())
111 self.ascend_resolver()
112