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   332167 use 5.006;
  4         58  
4 4     4   22 use strict;
  4         6  
  4         85  
5 4     4   19 use warnings;
  4         9  
  4         110  
6              
7 4     4   22 use Scalar::Util qw/reftype refaddr/;
  4         18  
  4         217  
8 4     4   643 use Encode qw/decode encode/;
  4         10018  
  4         1837  
9              
10             our $VERSION = '0.20';
11             our (%HELP, @MAYBE, $caller, $destruct);
12             BEGIN {
13             %HELP = (
14 4         8 arrayref => sub { return map { $_[0]->($_, $_[2]) } @{ $_[1] } },
  16         43  
  4         15  
15             hashref => sub { $caller->can('filter_keys') && $caller->filter_keys($_[1]->{$_}, $_) and next or
16 3   33     8 $destruct && do { $_[3]{$_[0]->($_)} = $_[0]->($_[1]->{$_}, $_[2]) } || do { $_[1]->{$_} = $_[0]->($_[1]->{$_}, $_[2]) } for keys %{ $_[1] }; $_[3]; },
  3   50     58  
  2   66     7  
  1   66     4  
  3   0     32  
17 9 100 66     12 scalarref => sub { ${$_[1]} =~ m/^(\d+(?:\.\d+)?)$/ ? $_[1] : do { ${$_[1]} =~ s/^(.*)$/$_[0]->(${$_[1]})/e; $_[1]; } && $destruct ? ${$_[1]} : $_[1]; },
  9 100       114  
  1         4  
18 13 100 100     43 scalar => sub { return undef unless defined $_[1]; eval { $_[1] = $_[0]->($_, $_[1], Encode::FB_CROAK); 1; } and last foreach @MAYBE; $_[1] =~ m/^((?!0\d)^\d+(?:\.\d+)?)$/ ? ($_[1] + 0) : $_[1]; }
  12 100       30  
  14         147  
  10         683  
  12         1151  
19 4     4   510 );
20             }
21              
22             sub import {
23 7     7   612 my ($pkg) = shift;
24 7 100       56 return unless my @export = @_;
25 3 50       15 my $opts = ref $export[scalar @export - 1] ? pop @export : ['UTF-8'];
26 3 50       10 @MAYBE = ref $opts eq 'HASH' ? do { $destruct = $opts->{destruct}; @{ $opts->{type} } } : @{ $opts };
  3         6  
  3         4  
  3         10  
  0         0  
27 3 50 33     29 @export = qw/maybe_decode maybe_encode/ if scalar @export == 1 && $export[0] eq 'all';
28 3         8 $caller = scalar caller();
29             {
30 4     4   29 no strict 'refs';
  4         7  
  4         1903  
  3         5  
31 3         7 do { *{"${caller}::${_}"} = \&{"${pkg}::${_}"} } foreach @export;
  6         7  
  6         170  
  6         20  
32             }
33             }
34              
35             sub maybe_decode {
36 29     29 1 2020 _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 29     29   115 my $ref = reftype($_[0]);
45 29 100       79 return $HELP{scalar}->($_[1], $_[0]) if !$ref;
46 16 100 100     64 return $destruct ? _d_recurse($_[0], $ref, $_[2]) : _recurse($_[0], $ref, $_[2], $_[3] || {});
47             }
48              
49             sub _recurse {
50 4     4   12 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   53 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__