File Coverage

blib/lib/Data/TableReader/Field.pm
Criterion Covered Total %
statement 35 36 97.2
branch 21 24 87.5
condition 2 6 33.3
subroutine 9 9 100.0
pod 1 2 50.0
total 68 77 88.3


line stmt bran cond sub pod time code
1             package Data::TableReader::Field;
2 8     8   383242 use Moo 2;
  8         10170  
  8         58  
3 8     8   4577 use Carp;
  8         20  
  8         607  
4 8     8   4638 use namespace::clean;
  8         120583  
  8         61  
5              
6             # ABSTRACT: Field specification for Data::TableReader
7             our $VERSION = '0.021'; # VERSION
8              
9              
10             has name => ( is => 'ro', required => 1 );
11             *addr= \&Scalar::Util::refaddr;
12             has header => ( is => 'ro' );
13             has required => ( is => 'ro', default => sub { 1 } );
14             has trim => ( is => 'ro', default => sub { 1 } );
15             has blank => ( is => 'ro' ); # default is undef
16             has type => ( is => 'ro', isa => sub { ref $_[0] eq 'CODE' or $_[0]->can('validate') } );
17             has coerce => ( is => 'ro', isa => sub { ref $_[0] eq 'CODE' or !ref $_[0] } );
18             has array => ( is => 'ro' );
19             has follows => ( is => 'ro' );
20 115 100   115 1 263 sub follows_list { my $f= shift->follows; ref $f? @$f : defined $f? ( $f ) : () }
  115 50       527  
21              
22             sub BUILD {
23 77     77 0 587 my $self= shift;
24 77 100       652 if ($self->coerce) {
25 1 50 33     19 croak "To coerce field ".$self->name.", either 'coerce' must be a coderef or 'type' must have a ->coerce method"
      33        
26             unless ref $self->coerce eq 'CODE' or (defined $self->type && ref($self->type)->can('coerce'));
27             }
28             }
29              
30              
31             has header_regex => ( is => 'lazy' );
32              
33             sub _build_header_regex {
34 74     74   4728 my $self= shift;
35 74         214 my $h= $self->header;
36 74 100       217 unless (defined $h) {
37 63         160 $h= $self->name;
38 63         181 $h =~ s/([[:lower:]])([[:upper:]])/$1 $2/g; # split words on camelCase
39 63         189 $h =~ s/([[:alpha:]])([[:digit:]])/$1 $2/g; # or digit
40 63         135 $h =~ s/([[:digit:]])([[:alpha:]])/$1 $2/g;
41 63         148 $h =~ s/_/ /g; # then split on underscore
42             }
43 74 100       241 return $h if ref($h) eq 'Regexp';
44 70 100       404 my $pattern= join "[\\W_]*", map { $_ eq "\n"? '\n' : "\Q$_\E" } grep { defined && length }
  87 100       381  
  114         450  
45             split /(\n)|\s+|(\W)/, $h; # capture newline or non-word, except for other whitespace
46 70         11823 return qr/^[\W_]*$pattern[\W_]*$/im;
47             }
48              
49             has trim_coderef => ( is => 'lazy' );
50              
51             sub _default_trim_coderef {
52 157     157   2963 $_ =~ s/\s+$//;
53 157         651 $_ =~ s/^\s+//;
54             }
55              
56             sub _build_trim_coderef {
57 66     66   2005 my $t= shift->trim;
58 66 100       198 return undef unless $t;
59 65 100       325 return \&_default_trim_coderef if !ref $t;
60 4 100       23 return $t if ref $t eq 'CODE';
61 2 50   8   18 return sub { s/$t//g; } if ref $t eq 'Regexp';
  8         3988  
62 0           croak("Can't convert ".ref($t)." to a coderef");
63             }
64              
65             1;
66              
67             __END__