File Coverage

blib/lib/Data/RuledValidator/Closure.pm
Criterion Covered Total %
statement 116 184 63.0
branch 27 62 43.5
condition 3 15 20.0
subroutine 4 4 100.0
pod n/a
total 150 265 56.6


line stmt bran cond sub pod time code
1             package Data::RuledValidator::Closure;
2              
3 6     6   36 use Data::RuledValidator::Util;
  6         14  
  6         792  
4 6     6   32 use strict;
  6         13  
  6         222  
5 6     6   37 use warnings qw/all/;
  6         12  
  6         20470  
6              
7             our $VERSION = 0.05;
8              
9             my $parent = 'Data::RuledValidator';
10              
11             use constant
12             {
13             IS => sub { # now this is not used, using ARE instead.
14 0         0 my($key, $c) = @_;
15 0   0     0 my $sub = $parent->_cond_op($c) || '';
16 0 0       0 unless($sub){
17 0 0       0 if($c eq 'n/a'){
18 0         0 return $c;
19             }else{
20 0         0 Carp::croak("$c is not defined. you can use; " . join ", ", $parent->_cond_op);
21             }
22             }
23 0         0 return sub {my($self, $v) = @_; $v = shift @$v; return ($sub->($self, $v) + 0)};
  0         0  
  0         0  
  0         0  
24             },
25             ISNT => sub { # now this is not used, using ARENT instead.
26 0         0 my($key, $c) = @_;
27 0         0 my $sub = $parent->_cond_op($c);
28 0 0       0 unless($sub){
29 0         0 Carp::croak("$c is not defined. you can use; " . join ", ", $parent->_cond_op);
30             }
31 0         0 return sub {my($self, $v) = @_; $v = shift @$v; return(! $sub->($self, $v) + 0)};
  0         0  
  0         0  
  0         0  
32             },
33             ARE => sub {
34 76         148 my($key, $c) = @_;
35 76 100       198 unless($c =~/,/){
36             # single condition
37 74   100     290 my $sub = $parent->_cond_op($c) || '';
38 74 100       255 unless($sub){
39 13 50       28 if($c eq 'n/a'){
40 13         44 return $c;
41             }else{
42 0         0 Carp::croak("$c is not defined. you can use; " . join ", ", $parent->_cond_op);
43             }
44             }
45 61         382 return sub {my($self, $v) = @_; return(_vand($self, $key, $c, $v, sub{my($self, $v) = @_; $sub->($self, $v)}))};
  144         237  
  144         784  
  151         255  
  151         479  
46             }else{
47 2         11 my @c = split /\s*,\s*/, $c;
48 2         8 my @sub = grep $_, map $parent->_cond_op($_), @c;
49 2 100       7 unless(@sub == @c){
50 1         8 Carp::croak("some of '@c' are not defined. you can use; " . join ", ", $parent->_cond_op);
51             }
52 1 0       51 return sub {my($self, $v) = @_; return(_vand($self, $key, $c, $v, sub{my($self, $v) = @_; foreach (@sub){$_->($self, $v) and return 1} }))};
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
53             }
54             },
55             ARENT => sub {
56 0         0 my($key, $c) = @_;
57 0 0       0 unless($c =~/,/){
58             # single condition
59 0   0     0 my $sub = $parent->_cond_op($c) || '';
60 0 0       0 unless($sub){
61 0 0       0 if($c eq 'n/a'){
62 0         0 return $c;
63             }else{
64 0         0 Carp::croak("$c is not defined. you can use; " . join ", ", $parent->_cond_op);
65             }
66             }
67 0         0 return sub {my($self, $v) = @_; return(_vand($self, $key, $c, $v, sub{my($self, $v) = @_; ! $sub->($self, $v)}))};
  0         0  
  0         0  
  0         0  
  0         0  
68             }else{
69 0         0 my @c = split /\s*,\s*/, $c;
70 0         0 my @sub = grep $parent->_cond_op($_), @c;
71 0 0       0 unless(@sub == @c){
72 0         0 Carp::croak("some of '@c' are not defined. you can use; " . join ", ", $parent->_cond_op);
73             }
74 0         0 return sub {my($self, $v) = @_; return(_vand($self, $key, $c, $v, sub{my($self, $v) = @_; ! (grep $_->($self, $v), @sub) == @sub}))};
  0         0  
  0         0  
  0         0  
  0         0  
75             }
76             },
77             MATCH => sub {
78 3         9 my($key, $c) = @_;
79 3         13 my @regex = map qr/$_/,_arg($c);
80             my $sub = sub{
81 9         16 my($self, $v) = @_;
82 9         14 my $ok = 0;
83 9         17 foreach my $regex (@regex){
84 23 100       162 $ok |= $v =~ $regex or last;
85             }
86 9         44 return $ok;
87 3         21 };
88 3         20 return sub {my($self, $v) = @_; return(_vor($self, $key, $c, $v, sub{my($self, $v) = @_; $sub->($self, $v)}))};
  9         17  
  9         59  
  9         14  
  9         26  
89             },
90             GT => sub {
91 2         5 my($key, $c, $op) = @_;
92 2         4 my $sub;
93 2 50       6 if($op eq '>='){
94 0 0       0 if($c =~s/\s*~\s*//){
95 0         0 $sub = sub{my($self, $v) = @_; return ((length($v) >= $c) + 0)}
  0         0  
96 0         0 }else{
97 0         0 $sub = sub{my($self, $v) = @_; return (($v >= $c) + 0)}
  0         0  
98 0         0 }
99             }else{
100 2 50       12 if($c =~s/\s*~\s*//){
101 0 0       0 $sub = sub{my($self, $v) = @_; return $v ? ((length($v) > $c) + 0) : ()}
  0         0  
102 0         0 }else{
103 11 50       14 $sub = sub{my($self, $v) = @_; return $v ? (($v > $c) + 0) : ()}
  11         54  
104 2         18 }
105             }
106 2         17 return sub{my($self, $v) = @_; _vand($self, $key, $c, $v, $sub)};
  8         14  
  8         28  
107             },
108             LT => sub {
109 3         9 my($key, $c, $op) = @_;
110 3         5 my $sub;
111 3 100       10 if($op eq '<='){
112 1 50       5 if($c =~s/\s*~\s*//){
113 7         14 $sub = sub{my($self, $v) = @_; return ((length($v) <= $c) + 0)}
  7         28  
114 1         9 }else{
115 0         0 $sub = sub{my($self, $v) = @_; return (($v <= $c) + 0)}
  0         0  
116 0         0 }
117             }else{
118 2 50       8 if($c =~s/\s*~\s*//){
119 0 0       0 $sub = sub{my($self, $v) = @_; return $v ? ((length($v) < $c) + 0) : ()}
  0         0  
120 0         0 }else{
121 11 50       17 $sub = sub{my($self, $v) = @_; return $v ? (($v < $c) + 0) : ()}
  11         59  
122 2         19 }
123             }
124 3         16 return sub{my($self, $v) = @_; _vand($self, $key, $c, $v, $sub)};
  15         29  
  15         78  
125             },
126             LENGTH => sub {
127 1         2 my($key, $c, $op) = @_;
128 1         3 my($start, $end) = split(/,/, $c);
129             my $sub = sub{
130 7         13 my($self, $v) = @_;
131 7         11 my $l = length($v);
132 7 50 0     39 return defined $end ? ($start <= $l and $l <= $end) : $l <= $start;
133 1         10 };
134 1         6 return sub{my($self, $v) = @_; _vand($self, $key, $c, $v, $sub)};
  7         15  
  7         21  
135             },
136             BETWEEN => sub {
137 1         3 my($key, $c, $op) = @_;
138 1         2 my $sub;
139 1 50       4 if($c =~s/\s*~\s*//){
140 0         0 my($start, $end) = split(/,/, $c);
141 0 0 0     0 $sub = sub{my($self, $v) = @_; return $v ? (($start <= length($v) and length($v) <= $end) + 0) : ()}
  0         0  
142 0         0 }else{
143 1         4 my($start, $end) = split(/,/, $c);
144 35 50 33     48 $sub = sub{my($self, $v) = @_; return $v ? (($start <= $v and $v <= $end) + 0) : ()}
  35         235  
145 1         12 }
146 1         5 return sub{my($self, $v) = @_; _vand($self, $key, $c, $v, $sub)};
  7         12  
  7         21  
147             },
148             IN => sub {
149 3         7 my($key, $c) = @_;
150 3         11 my @words = _arg($c);
151             my $sub = sub{
152 47         58 my($self, $v) = @_;
153 47         58 my $ok = 0;
154 47         72 foreach my $word (@words){
155 80 100       219 $ok |= $v eq $word or last;
156             }
157 47         9534 return $ok;
158 3         26 };
159 3         15 return sub {my($self, $v) = @_; return(_vor($self, $key, $c, $v, sub{my($self, $v) = @_; $sub->($self, $v)}))};
  26         40  
  26         124  
  47         66  
  47         96  
160             },
161             EQ => sub {
162 7         13 my($key, $c) = @_;
163 7 100       32 if($c =~s/^\[(.+)\]$/$1/){
    100          
164             return sub{
165 18         36 my($self, $v, $key) = @_;
166 18         47 my($obj, $method) = ($self->obj, $self->method);
167 18         60 return (($v->[0] eq $obj->$method($c)) + 0)
168 3         23 };
169             }elsif($c =~s/^\{(.+)\}$/$1/){
170             return sub{
171 7         15 my($self, $v, $key, $given_data) = @_;
172 7         21 my($obj, $method) = ($self->obj, $self->method);
173 7         39 return (($v->[0] eq $given_data->{$c}) + 0)
174 1         6 };
175             }else{
176             return sub{
177 3         7 my($self, $v) = @_;
178 3         17 return (($v->[0] eq $c) + 0);
179 3         14 };
180             }
181             },
182             NE => sub {
183 1         3 my($key, $c) = @_;
184 1 50       6 if($c =~s/^\[(.+)\]$/$1/){
185             return sub{
186 2         5 my($self, $v, $key) = @_;
187 2         8 my($obj, $method) = ($self->obj, $self->method);
188 2         10 return (($v->[0] ne $obj->$method($c)) + 0)
189 1         8 };
190             }else{
191             return sub{
192 0           my($self, $v) = @_;
193 0           return (($v->[0] ne $c) + 0);
194 0           };
195             }
196             },
197 6     6   99 };
  6         15  
  6         6941  
198              
199             $parent->add_operator
200             (
201             'is' => ARE,
202             'isnt' => ARENT,
203             'are' => ARE,
204             'arent' => ARENT,
205             're' => MATCH,
206             'match' => MATCH,
207             'length' => LENGTH,
208             '>' => GT,
209             '>=' => GT,
210             '<' => LT,
211             '<=' => LT,
212             'between' => BETWEEN,
213             'in' => IN,
214             'eq' => EQ,
215             'ne' => NE,
216             'equal' => EQ,
217             'not_equal' => NE,
218             'has' =>
219             sub {
220             my($key, $c) = @_;
221             if(my($e, $n) = $c =~m{^\s*([<>])?\s*(\d+)$}){
222             $e ||= '';
223             if($e eq '<'){
224             return sub{my($self, $v) = @_; return @$v < $n}
225             }elsif($e eq '>'){
226             return sub{my($self, $v) = @_; return @$v > $n}
227             }else{
228             return sub{my($self, $v) = @_; return @$v == $n}
229             }
230             }else{
231             Carp::croak("$c is not number");
232             }
233             },
234             'of-valid' =>
235             sub {
236             my($key, $c) = @_;
237             my @cond = _arg($c);
238             return
239             sub {
240             my($self, $values, $alias, $given_data, $validate_data) = @_;
241             my($obj, $method) = ($self->obj, $self->method);
242             my $ok = 0;
243             my $n = 0;
244             foreach my $k (@cond){
245             next unless $k;
246             if($self->valid_yet($k)){
247             $self->{valid} &= $self->_validate($k, @$validate_data);
248             }
249             ++$ok if $self->valid_ok($k);
250             ++$n;
251             }
252             return $key eq 'all' ? ($ok == $n) + 0 : ($ok == $key) + 0 ;
253             }, NEED_ALIAS | ALLOW_NO_VALUE;
254             },
255             'of' =>
256             sub {
257             my($key, $c) = @_;
258             my @cond = _arg($c);
259             return
260             sub {
261             my($self, $values, $alias) = @_;
262             my($obj, $method) = ($self->obj, $self->method);
263             my $ok = 0;
264             my $n = 0;
265             foreach my $k (@cond){
266             next unless $k;
267             ++$ok if defined $obj->$method($k);
268             ++$n;
269             }
270             return $key eq 'all' ? ($ok == $n) + 0 : ($ok == $key) + 0 ;
271             }, NEED_ALIAS | ALLOW_NO_VALUE;
272             },
273             );
274              
275             1;
276              
277             =head1 Name
278              
279             Data::RuledValidator::Closure - sobroutines to create closure using by Data::RuledValidator
280              
281             =head1 Description
282              
283             =head1 Synopsys
284              
285             =head1 Author
286              
287             Ktat, Ektat@cpan.orgE
288              
289             =head1 Copyright
290              
291             Copyright 2006-2007 by Ktat
292              
293             This program is free software; you can redistribute it
294             and/or modify it under the same terms as Perl itself.
295              
296             See http://www.perl.com/perl/misc/Artistic.html
297              
298             =cut