File Coverage

blib/lib/Venus/Constraint.pm
Criterion Covered Total %
statement 49 52 94.2
branch 12 16 75.0
condition 2 3 66.6
subroutine 13 14 92.8
pod 7 9 77.7
total 83 94 88.3


line stmt bran cond sub pod time code
1             package Venus::Constraint;
2              
3 11     11   231 use 5.018;
  11         45  
4              
5 11     11   70 use strict;
  11         35  
  11         279  
6 11     11   65 use warnings;
  11         52  
  11         436  
7              
8 11     11   84 use Venus::Class 'attr', 'base', 'with';
  11         40  
  11         89  
9              
10 11     11   981 use Venus::Check;
  11         34  
  11         109  
11              
12             base 'Venus::Kind::Utility';
13              
14             with 'Venus::Role::Buildable';
15              
16             # ATTRIBUTES
17              
18             attr 'on_eval';
19              
20             # BUILDERS
21              
22             sub build_arg {
23 0     0 0 0 my ($self, $data) = @_;
24              
25             return {
26 0 0       0 on_eval => ref $data eq 'ARRAY' ? $data : [$data],
27             };
28             }
29              
30             sub build_args {
31 187     187 0 449 my ($self, $data) = @_;
32              
33 187 50       681 $data->{on_eval} = [] if !$data->{on_eval};
34              
35 187         541 return $data;
36             }
37              
38             # METHODS
39              
40             sub accept {
41 13     13 1 31 my ($self, $name, @args) = @_;
42              
43 13 50       29 if (!$name) {
44 0         0 return $self;
45             }
46 13 100       34 if ($self->check->can($name)) {
47 12         27 $self->check->accept($name, @args);
48             }
49             else {
50 1         4 $self->check->identity($name, @args);
51             }
52 13         196 return $self;
53             }
54              
55             sub check {
56 426     426 1 1078 my ($self, @args) = @_;
57              
58 426 100       1056 $self->{check} = $args[0] if @args;
59              
60 426   66     1704 return $self->{check} ||= Venus::Check->new;
61             }
62              
63             sub clear {
64 2     2 1 7 my ($self) = @_;
65              
66 2         7 @{$self->on_eval} = ();
  2         9  
67              
68 2         8 $self->check->clear;
69              
70 2         11 return $self;
71             }
72              
73             sub ensure {
74 10     10 1 26 my ($self, @code) = @_;
75              
76 10         16 push @{$self->on_eval}, @code;
  10         29  
77              
78 10         99 return $self;
79             }
80              
81             sub eval {
82 225     225 1 2056 my ($self, $data) = @_;
83              
84 225         580 my $result = false;
85              
86 225 100       524 if (!($result = $self->check->eval($data))) {
87 70         415 return $result;
88             }
89              
90 155         313 for my $callback (@{$self->on_eval}) {
  155         505  
91 16         33 local $_ = $data;
92 16 100       429 $result = $self->$callback($data) ? true : false;
93 16 100       52 last if !$result;
94             }
95              
96 155         697 return $result;
97             }
98              
99             sub evaler {
100 2     2 1 5 my ($self) = @_;
101              
102 2         16 return $self->defer('eval');
103             }
104              
105             sub result {
106 215     215 1 459 my ($self, $data) = @_;
107              
108 215         504 return $self->eval($data);
109             }
110              
111             1;
112              
113              
114              
115             =head1 NAME
116              
117             Venus::Constraint - Constraint Class
118              
119             =cut
120              
121             =head1 ABSTRACT
122              
123             Constraint Class for Perl 5
124              
125             =cut
126              
127             =head1 SYNOPSIS
128              
129             package main;
130              
131             use Venus::Constraint;
132              
133             my $constraint = Venus::Constraint->new;
134              
135             # $constraint->accept('float');
136              
137             # $constraint->ensure(sub{$_ > 1});
138              
139             # $constraint->result(1.01);
140              
141             # true
142              
143             =cut
144              
145             =head1 DESCRIPTION
146              
147             This package provides a mechanism for evaluating type constraints on data.
148             Built-in type constraints are handled via L.
149              
150             =cut
151              
152             =head1 INHERITS
153              
154             This package inherits behaviors from:
155              
156             L
157              
158             =cut
159              
160             =head1 INTEGRATES
161              
162             This package integrates behaviors from:
163              
164             L
165              
166             =cut
167              
168             =head1 METHODS
169              
170             This package provides the following methods:
171              
172             =cut
173              
174             =head2 accept
175              
176             accept(string $name, any @args) (Venus::Constraint)
177              
178             The accept method registers a condition via L based on the arguments
179             provided. The built-in types are defined as methods in L.
180              
181             I>
182              
183             =over 4
184              
185             =item accept example 1
186              
187             # given: synopsis
188              
189             package main;
190              
191             $constraint = $constraint->accept('float');
192              
193             # bless(..., "Venus::Constraint")
194              
195             # $constraint->result;
196              
197             # false
198              
199             # $constraint->result(1.01);
200              
201             # true
202              
203             =back
204              
205             =over 4
206              
207             =item accept example 2
208              
209             # given: synopsis
210              
211             package main;
212              
213             $constraint = $constraint->accept('number');
214              
215             # bless(..., "Venus::Constraint")
216              
217             # $constraint->result(1.01);
218              
219             # false
220              
221             # $constraint->result(1_01);
222              
223             # true
224              
225             =back
226              
227             =over 4
228              
229             =item accept example 3
230              
231             # given: synopsis
232              
233             package Example1;
234              
235             sub new {
236             bless {};
237             }
238              
239             package Example2;
240              
241             sub new {
242             bless {};
243             }
244              
245             package main;
246              
247             $constraint = $constraint->accept('object');
248              
249             # bless(..., "Venus::Constraint")
250              
251             # $constraint->result;
252              
253             # false
254              
255             # $constraint->result(qr//);
256              
257             # false
258              
259             # $constraint->result(Example1->new);
260              
261             # true
262              
263             # $constraint->result(Example2->new);
264              
265             # true
266              
267             =back
268              
269             =over 4
270              
271             =item accept example 4
272              
273             # given: synopsis
274              
275             package Example1;
276              
277             sub new {
278             bless {};
279             }
280              
281             package Example2;
282              
283             sub new {
284             bless {};
285             }
286              
287             package main;
288              
289             $constraint = $constraint->accept('Example1');
290              
291             # bless(..., "Venus::Constraint")
292              
293             # $constraint->result;
294              
295             # false
296              
297             # $constraint->result(qr//);
298              
299             # false
300              
301             # $constraint->result(Example1->new);
302              
303             # true
304              
305             # $constraint->result(Example2->new);
306              
307             # false
308              
309             =back
310              
311             =cut
312              
313             =head2 check
314              
315             check(Venus::Check $data) (Venus::Check)
316              
317             The check method gets or sets the L object used for performing
318             runtime data type validation.
319              
320             I>
321              
322             =over 4
323              
324             =item check example 1
325              
326             # given: synopsis
327              
328             package main;
329              
330             my $check = $constraint->check(Venus::Check->new);
331              
332             # bless(..., 'Venus::Check')
333              
334             =back
335              
336             =over 4
337              
338             =item check example 2
339              
340             # given: synopsis
341              
342             package main;
343              
344             $constraint->check(Venus::Check->new);
345              
346             my $check = $constraint->check;
347              
348             # bless(..., 'Venus::Check')
349              
350             =back
351              
352             =cut
353              
354             =head2 clear
355              
356             clear() (Venus::Constraint)
357              
358             The clear method resets the L attributes and returns the invocant.
359              
360             I>
361              
362             =over 4
363              
364             =item clear example 1
365              
366             # given: synopsis
367              
368             package main;
369              
370             $constraint->accept('string');
371              
372             $constraint = $constraint->clear;
373              
374             # bless(..., "Venus::Constraint")
375              
376             =back
377              
378             =cut
379              
380             =head2 ensure
381              
382             ensure(coderef $code) (Venus::Constraint)
383              
384             The ensure method registers a custom (not built-in) constraint condition and
385             returns the invocant.
386              
387             I>
388              
389             =over 4
390              
391             =item ensure example 1
392              
393             # given: synopsis
394              
395             package main;
396              
397             $constraint->accept('number');
398              
399             my $ensure = $constraint->ensure(sub {
400             $_ >= 0
401             });
402              
403             # bless(.., "Venus::Constraint")
404              
405             =back
406              
407             =over 4
408              
409             =item ensure example 2
410              
411             # given: synopsis
412              
413             package main;
414              
415             $constraint->accept('number');
416              
417             my $ensure = $constraint->ensure(sub {
418             my ($source, $value) = @_;
419              
420             if ($value >= 0) {
421             return 1;
422             }
423             else {
424             return 0;
425             }
426             });
427              
428             # bless(..., "Venus::Constraint")
429              
430             =back
431              
432             =cut
433              
434             =head2 eval
435              
436             eval(any $data) (boolean)
437              
438             The eval method dispatches to the L object as well as evaluating any
439             custom conditions, and returns true if all conditions pass, and false if any
440             condition fails.
441              
442             I>
443              
444             =over 4
445              
446             =item eval example 1
447              
448             # given: synopsis
449              
450             package main;
451              
452             $constraint->accept('float');
453              
454             $constraint->ensure(sub{$_ >= 1});
455              
456             my $eval = $constraint->eval('1.00');
457              
458             # true
459              
460             =back
461              
462             =over 4
463              
464             =item eval example 2
465              
466             # given: synopsis
467              
468             package main;
469              
470             $constraint->accept('float');
471              
472             $constraint->ensure(sub{$_ >= 1});
473              
474             my $eval = $constraint->eval('0.99');
475              
476             # false
477              
478             =back
479              
480             =cut
481              
482             =head2 evaler
483              
484             evaler(any @args) (coderef)
485              
486             The evaler method returns a coderef which calls the L method with the
487             invocant when called.
488              
489             I>
490              
491             =over 4
492              
493             =item evaler example 1
494              
495             # given: synopsis
496              
497             package main;
498              
499             my $evaler = $constraint->evaler;
500              
501             # sub{...}
502              
503             # my $result = $evaler->();
504              
505             # false
506              
507             =back
508              
509             =over 4
510              
511             =item evaler example 2
512              
513             # given: synopsis
514              
515             package main;
516              
517             my $evaler = $constraint->accept('any')->evaler;
518              
519             # sub{...}
520              
521             # my $result = $evaler->();
522              
523             # true
524              
525             =back
526              
527             =cut
528              
529             =head2 result
530              
531             result(any $data) (boolean)
532              
533             The result method dispatches to the L method and returns the result.
534              
535             I>
536              
537             =over 4
538              
539             =item result example 1
540              
541             # given: synopsis
542              
543             package main;
544              
545             $constraint->accept('float');
546              
547             $constraint->ensure(sub{$_ >= 1});
548              
549             my $result = $constraint->result('1.00');
550              
551             # true
552              
553             =back
554              
555             =over 4
556              
557             =item result example 2
558              
559             # given: synopsis
560              
561             package main;
562              
563             $constraint->accept('float');
564              
565             $constraint->ensure(sub{$_ >= 1});
566              
567             my $result = $constraint->result('0.99');
568              
569             # false
570              
571             =back
572              
573             =cut
574              
575             =head1 AUTHORS
576              
577             Awncorp, C
578              
579             =cut
580              
581             =head1 LICENSE
582              
583             Copyright (C) 2000, Awncorp, C.
584              
585             This program is free software, you can redistribute it and/or modify it under
586             the terms of the Apache license version 2.0.
587              
588             =cut