File Coverage

blib/lib/Data/YAML/Writer.pm
Criterion Covered Total %
statement 61 65 93.8
branch 18 24 75.0
condition 9 13 69.2
subroutine 12 13 92.3
pod 2 2 100.0
total 102 117 87.1


line stmt bran cond sub pod time code
1             package Data::YAML::Writer;
2              
3 4     4   27290 use strict;
  4         5  
  4         111  
4 4     4   13 use warnings;
  4         2  
  4         73  
5 4     4   10 use Carp;
  4         10  
  4         179  
6              
7 4     4   12 use vars qw{$VERSION};
  4         5  
  4         2093  
8              
9             $VERSION = '0.0.7';
10              
11             my $ESCAPE_CHAR = qr{ [\x00-\x1f\"] }x;
12              
13             my @UNPRINTABLE = qw(
14             z x01 x02 x03 x04 x05 x06 a
15             x08 t n v f r x0e x0f
16             x10 x11 x12 x13 x14 x15 x16 x17
17             x18 x19 x1a e x1c x1d x1e x1f
18             );
19              
20             # Create an empty Data::YAML::Writer object
21             sub new {
22 19     19 1 6167 my $class = shift;
23 19         88 bless {}, $class;
24             }
25              
26             sub write {
27 19     19 1 16 my $self = shift;
28              
29 19 50       38 croak "Need something to write"
30             unless @_;
31              
32 19         19 my $obj = shift;
33 19   50     31 my $out = shift || \*STDOUT;
34              
35 19 50       33 croak "Need a reference to something I can write to"
36             unless ref $out;
37              
38 19         33 $self->{writer} = $self->_make_writer( $out );
39              
40 19         30 $self->_write_obj( '---', $obj );
41 19         103 $self->_put( '...' );
42              
43 19         60 delete $self->{writer};
44             }
45              
46             sub _make_writer {
47 19     19   17 my $self = shift;
48 19         16 my $out = shift;
49              
50 19         20 my $ref = ref $out;
51              
52 19 100 0     36 if ( 'CODE' eq $ref ) {
    100          
    50          
    0          
53 17         37 return $out;
54             }
55             elsif ( 'ARRAY' eq $ref ) {
56 1     26   6 return sub { push @$out, shift };
  26         50  
57             }
58             elsif ( 'SCALAR' eq $ref ) {
59 1     26   5 return sub { $$out .= shift() . "\n" };
  26         470  
60             }
61             elsif ( 'GLOB' eq $ref || 'IO::Handle' eq $ref ) {
62 0     0   0 return sub { print $out shift(), "\n" };
  0         0  
63             }
64              
65 0         0 croak "Can't write to $out";
66             }
67              
68             sub _put {
69 166     166   117 my $self = shift;
70 166         330 $self->{writer}->( join '', @_ );
71             }
72              
73             sub _enc_scalar {
74 214     214   148 my $self = shift;
75 214         149 my $val = shift;
76              
77 214 100       276 return '~' unless defined $val;
78              
79 211 100 100     862 if ( $val =~ /$ESCAPE_CHAR/ or $val =~ /:$/ ) {
80 12         15 $val =~ s/\\/\\\\/g;
81 12         13 $val =~ s/"/\\"/g;
82 12         33 $val =~ s/ ( [\x00-\x1f] ) / '\\' . $UNPRINTABLE[ ord($1) ] /gex;
  16         40  
83 12         45 return qq{"$val"};
84             }
85              
86 199 100 100     537 if ( length( $val ) == 0 or $val =~ /\s/ ) {
87 11         13 $val =~ s/'/''/;
88 11         25 return "'$val'";
89             }
90              
91 188         370 return $val;
92             }
93              
94             sub _write_obj {
95 147     147   113 my $self = shift;
96 147         112 my $prefix = shift;
97 147         91 my $obj = shift;
98 147   100     218 my $indent = shift || 0;
99              
100 147 100       182 if ( my $ref = ref $obj ) {
101 42         44 my $pad = ' ' x $indent;
102 42         54 $self->_put( $prefix );
103 42 100       113 if ( 'HASH' eq $ref ) {
    50          
104 34         105 for my $key ( sort keys %$obj ) {
105 109         200 my $value = $obj->{$key};
106 109         120 $self->_write_obj( $pad . $self->_enc_scalar( $key ) . ':',
107             $value, $indent + 1 );
108             }
109             }
110             elsif ( 'ARRAY' eq $ref ) {
111 8         10 for my $value ( @$obj ) {
112 19         54 $self->_write_obj( $pad . '-', $value, $indent + 1 );
113             }
114             }
115             else {
116 0         0 croak "Don't know how to encode $ref";
117             }
118             }
119             else {
120 105         113 $self->_put( $prefix, ' ', $self->_enc_scalar( $obj ) );
121             }
122             }
123              
124             1;
125              
126             __END__