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   613415 use 5.006;
  4         19  
4 4     4   25 use strict;
  4         7  
  4         152  
5 4     4   27 use warnings;
  4         20  
  4         309  
6              
7 4     4   25 use Scalar::Util qw/reftype refaddr/;
  4         9  
  4         299  
8 4     4   824 use Encode qw/decode encode/;
  4         23307  
  4         3059  
9              
10             our $VERSION = '0.21';
11             our (%HELP, @MAYBE, $caller, $destruct);
12             BEGIN {
13             %HELP = (
14 4         11 arrayref => sub { return map { $_[0]->($_, $_[2]) } @{ $_[1] } },
  16         63  
  4         51  
15             hashref => sub { $caller->can('filter_keys') && $caller->filter_keys($_[1]->{$_}, $_) and next or
16 3   33     9 $destruct && do { $_[3]{$_[0]->($_)} = $_[0]->($_[1]->{$_}, $_[2]) } || do { $_[1]->{$_} = $_[0]->($_[1]->{$_}, $_[2]) } for keys %{ $_[1] }; $_[3]; },
  3   50     77  
  2   66     10  
  1   66     5  
  3   0     62  
17 9 100 66     30 scalarref => sub { ${$_[1]} =~ m/^(\d+(?:\.\d+)?)$/ ? $_[1] : do { ${$_[1]} =~ s/^(.*)$/$_[0]->(${$_[1]})/e; $_[1]; } && $destruct ? ${$_[1]} : $_[1]; },
  9 100       147  
  1         5  
18 13 100 100     56 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       40  
  14         205  
  10         571  
  12         1684  
19 4     4   758 );
20             }
21              
22             sub import {
23 7     7   996 my ($pkg) = shift;
24 7 100       92 return unless my @export = @_;
25 3 50       37 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         7  
  3         9  
  3         12  
  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   55 no strict 'refs';
  4         8  
  4         3101  
  3         7  
31 3         8 do { *{"${caller}::${_}"} = \&{"${pkg}::${_}"} } foreach @export;
  6         10  
  6         250  
  6         22  
32             }
33             }
34              
35             sub maybe_decode {
36 29     29 1 625571 _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   70 my $ref = reftype($_[0]);
45 29 100       139 return $HELP{scalar}->($_[1], $_[0]) if !$ref;
46 16 100 100     110 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     14 ? $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   70 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__