File Coverage

blib/lib/Data/InputMonster.pm
Criterion Covered Total %
statement 54 54 100.0
branch 22 30 73.3
condition 13 24 54.1
subroutine 6 6 100.0
pod 2 2 100.0
total 97 116 83.6


line stmt bran cond sub pod time code
1 1     1   30823 use strict;
  1         3  
  1         41  
2 1     1   5 use warnings;
  1         1  
  1         58  
3             package Data::InputMonster;
4             {
5             $Data::InputMonster::VERSION = '0.010';
6             }
7             # ABSTRACT: consume data from multiple sources, best first; om nom nom!
8              
9              
10 1     1   6 use Carp ();
  1         1  
  1         703  
11              
12              
13             sub new {
14 1     1 1 92 my ($class, $arg) = @_;
15            
16 1 50 33     24 Carp::confess("illegal parameters to Data::InputMonster constructor")
      33        
17             unless $arg and (keys %$arg == 1) and exists $arg->{fields};
18              
19 1         3 my $fields = $arg->{fields};
20              
21 1         10 $class->_assert_field_spec_ok($_) for values %$fields;
22              
23 1         6 bless { fields => $fields } => $class;
24             }
25              
26             sub _assert_field_spec_ok {
27 3     3   8 my ($self, $spec) = @_;
28              
29 3 50 33     20 Carp::confess("illegal or missing sources")
30             unless $spec->{sources} and ref $spec->{sources} eq 'ARRAY';
31              
32 3 50 66     14 Carp::confess("if given, filter must be a coderef")
33             if $spec->{filter} and ref $spec->{filter} ne 'CODE';
34              
35 3 50 33     17 Carp::confess("if given, check must be a coderef")
36             if $spec->{check} and ref $spec->{check} ne 'CODE';
37              
38 3 50 66     14 Carp::confess("if given, store must be a coderef")
39             if $spec->{store} and ref $spec->{store} ne 'CODE';
40              
41 3 50 50     24 Carp::confess("defaults that are references must be wrapped in code")
42             if ((ref $spec->{default})||'CODE') ne 'CODE';
43             }
44              
45              
46             sub consume {
47 4     4 1 3781 my ($self, $input, $arg) = @_;
48 4   100     17 $arg ||= {};
49              
50 1         5 my %no_default_for
51             = (! $arg->{no_default_for}) ? ()
52 4 100       19 : (ref $arg->{no_default_for}) ? (map {$_=>1} @{$arg->{no_default_for}})
  1 100       3  
53             : ($arg->{no_default_for} => 1);
54              
55 4         31 my $field = $self->{fields};
56 4         8 my %output;
57              
58 4         13 FIELD: for my $field_name (keys %$field) {
59 12         19 my $spec = $field->{$field_name};
60              
61 12         16 my $checker = $spec->{check};
62 12         16 my $filter = $spec->{filter};
63 12         16 my $storer = $spec->{store};
64              
65 12         14 my @sources = @{ $spec->{sources} };
  12         35  
66              
67 12 100       27 if (ref $sources[0]) {
68 4         7 my $i = 1;
69 4         9 @sources = map { ("source_" . $i++) => $_ } @sources;
  4         22  
70             }
71              
72 12         31 my $input_arg = { field_name => $field_name };
73              
74 12         56 SOURCE: for (my $i = 0; $i < @sources; $i += 2) {
75 23         50 my ($name, $getter) = @sources[ $i, $i + 1 ];
76 23         61 my $value = $getter->($self, $input, $input_arg);
77 23 100       185 next unless defined $value;
78 6 100       15 if ($filter) { $filter->() for $value; }
  1         5  
79 6 50 100     34 if ($checker) { $checker->() or next SOURCE for $value; }
  6         19  
80            
81 5         53 $output{ $field_name } = $value;
82 5 100       13 if ($storer) {
83 4         24 $storer->(
84             $self,
85             {
86             input => $input,
87             source => $name,
88             value => $value,
89             field_name => $field_name,
90             },
91             );
92             }
93              
94 5         47 next FIELD;
95             }
96              
97 7 100       21 my $default = $no_default_for{ $field_name } ? undef : $spec->{default};
98 7 50       33 $output{ $field_name } = ref $default ? $default->() : $default;
99             }
100              
101 4         19 return \%output;
102             }
103              
104              
105             "OM NOM NOM I EAT DATA";
106              
107             __END__