File Coverage

blib/lib/Data/Tubes/Plugin/Validator.pm
Criterion Covered Total %
statement 71 71 100.0
branch 24 26 92.3
condition 12 13 92.3
subroutine 15 15 100.0
pod 6 6 100.0
total 128 131 97.7


line stmt bran cond sub pod time code
1             package Data::Tubes::Plugin::Validator;
2 8     8   1464 use strict;
  8         18  
  8         244  
3 8     8   38 use warnings;
  8         16  
  8         223  
4 8     8   38 use English qw< -no_match_vars >;
  8         15  
  8         75  
5             our $VERSION = '0.737';
6              
7 8     8   3309 use Log::Log4perl::Tiny qw< :easy :dead_if_first >;
  8         17  
  8         62  
8              
9             use Data::Tubes::Util
10 8     8   2946 qw< args_array_with_options normalize_args shorter_sub_names >;
  8         15  
  8         514  
11 8     8   3062 use Data::Tubes::Plugin::Util qw< identify >;
  8         24  
  8         8077  
12             my %global_defaults = (input => 'structured',);
13              
14             sub validate_admit {
15 28     28 1 4163 my ($validators, $args) = args_array_with_options(
16             @_,
17             {
18             input => 'raw',
19             name => 'validate with acceptance regexp',
20             }
21             );
22 28         107 identify($args);
23 28         67 my $name = $args->{name};
24 28         51 my $input = $args->{input};
25 28         47 my $refuse = $args->{refuse};
26             return sub {
27 28     28   55 my $record = shift;
28 28 100       81 my $target = defined($input) ? $record->{$input} : $record;
29 28         60 for my $validator (@$validators) {
30 35 100       239 my $outcome =
31             (ref($validator) eq 'CODE')
32             ? $validator->($target)
33             : ($target =~ m{$validator});
34 35 100 100     226 return unless ($outcome xor $refuse);
35             } ## end for my $validator (@$validators)
36 14         57 return $record;
37 28         200 };
38             } ## end sub validate_admit
39              
40             sub validate_refuse {
41 20     20 1 2959 my ($validators, $args) = args_array_with_options(
42             @_,
43             {
44             input => 'raw',
45             name => 'validate with rejection regexp',
46             }
47             );
48 20         58 $args->{refuse} = 1;
49 20         48 return validate_admit(@$validators, $args);
50             } ## end sub validate_refuse
51              
52             sub validate_refuse_comment {
53 5     5 1 1089 my $args = normalize_args(@_, {name => 'validate reject comment line'});
54 5         21 identify($args);
55 5         27 return validate_refuse(qr{(?mxs:\A \s* \#)}, $args);
56             }
57              
58             sub validate_refuse_comment_or_empty {
59 5     5 1 25 my $args = normalize_args(@_,
60             {name => 'validate reject comment or non-spaces-only line'});
61 5         21 identify($args);
62 5         26 return validate_refuse(qr{(?mxs:\A \s* (?: \# | \z ))}, $args);
63             } ## end sub validate_refuse_comment_or_empty
64              
65             sub validate_refuse_empty {
66 4     4 1 20 my $args = normalize_args(@_,
67             {name => 'validate reject empty (non-spaces only) string'});
68 4         17 identify($args);
69 4         22 return validate_refuse(qr{(?mxs:\A \s* \z)}, $args);
70             } ## end sub validate_refuse_empty
71              
72              
73             sub validate_thoroughly {
74 6     6 1 7449 my ($validators, $args) = args_array_with_options(
75             @_,
76             {
77             %global_defaults,
78             name => 'validate with subs',
79             output => 'validation',
80             keep_positives => 0,
81             keep_empty => 0,
82             wrapper => undef,
83             }
84             );
85 6         38 identify($args);
86 6         20 my $name = $args->{name};
87              
88 6         16 my $wrapper = $args->{wrapper};
89 6 100 66     35 if ($wrapper && $wrapper eq 'try') {
90 3 50       8 eval { require Try::Tiny; }
  3         1615  
91             or LOGCONFESS 'Validator::validate_with_subs '
92             . 'needs Try::Tiny, please install';
93              
94             $wrapper = sub {
95 18     18   41 my ($validator, @params) = @_;
96             return Try::Tiny::try(
97 18         1863 sub { $validator->(@params); },
98 18         83 Try::Tiny::catch(sub { return (0, $_); }),
  5         95  
99             );
100 3         6187 };
101             } ## end if ($wrapper && $wrapper...)
102              
103 6         17 my $input = $args->{input};
104 6         15 my $output = $args->{output};
105 6         15 my $keep_positives = $args->{keep_positives};
106 6         10 my $keep_empty = $args->{keep_empty};
107             return sub {
108 13     13   11179 my $record = shift;
109 13 50       51 my $target = defined($input) ? $record->{$input} : $record;
110 13         28 my @outcomes;
111 13         45 for my $i (0 .. $#$validators) {
112             my ($name, $validator, @params) =
113             (ref($validators->[$i]) eq 'ARRAY')
114 39 100       148 ? @{$validators->[$i]}
  23         60  
115             : ("validator-$i", $validators->[$i]);
116 39 100       180 my @outcome =
    100          
    100          
117             $wrapper
118             ? $wrapper->($validator, $target, $record, $args, @params)
119             : (ref($validator) eq 'CODE')
120             ? $validator->($target, $record, $args, @params)
121             : (
122             $target =~ m{$validator}
123             ? (1)
124             : (0, regex => "$validator")
125             );
126 39 100       441 push @outcome, 0 unless @outcome;
127 39 100 100     200 push @outcomes, [$name, @outcome]
128             if !$outcome[0] || $keep_positives;
129             } ## end for my $i (0 .. $#$validators)
130 13         34 $record->{$output} = undef;
131 13 100 100     51 $record->{$output} = \@outcomes if @outcomes || $keep_empty;
132 13         61 return $record;
133 6         48 };
134             } ## end sub validate_with_subs
135              
136             *validate_with_subs = \&validate_thoroughly;
137              
138             shorter_sub_names(__PACKAGE__, 'validate_');
139              
140             1;