File Coverage

blib/lib/Struct/WOP.pm
Criterion Covered Total %
statement 55 57 96.4
branch 28 34 82.3
condition 17 33 51.5
subroutine 12 13 92.3
pod 2 2 100.0
total 114 139 82.0


line stmt bran cond sub pod time code
1             package Struct::WOP;
2              
3 4     4   333821 use 5.006;
  4         59  
4 4     4   22 use strict;
  4         11  
  4         89  
5 4     4   19 use warnings;
  4         9  
  4         111  
6              
7 4     4   22 use Scalar::Util qw/reftype refaddr/;
  4         18  
  4         244  
8 4     4   593 use Encode qw/decode encode/;
  4         10446  
  4         1897  
9              
10             our $VERSION = '0.19';
11             our (%HELP, @MAYBE, $caller, $destruct);
12             BEGIN {
13             %HELP = (
14 4         8 arrayref => sub { return map { $_[0]->($_, $_[2]) } @{ $_[1] } },
  15         40  
  4         12  
15             hashref => sub { $caller->can('filter_keys') && $caller->filter_keys($_[1]->{$_}, $_) and next or
16 3   33     6 $destruct && do { $_[3]{$_[0]->($_)} = $_[0]->($_[1]->{$_}, $_[2]) } || do { $_[1]->{$_} = $_[0]->($_[1]->{$_}, $_[2]) } for keys %{ $_[1] }; $_[3]; },
  3   50     54  
  2   66     7  
  1   66     4  
  3   0     38  
17 9 100 66     16 scalarref => sub { ${$_[1]} =~ m/^(^\d+(?:\.\d+)?)$/ ? $_[1] : do { ${$_[1]} =~ s/^(.*)$/$_[0]->(${$_[1]})/e; $_[1]; } && $destruct ? ${$_[1]} : $_[1]; },
  9 100       140  
  1         4  
18 12 100 100     42 scalar => sub { return undef unless defined $_[1]; eval { $_[1] = $_[0]->($_, $_[1], Encode::FB_CROAK); 1; } and last foreach @MAYBE; $_[1] =~ m/^(^\d+(?:\.\d+)?)$/ ? ($_[1] + 0) : $_[1]; }
  11 100       26  
  13         134  
  9         661  
  11         1141  
19 4     4   522 );
20             }
21              
22             sub import {
23 7     7   537 my ($pkg) = shift;
24 7 100       55 return unless my @export = @_;
25 3 50       14 my $opts = ref $export[scalar @export - 1] ? pop @export : ['UTF-8'];
26 3 50       11 @MAYBE = ref $opts eq 'HASH' ? do { $destruct = $opts->{destruct}; @{ $opts->{type} } } : @{ $opts };
  3         9  
  3         4  
  3         8  
  0         0  
27 3 50 33     28 @export = qw/maybe_decode maybe_encode/ if scalar @export == 1 && $export[0] eq 'all';
28 3         8 $caller = scalar caller();
29             {
30 4     4   31 no strict 'refs';
  4         7  
  4         1874  
  3         4  
31 3         7 do { *{"${caller}::${_}"} = \&{"${pkg}::${_}"} } foreach @export;
  6         10  
  6         172  
  6         17  
32             }
33             }
34              
35             sub maybe_decode {
36 28     28 1 1856 _maybe(shift, \&decode, \&maybe_decode, shift);
37             }
38              
39             sub maybe_encode {
40 0     0 1 0 _maybe(shift, \&encode, \&maybe_encode, shift);
41             }
42              
43             sub _maybe {
44 28     28   118 my $ref = reftype($_[0]);
45 28 100       77 return $HELP{scalar}->($_[1], $_[0]) if !$ref;
46 16 100 100     63 return $destruct ? _d_recurse($_[0], $ref, $_[2]) : _recurse($_[0], $ref, $_[2], $_[3] || {});
47             }
48              
49             sub _recurse {
50 4     4   11 my $addr = refaddr $_[0];
51             return defined $_[3]->{$addr} ? $_[0] : do { $_[3]->{$addr} = 1 } && $_[1] eq 'SCALAR' ? $HELP{scalarref}->($_[2], $_[0]) : $_[1] eq 'ARRAY'
52 4 50 66     10 ? $HELP{arrayref}->($_[2], $_[0], $_[3]) && $_[0] : $_[1] eq 'HASH' ? $HELP{hashref}->($_[2], $_[0], $_[3], 1) && $_[0] : $_[0];
    100 33        
    100 33        
    50          
53             }
54              
55             sub _d_recurse {
56 12 50   12   65 return $_[1] eq 'SCALAR' ? $HELP{scalarref}->($_[2], $_[0]) : $_[1] eq 'ARRAY' ? [ $HELP{arrayref}->($_[2], $_[0]) ] : $_[1] eq 'HASH' ? $HELP{hashref}->($_[2], $_[0], {}) : $_[0];
    100          
    100          
57             }
58              
59             1;
60              
61             __END__