File Coverage

blib/lib/YAML/Perl/Serializer.pm
Criterion Covered Total %
statement 92 92 100.0
branch 14 16 87.5
condition 8 8 100.0
subroutine 13 13 100.0
pod 0 7 0.0
total 127 136 93.3


line stmt bran cond sub pod time code
1             package YAML::Perl::Serializer;
2 5     5   702 use strict;
  5         10  
  5         251  
3 5     5   27 use warnings;
  5         8  
  5         137  
4              
5 5     5   566 use YAML::Perl::Error;
  5         9  
  5         53  
6              
7             package YAML::Perl::Error::Serializer;
8 5     5   25 use YAML::Perl::Error::Marked -base;
  5         9  
  5         44  
9              
10             package YAML::Perl::Serializer;
11 5     5   627 use YAML::Perl::Processor -base;
  5         12  
  5         40  
12              
13             field 'next_layer' => 'emitter';
14              
15             field 'emitter_class', -init => '"YAML::Perl::Emitter"';
16             field 'emitter', -init => '$self->create("emitter")';
17              
18             field 'resolver_class', 'YAML::Perl::Resolver';
19             field 'resolver', -init => '$self->create("resolver")';
20              
21 5     5   28 use constant ANCHOR_TEMPLATE => '%03d';
  5         22  
  5         6119  
22              
23             field 'use_encoding';
24             field 'use_explicit_start' => 1;
25             field 'use_explicit_end';
26             field 'use_version';
27             field 'use_tags';
28             field 'serialized_nodes' => {};
29             field 'anchors' => {};
30             field 'last_anchor_id' => 0;
31             field 'closed';
32              
33             sub serialize {
34 1     1 0 3 my $self = shift;
35 1         4 for my $node (@_) {
36 1         12 $self->serialize_document($node);
37             }
38 1         3 return ${$self->emitter->writer->stream->buffer};
  1         23  
39             }
40              
41             sub open {
42 19     19 0 40 my $self = shift;
43 19         114 $self->SUPER::open(@_);
44 19         490 $self->emitter->emit(
45             YAML::Perl::Event::StreamStart->new()
46             );
47 19         115 return $self;
48             }
49              
50             sub close {
51 6     6 0 13 my $self = shift;
52 6         145 $self->emitter->emit(
53             YAML::Perl::Event::StreamEnd->new()
54             );
55 6         67 $self->SUPER::close(@_);
56 6         14 return $self;
57             }
58              
59             sub serialize_document {
60 19     19 0 34 my $self = shift;
61 19         43 my $node = shift;
62             # if self.closed is None:
63             # raise SerializerError("serializer is not opened")
64             # elif self.closed:
65             # raise SerializerError("serializer is closed")
66 19         467 $self->emitter->emit(
67             YAML::Perl::Event::DocumentStart->new(
68             explicit => $self->use_explicit_start,
69             version => $self->use_version,
70             tags => $self->use_tags,
71             )
72             );
73 19         91 $self->anchor_node($node);
74 19         85 $self->serialize_node($node, undef, undef);
75 19         487 $self->emitter->emit(
76             YAML::Perl::Event::DocumentEnd->new(
77             explicit => $self->use_explicit_end
78             )
79             );
80 19         533 $self->serialized_nodes({});
81 19         474 $self->anchors({});
82 19         511 $self->last_anchor_id(0);
83             }
84              
85             sub anchor_node {
86 82     82 0 118 my $self = shift;
87 82         103 my $node = shift;
88 82 100       1954 if (exists $self->anchors->{$node}) {
89 3 50       79 if (not defined $self->anchors->{$node}) {
90 3         14 $self->anchors->{$node} = $self->generate_anchor($node);
91             }
92             }
93             else {
94 79         1856 $self->anchors->{$node} = undef;
95 79 100       845 if ($node->isa('YAML::Perl::Node::Sequence')) {
    100          
96 16         25 for my $item (@{$node->value}) {
  16         416  
97 33         96 $self->anchor_node($item);
98             }
99             }
100             elsif ($node->isa('YAML::Perl::Node::Mapping')) {
101 15         34 for (my $i = 0; $i < @{$node->value}; $i += 2) {
  30         699  
102 15         457 my $key = $node->value->[$i];
103 15         341 my $value = $node->value->[$i + 1];
104 15         65 $self->anchor_node($key);
105 15         51 $self->anchor_node($value);
106             }
107             }
108             }
109             }
110              
111             sub generate_anchor {
112 3     3 0 7 my $self = shift;
113 3         7 my $node = shift;
114 3         70 $self->last_anchor_id($self->last_anchor_id + 1);
115 3         66 return sprintf ANCHOR_TEMPLATE, $self->last_anchor_id;
116             }
117              
118             sub serialize_node {
119 82     82 0 141 my $self = shift;
120 82         116 my $node = shift;
121 82         111 my $parent = shift;
122 82         108 my $index = shift;
123              
124 82         2057 my $alias = $self->anchors->{$node};
125 82 100       2035 if ($self->serialized_nodes->{$node}) {
126 3         81 $self->emitter->emit(
127             YAML::Perl::Event::Alias->new(
128             anchor => $alias,
129             )
130             );
131             }
132             else {
133 79         1928 $self->serialized_nodes->{$node} = True;
134 79         2124 $self->resolver->descend_resolver($parent, $index);
135 79 100       657 if ($node->isa('YAML::Perl::Node::Scalar')) {
    100          
    50          
136 48         8530 my $detected_tag = $self->resolver->resolve(
137             'YAML::Perl::Node::Scalar',
138             $node->value,
139             [True, False]
140             );
141 48         1158 my $default_tag = $self->resolver->resolve(
142             'YAML::Perl::Node::Scalar',
143             $node->value,
144             [False, True]
145             );
146 48   100     1352 my $implicit = [
      100        
147             (($node->tag || '') eq $detected_tag),
148             (($node->tag || '') eq $default_tag),
149             ];
150 48         1268 $self->emitter->emit(YAML::Perl::Event::Scalar->new(
151             anchor => $alias,
152             tag => $node->tag,
153             implicit => $implicit,
154             value => $node->value,
155             style => $node->style,
156             ));
157             }
158             elsif ($node->isa('YAML::Perl::Node::Sequence')) {
159 16   100     412 my $implicit = ($node->tag || '') eq $self->resolver->resolve(
160             'YAML::Perl::Node::Sequence',
161             $node->value,
162             True
163             );
164 16         398 $self->emitter->emit(YAML::Perl::Event::SequenceStart->new(
165             anchor => $alias,
166             tag => $node->tag,
167             implicit => $implicit,
168             flow_style => $node->flow_style)
169             );
170 16         43 $index = 0;
171 16         28 for my $item (@{$node->value}) {
  16         459  
172 33         116 $self->serialize_node($item, $node, $index);
173 33         116 $index += 1;
174             }
175 16         403 $self->emitter->emit(YAML::Perl::Event::SequenceEnd->new());
176             }
177             elsif ($node->isa('YAML::Perl::Node::Mapping')) {
178 15   100     383 my $implicit = ($node->tag || '') eq $self->resolver->resolve(
179             'YAML::Perl::Node::Mapping',
180             $node->value,
181             True
182             );
183 15         373 $self->emitter->emit(YAML::Perl::Event::MappingStart->new(
184             anchor => $alias,
185             tag => $node->tag,
186             implicit => $implicit,
187             flow_style => $node->flow_style
188             ));
189 15         46 for (my $i = 0; $i < @{$node->value}; $i += 2) {
  30         705  
190 15         350 my $key = $node->value->[$i];
191 15         329 my $value = $node->value->[$i + 1];
192 15         123 $self->serialize_node($key, $node, undef);
193 15         64 $self->serialize_node($value, $node, $key);
194             }
195 15         362 $self->emitter->emit(YAML::Perl::Event::MappingEnd->new());
196             }
197 79         2168 $self->resolver->ascend_resolver();
198             }
199             }
200              
201             1;