File Coverage

blib/lib/MooX/ValidateSubs/Role.pm
Criterion Covered Total %
statement 67 67 100.0
branch 29 30 96.6
condition 28 39 71.7
subroutine 8 8 100.0
pod n/a
total 132 144 91.6


line stmt bran cond sub pod time code
1             package MooX::ValidateSubs::Role;
2              
3 10     10   198497 use Moo::Role;
  10         21  
  10         96  
4 10     10   5292 use Carp qw/croak/;
  10         24  
  10         670  
5 10     10   6341 use Type::Utils qw//;
  10         668688  
  10         473  
6 10     10   7511 use Type::Params qw/compile compile_named/;
  10         1011293  
  10         133  
7 10     10   5944 use Types::Standard qw//;
  10         23  
  10         9259  
8              
9             sub _validate_sub {
10 76     76   275 my ( $self, $name, $type, $spec, @params ) = @_;
11 76         182 my $store_spec = sprintf '%s_spec', $name;
12              
13 76   66     397 my $compiled_check = ($self->$store_spec->{"compiled_$type"} ||= do {
14 28 100       118 if (ref $spec eq 'ARRAY') {
15             my @types = map {
16 12         39 my ($constraint, $default) = (@$_, 0);
  33         951  
17 33 100       125 $default eq '1' ? Types::Standard::Optional->of($constraint) : $constraint;
18             } @$spec;
19 12         230 compile(@types);
20             }
21             else {
22 16         62 my %types;
23 16         83 for my $key (keys %$spec) {
24 56         1417 my ($constraint, $default) = (@{$spec->{$key}}, 0);
  56         166  
25 56 100       222 $types{$key} =
26             $default eq '1' ? Types::Standard::Optional->of($constraint) : $constraint;
27             }
28 16         272 compile_named(%types);
29             }
30             });
31              
32 76         1269106 my @count = ( scalar @params );
33 76 100       310 if ( ref $spec eq 'ARRAY' ) {
34 36         83 push @count, scalar @{$spec};
  36         86  
35              
36 36 100 33     68 @params = $self->_preprocess_params(@params) and $count[0] = scalar @params if ( do {
37 36         71 my $preprocess = $count[0];
38 36 100 66     342 $_ == 0 || ! $_ % 2 ? $params[$_] =~ m/[0-9]+/ && $params[$_] <= $count[1] ? next : do { $preprocess = 0 } && last : next foreach 0 .. $count[0] - 1;
    100 100        
      50        
39 36         125 $preprocess;
40             } );
41              
42 36 100 100     149 if ( $count[0] == 1 && $count[1] != 1 and ref $params[0] eq 'ARRAY' ) {
      100        
43 4         8 @params = @{ $params[0] };
  4         12  
44 4         10 $count[0] = scalar @params;
45 4         8 $count[3] = 'ref';
46             }
47              
48 36         108 $count[2] = $count[1] - grep { $spec->[$_]->[1] } 0 .. $count[1] - 1;
  105         249  
49 36 100 66     1609 $count[0] >= $count[2] && $count[0] <= $count[1]
50             or croak sprintf 'Error - Invalid count in %s for sub - %s - expected - %s - got - %s',
51             $type, $name, $count[1], $count[0];
52              
53 29         79 foreach ( 0 .. $count[1] - 1 ) {
54 82 50 100     512 not $params[$_] and $spec->[$_]->[1]
      33        
      66        
55             and ( $spec->[$_]->[1] =~ m/^1$/ and next or $params[$_] = $self->_default( $spec->[$_]->[1] ) );
56             }
57              
58 29         114 @params = $compiled_check->(@params);
59 29 100       593 return defined $count[3] ? \@params : @params;
60             }
61              
62 40 100       201 my %para = $count[0] == 1 ? %{ $params[0] } : @params;
  6         28  
63 40         85 my %cry = ( %{$spec}, %para );
  40         252  
64 40         186 foreach ( keys %cry ) {
65             not $para{$_} and $spec->{$_}->[1]
66 139 100 100     1431 and ( $spec->{$_}->[1] =~ m/^1$/ and next or $para{$_} = $self->_default( $spec->{$_}->[1] ) );
      33        
      100        
67             }
68              
69 40         202 my $paraRef = $compiled_check->(\%para);
70              
71 28 100       1242 return $count[0] == 1 ? $paraRef : %{$paraRef};
  23         255  
72             }
73              
74             sub _default {
75 80     80   197 my ( $self, $default ) = @_;
76              
77 80 100       234 if ( ref $default eq 'CODE' ) {
78 62         243 return $default->();
79             }
80 18         118 return $self->$default;
81             }
82              
83             sub _preprocess_params {
84 8     8   36 my ($self, %params) = @_;
85              
86 8         14 my @world;
87 8         35 map { $world[$_] = $params{$_} } sort keys %params;
  10         66  
88 8         49 return @world;
89             }
90              
91             1;
92