File Coverage

blib/lib/Hash/Transform.pm
Criterion Covered Total %
statement 41 42 97.6
branch 17 30 56.6
condition 2 6 33.3
subroutine 9 9 100.0
pod 4 4 100.0
total 73 91 80.2


line stmt bran cond sub pod time code
1             package Hash::Transform;
2              
3 2     2   54138 use warnings;
  2         4  
  2         70  
4 2     2   14 use strict;
  2         4  
  2         100  
5              
6             our $VERSION = '0.01';
7              
8 2     2   13 use Carp ();
  2         13  
  2         1216  
9              
10              
11              
12             sub new {
13 1     1 1 40 my $class = shift;
14 1         6 my $self = bless {}, $class;
15 1         6 $self->init(@_);
16 1         4 return $self;
17             }
18              
19              
20             sub init {
21 1     1 1 2 my $self = shift;
22 1         7 $self->{rules} = {};
23 1 50       7 $self->rules(@_) if @_;
24 1         2 return $self;
25             }
26              
27              
28             sub rules {
29 1     1 1 2 my $self = shift;
30 1 50       4 Carp::croak "Missing rules" unless @_;
31 1         4 my $hash_ref = _hash_arg(@_);
32 1 50       4 Carp::croak "Invalid rules" unless $hash_ref;
33 1         3 $self->{rules} = $hash_ref;
34 1         4 return $self;
35             }
36              
37              
38             sub _apply_rule {
39 8     8   10 my ($self, $code, $data) = @_;
40 8 50 33     36 return unless defined $code && ref $data eq 'HASH';
41              
42 8 100       22 '' eq ref $code
43             and return $data->{$code};
44              
45 4 100       13 'SCALAR' eq ref $code
46             and return $$code;
47              
48 2 100       11 'CODE' eq ref $code
49             and return $code->($data);
50              
51 3         9 'ARRAY' eq ref $code
52             and return join(
53             $code->[0],
54             map {
55 1 50       9 my $entry = $self->_apply_rule($_, $data);
56 3 50       11 defined $entry ? $entry : '';
57             } @$code[1..$#$code]
58             );
59              
60             ## default
61 0         0 return;
62             }
63              
64              
65             sub apply {
66 1     1 1 816 my $self = shift;
67 1 50       3 my $source = _hash_arg (@_)
68             or Carp::croak "Invalid data set";
69 1 50       4 my $rules = $self->{rules}
70             or Carp::croak "Missing rules table";
71              
72 5         9 my %target = map {
73 1         8 my $key = $_;
74 5         13 my $value = $self->_apply_rule ($rules->{$key}, $source);
75 5         25 ($key => $value);
76             } keys %$rules;
77              
78 1 50       5 return wantarray ? %target : \%target;
79             }
80              
81              
82             sub _hash_arg {
83 2 0 33 2   21 my $hash_ref
    50          
84             = (@_ == 1 and ref $_[0] eq 'HASH') ? $_[0]
85             : (@_ % 2 == 0) ? { @_ }
86             : return
87             ;
88 2 50       11 return wantarray ? %$hash_ref : $hash_ref;
89             }
90              
91              
92              
93             1;
94              
95             __END__