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   336741 use 5.006;
  4         57  
4 4     4   27 use strict;
  4         8  
  4         77  
5 4     4   19 use warnings;
  4         8  
  4         126  
6              
7 4     4   23 use Scalar::Util qw/reftype refaddr/;
  4         21  
  4         234  
8 4     4   693 use Encode qw/decode encode/;
  4         10544  
  4         1913  
9              
10             our $VERSION = '0.18';
11             our (%HELP, @MAYBE, $caller, $destruct);
12             BEGIN {
13             %HELP = (
14 4         9 arrayref => sub { return map { $_[0]->($_, $_[2]) } @{ $_[1] } },
  15         41  
  4         16  
15             hashref => sub { $caller->can('filter_keys') && $caller->filter_keys($_[1]->{$_}, $_) and next or
16 3   33     17 $destruct && do { $_[3]{$_[0]->($_)} = $_[0]->($_[1]->{$_}, $_[2]) } || do { $_[1]->{$_} = $_[0]->($_[1]->{$_}, $_[2]) } for keys %{ $_[1] }; $_[3]; },
  3   50     64  
  2   66     8  
  1   66     4  
  3   0     36  
17 9 100 66     13 scalarref => sub { ${$_[1]} =~ m/^(^\d+(?:\.\d+)?)$/ ? $_[1] : do { ${$_[1]} =~ s/^(.*)$/$_[0]->(${$_[1]})/e; $_[1]; } && $destruct ? ${$_[1]} : $_[1]; },
  9 100       122  
  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       27  
  13         140  
  9         638  
  11         1230  
19 4     4   575 );
20             }
21              
22             sub import {
23 7     7   589 my ($pkg) = shift;
24 7 100       59 return unless my @export = @_;
25 3 50       15 my $opts = ref $export[scalar @export - 1] ? pop @export : ['UTF-8'];
26 3 50       13 @MAYBE = ref $opts eq 'HASH' ? do { $destruct = $opts->{destruct}; @{ $opts->{type} } } : @{ $opts };
  3         6  
  3         3  
  3         9  
  0         0  
27 3 50 33     34 @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         1938  
  3         3  
31 3         6 do { *{"${caller}::${_}"} = \&{"${pkg}::${_}"} } foreach @export;
  6         11  
  6         183  
  6         16  
32             }
33             }
34              
35             sub maybe_decode {
36 28     28 1 2026 _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   128 my $ref = reftype($_[0]);
45 28 100       79 return $HELP{scalar}->($_[1], $_[0]) if !$ref;
46 16 100 100     68 return $destruct ? _d_recurse($_[0], $ref, $_[2]) : _recurse($_[0], $ref, $_[2], $_[3] || {});
47             }
48              
49             sub _recurse {
50 4     4   10 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     11 ? $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   83 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__