File Coverage

blib/lib/YAML/SyckWrapper.pm
Criterion Covered Total %
statement 62 68 91.1
branch 12 20 60.0
condition n/a
subroutine 14 15 93.3
pod 7 7 100.0
total 95 110 86.3


line stmt bran cond sub pod time code
1             package YAML::SyckWrapper;
2              
3             =encoding utf8
4              
5             =cut
6              
7              
8             # ABSTRACT: Loads YAML files in old and new fashion encoding ways.
9              
10             our $VERSION = '0.001'; # VERSION
11              
12 1     1   17428 use strict;
  1         4  
  1         40  
13 1     1   8 use warnings;
  1         3  
  1         43  
14              
15 1     1   8 use Carp qw( croak );
  1         3  
  1         89  
16 1     1   385 use YAML::Syck qw( Load LoadFile Dump );
  1         2627  
  1         79  
17 1     1   10 use Exporter qw( import );
  1         3  
  1         39  
18 1     1   448 use File::Slurp qw( read_file );
  1         12675  
  1         528  
19              
20              
21             our @EXPORT = ();
22             our @EXPORT_OK = qw(
23             &load_yaml_utf8
24             &load_yaml_bytes
25             &load_yaml
26             &load_yaml_objects
27             &dump_yaml
28             &parse_yaml
29             &yaml_merge_hash_fix
30             );
31              
32             our $allow_blessed = 0;
33              
34             =head1 FUNCTIONS
35              
36             None exported by default.
37              
38             =over
39              
40             =item B<load_yaml_utf8>
41              
42             load_yaml_utf8( $file_name );
43              
44             Loads specified YAML file.
45             Source file should be in UTF-8.
46             Output is UTF-8 binary string. UTF-8 validation performed.
47              
48             =cut
49              
50             sub _load_yaml_and_close {
51 5     5   12 my ( $file_name, $fh ) = @_;
52              
53 5         10 local $YAML::Syck::LoadBlessed = $allow_blessed; # никаких bless по умолчанию
54 5         10 my ( $res, $err ) = ( undef, undef );
55             eval {
56 5         28 $res = LoadFile( $fh );
57 5         477 1;
58 5 50       10 } or do {
59 0         0 $err = $@;
60             };
61 5         37 close $fh;
62 5 50       11 if ( $err ) {
63 0         0 croak "Cannot load $file_name: $err";
64             }
65 5         31 return $res;
66             }
67              
68             sub load_yaml_utf8 {
69 5     5 1 5333 my ( $file_name ) = @_;
70              
71             # This misleading hack taken from YAML::Syck documentation. We use encoding(UTF-8) layer here - obviously
72             # output should be Perl character string, but YAML::Syck::LoadFile will output binary UTF-8 (with
73             # YAML::Syck::ImplicitUnicode == false, which is default)
74             # Also YAML format defined as bytes (UTF-8 , UTF-16), so passing character filehandle to YAML::Syck::LoadFile is
75             # a hack too.
76             # encoding(UTF-8) does nothing here, except forcing perl to validate UTF-8
77 5 100       179 open ( my $fh, '<:encoding(UTF-8)', $file_name )
78             or die "Cannot open $file_name: $!";
79              
80 3         226 return _load_yaml_and_close( $file_name, $fh );
81             }
82              
83             =item B<load_yaml>
84              
85             load_yaml( $file_name );
86              
87             Loads specified YAML file.
88             Source file should be in UTF-8.
89             Output is UTF-8 character string. UTF-8 validation performed.
90              
91             =cut
92              
93             sub load_yaml {
94 3     3 1 4194 my ( $file_name ) = @_;
95              
96 3         7 local $YAML::Syck::ImplicitUnicode = 1;
97 3         15 return load_yaml_utf8( $file_name );
98             }
99              
100             =item B<load_yaml_bytes>
101              
102             load_yaml_bytes( $file_name );
103              
104             Loads specified as-is (no charset processing is involved). For old cp1251 yamls only.
105             Output is binary string, same as input data.
106              
107             =cut
108              
109             sub load_yaml_bytes {
110 4     4 1 4946 my ( $file_name ) = @_;
111 4 100       129 open ( my $fh, '<:bytes', $file_name )
112             or die "Cannot open $file_name: $!";
113 2         8 return _load_yaml_and_close( $file_name, $fh );
114             }
115              
116              
117             =item B<load_yaml_objects>
118              
119             load_yaml_objects( $file_name )
120              
121              
122             Loads specified file and outputs data in configured encoding.
123             Source file always in UTF-8.
124             Output format is text (unicode)
125              
126             Any !perl tag will be blessed.
127              
128             Syntax:
129              
130             myobj: !!perl/Some::Class
131             prop: value
132              
133             Don't use on insecure data!
134              
135             =cut
136              
137             sub load_yaml_objects {
138 1     1 1 8515 my ( $file_name ) = @_;
139 1         2 local $allow_blessed = 1;
140 1     0   6 local $SIG{__WARN__} = sub {};
141 1         4 my $data = load_yaml( $file_name );
142 1 50       5 return unless defined $data;
143 1         5 return $data;
144             }
145              
146             =item B<dump_yaml>
147              
148             dump_yaml( $data );
149              
150             Dumps data in YAML in Unicode.
151             Возвращает уникод.
152              
153             =cut
154              
155             sub dump_yaml {
156 1     1 1 925 my ( $data ) = @_;
157 1         2 local $YAML::Syck::ImplicitUnicode = 1;
158 1         2 local $YAML::Syck::SortKeys = 1;
159 1         5 return Dump( $data );
160             }
161              
162             =item B<parse_yaml>
163              
164             parse_yaml( $yaml_text );
165              
166             Parses YAML text into Unicode structure.
167              
168             Принимает unicode или UTF-8.
169              
170             =cut
171              
172             sub parse_yaml {
173 2     2 1 2112 my ( $yaml_text ) = @_;
174 2         4 local $YAML::Syck::LoadBlessed = $allow_blessed; # никаких bless по умолчанию
175 2         3 local $YAML::Syck::ImplicitUnicode = 1;
176 2         6 return Load( $yaml_text );
177             }
178              
179              
180             =item B<yaml_merge_hash_fix>
181              
182             yaml_merge_hash_fix( $ref );
183              
184             YAML hash merge bugfix
185             http://www.perlmonks.org/?node_id=813443.
186              
187             =cut
188              
189             sub yaml_merge_hash_fix {
190 8     8 1 65 my ($ref) = @_;
191              
192 8         10 my $type = ref $ref;
193 8 100       18 if ( $type eq 'HASH' ) {
    50          
194 3         9 while ( exists $ref->{'<<'} ) {
195 1         2 my $tmphref = $ref->{'<<'};
196 1 50       3 if ($tmphref) {
197 1 50       4 if (ref $tmphref eq 'HASH') {
    0          
198 1         5 my %tmphash = %$tmphref;
199 1         3 delete $ref->{'<<'};
200 1         7 %$ref = (%tmphash, %$ref);
201             }
202             elsif (ref $tmphref eq 'ARRAY') {
203 0         0 delete $ref->{'<<'};
204 0         0 %$ref = ( (map %$_, reverse @$tmphref ), %$ref);
205             }
206             else {
207 0         0 die "Merge key only support merging hashes or arrays";
208             }
209             }
210             }
211 3         11 yaml_merge_hash_fix($_) for ( values %$ref );
212             }
213             elsif ( $type eq 'ARRAY' ) {
214 0         0 yaml_merge_hash_fix($_) for (@$ref);
215             }
216 8         12 return $ref;
217             }
218              
219             =back
220              
221             =cut
222              
223             1;