File Coverage

blib/lib/App/Table2YAML/Serializer.pm
Criterion Covered Total %
statement 45 114 39.4
branch 2 28 7.1
condition 2 9 22.2
subroutine 10 22 45.4
pod 1 1 100.0
total 60 174 34.4


line stmt bran cond sub pod time code
1             package App::Table2YAML::Serializer;
2              
3 1     1   7 use common::sense;
  1         2  
  1         10  
4 1     1   69 use charnames q(:full);
  1         61  
  1         10  
5 1     1   579 use English qw[-no_match_vars];
  1         2  
  1         9  
6 1     1   2761 use List::Util qw[first];
  1         2  
  1         100  
7 1     1   7 use Moo;
  1         2  
  1         10  
8 1     1   2142 use Unicode::CaseFold qw[case_fold];
  1         1349  
  1         406  
9              
10             our $VERSION = '0.003'; # VERSION
11              
12             has allow_nulls => (
13             is => q(rw),
14             isa => sub { $_[0] == 0 || $_[0] == 1 },
15             default => 1,
16             );
17              
18             sub serialize {
19 1     1 1 3 my $self = shift;
20 1         13 my @table = splice @_;
21              
22 1 50       6 return unless @table;
23              
24 1         3 my @header = @{ shift @table };
  1         4  
25 1         5 foreach (@header) { s{\A\p{IsSpace}+}{}msx; s{\p{IsSpace}+\z}{}msx; }
  4         9  
  4         10  
26              
27 1         3 my @yaml;
28 1         5 while ( my $row = shift @table ) {
29 1         2 my @row;
30 1         9 while ( my ( $i, $header ) = each @header ) {
31 1         3 my $data = $row->[$i];
32 1         5 $data = $self->_serialize_scalar_data($data);
33 0 0 0     0 next if !( $self->allow_nulls() ) && $data eq q(null);
34 0         0 my %column = ( $header => $data );
35 0         0 push @row, {%column};
36             }
37 0 0       0 if (@row) {
38 0         0 my $yaml_record = $self->_serialize_row(@row);
39 0         0 push @yaml, $yaml_record;
40             }
41             }
42              
43 0         0 return @yaml;
44             } ## end sub serialize
45              
46             sub _serialize_row {
47 0     0   0 my $self = shift;
48 0         0 my @row = splice @_;
49              
50 0         0 foreach my $column (@row) {
51 0         0 $column = $self->_serialize_hash($column);
52             }
53              
54 0         0 my $row = join qq(\N{COMMA}\N{SPACE}), @row;
55 0         0 $row = sprintf q(- [ %s ]), $row;
56              
57 0         0 return $row;
58             }
59              
60             sub _serialize_hash {
61 0     0   0 my $self = shift;
62 0         0 my %hash = %{ +shift };
  0         0  
63              
64 0         0 my @hash;
65 0         0 while ( my ( $key, $value ) = each %hash ) {
66 0         0 my $pair = join qq(\N{COLON}\N{SPACE}), $key, $value;
67 0         0 push @hash, $pair;
68             }
69              
70 0         0 my $hash = join qq(\N{COMMA}), @hash;
71 0         0 $hash = sprintf q({%s}), $hash;
72              
73 0         0 return $hash;
74             } ## end sub _serialize_hash
75              
76             sub _serialize_scalar_data {
77 1     1   3 my $self = shift;
78 1         2 my $data = shift;
79              
80 1         4 foreach ($data) {
81              
82 1 50 33     16 if ( !(defined) || $_ eq q() || m{^\p{IsSpace}+$}msx ) {
      33        
83 0         0 $_ = q(null);
84 0         0 last;
85             }
86              
87 1         4 s{\A\p{IsSpace}+}{}msx;
88 1         3 s{\p{IsSpace}+\z}{}msx;
89              
90 1         7 my $scalar_value = $self->_define_scalar_value($_);
91              
92 0 0       0 if ( $scalar_value eq q(string) ) {
    0          
93 0         0 s{"}{\\"}gmsx;
94 0         0 $_ = qq("$_");
95             }
96 0     0   0 elsif ( first { $scalar_value eq $_ } qw[inf nan] ) {
97 0         0 s{^[+-]?\K}{.}msx;
98             }
99              
100             } ## end foreach ($data)
101              
102 0         0 return $data;
103             } ## end sub _serialize_scalar_data
104              
105             sub _define_scalar_value {
106 1     1   3 my $self = shift;
107 1         3 my $value = shift;
108              
109 1         21 my @method = grep { substr( $_, 0, 4 ) eq q(_is_) }
  0            
110             $self->meta->get_method_list();
111 0     0     my $method = first { $self->$_($value) } @method;
  0            
112 0 0         my $scalar_value = $method ? substr $method, 4 : q(string);
113              
114 0           return $scalar_value;
115             }
116              
117             sub _is_boolean {
118 0     0     my $self = shift;
119 0           my $value = shift;
120              
121 0           my $fc = case_fold($value);
122 0 0   0     my $st = ( first { $fc eq $_ } qw[y true yes on n false no off] ) ? 1 : 0;
  0            
123              
124 0           return $st;
125             }
126              
127             sub _is_inf {
128 0     0     my $self = shift;
129 0           my $value = shift;
130              
131 0           my $fc = case_fold($value);
132 0 0   0     my $st = ( first { $fc eq $_ } qw[inf -inf] ) ? 1 : 0;
  0            
133              
134 0           return $st;
135             }
136              
137             sub _is_nan {
138 0     0     my $self = shift;
139 0           my $value = shift;
140              
141 0           my $fc = case_fold($value);
142 0           my $st = $fc eq q(nan);
143              
144 0           return $st;
145             }
146              
147             sub _is_null {
148 0     0     my $self = shift;
149 0           my $value = shift;
150              
151 0 0   0     my $st = ( first { $value eq $_ } qw[~ null] ) ? 1 : 0;
  0            
152              
153 0           return $st;
154             }
155              
156             sub _is_numeric {
157 0     0     my $self = shift;
158 0           my $value = shift;
159              
160 0           my $st;
161              
162 0           foreach ($value) {
163 0 0         if (m{^[+-]?[0-9]+$}msx) {
    0          
    0          
    0          
164 0           $st = 1; # {Decimal,Octal} int
165             }
166             elsif (m{^[+-]?0x[0-9A-F]+$}imsx) {
167 0           $st = 1; # Hexadecimal int
168             }
169             elsif (m{^[+-]?(?:[0-9]{1,3})(?:_[0-9]{3})*(?:\.[0-9]+)?$}msx) {
170 0           $st = 1; # Fixed float
171             }
172             elsif (m{^[+-]?[0-9]+(?:\.[0-9]+)?e[+-]?[0-9]+$}imsx) {
173 0           $st = 1; # Exponential float
174             }
175             }
176              
177 0           return $st;
178             } ## end sub _is_numeric
179              
180 1     1   31121 no Moo;
  1         4  
  1         13  
181             __PACKAGE__->meta->make_immutable;
182              
183             1;
184              
185             __END__