File Coverage

blib/lib/Brick/Numbers.pm
Criterion Covered Total %
statement 49 59 83.0
branch 3 16 18.7
condition 7 24 29.1
subroutine 14 19 73.6
pod 0 1 0.0
total 73 119 61.3


line stmt bran cond sub pod time code
1             package Brick::Numbers;
2 5     5   45 use strict;
  5         10  
  5         169  
3              
4 5     5   25 use base qw(Exporter);
  5         10  
  5         476  
5 5     5   32 use vars qw($VERSION);
  5         9  
  5         274  
6              
7             $VERSION = '0.901';
8              
9             package Brick::Bucket;
10 5     5   43 use strict;
  5         14  
  5         420  
11              
12              
13             =encoding utf8
14              
15             =head1 NAME
16              
17             Brick - This is the description
18              
19             =head1 SYNOPSIS
20              
21             use Brick;
22              
23             =head1 DESCRIPTION
24              
25             =cut
26              
27             =over 4
28              
29             =item number_within_range( HASHREF )
30              
31             Hash fields:
32              
33             minimum - the lower bound
34             maximum - the higher bound
35             inclusive - true includes bounds, false excludes bounds
36              
37             =cut
38              
39             sub number_within_range
40             {
41 2     2 0 4 my( $bucket, $setup ) = @_;
42              
43 2         4 my @missing = sort grep { ! defined $setup->{$_} } qw( minimum maximum );
  4         12  
44              
45 2 50       6 if( @missing )
46             {
47 5     5   41 no warnings 'uninitialized';
  5         27  
  5         1810  
48 0 0       0 croak( sprintf "number_within_range missing %s%s attibute%s",
    0          
49             $missing[0],
50             $missing[1] ? " and $missing[1]" : '',
51             $missing[1] ? 's' : ''
52             );
53             }
54              
55 2         14 my $format_sub = $bucket->_is_decimal_integer( $setup );
56              
57             my $range_sub = $setup->{inclusive} ?
58 2 100       11 $bucket->_inclusive_within_numeric_range( $setup )
59             :
60             $bucket->_exclusive_within_numeric_range( $setup );
61              
62 2         8 my $composed_sub = $bucket->__compose_satisfy_all( $format_sub, $range_sub );
63              
64 2         7 $bucket->__make_constraint( $composed_sub, $setup );
65             }
66              
67             sub _is_only_decimal_digits
68             {
69 0     0   0 my( $bucket, $setup ) = @_;
70              
71 0         0 my @caller = $bucket->__caller_chain_as_list();
72              
73             my $sub = $bucket->_matches_regex( {
74             description => "The $setup->{field} value only has decimal digits",
75             field => $setup->{field},
76 0   0     0 name => $setup->{name} || $caller[0]{'sub'},
77             regex => qr/
78             \A
79             \d+ # digits only
80             \z
81             /x,
82             } );
83              
84 0         0 my $composed = $bucket->__compose_satisfy_all( $sub );
85              
86             $bucket->add_to_bucket( {
87 0         0 name => $caller[0]{'sub'},
88             code => $composed,
89             } );
90             }
91              
92             sub _is_decimal_integer
93             {
94 2     2   5 my( $bucket, $setup ) = @_;
95              
96 2         7 my @caller = $bucket->__caller_chain_as_list();
97              
98 5     5   59 no warnings 'uninitialized';
  5         9  
  5         5191  
99             my $sub = $bucket->_matches_regex( {
100             description => "The $setup->{field} is an integer in base 10",
101             field => $setup->{field},
102 2   33     28 name => $setup->{name} || $caller[0]{'sub'},
103             regex => qr/
104             \A
105             (?:[+-])? # optional leading sign
106             \d+
107             \z
108             /x,
109             } );
110              
111 2         19 my $composed = $bucket->__compose_satisfy_all( $sub );
112              
113             $bucket->add_to_bucket( {
114 2         60 name => $caller[0]{'sub'},
115             code => $composed,
116             } );
117             }
118              
119             sub _inclusive_within_numeric_range
120             {
121 1     1   3 my( $bucket, $setup ) = @_;
122              
123 1         3 my @caller = $bucket->__caller_chain_as_list();
124              
125             $bucket->add_to_bucket( {
126             name => $setup->{name} || $caller[0]{'sub'},
127             description => "Find number within the range [$setup->{minimum}, $setup->{maximum}] inclusively",
128 1   33     16 fields => [ $setup->{field} ],
129             code => $bucket->__compose_satisfy_all(
130             $bucket->_numeric_equal_or_greater_than( $setup ),
131             $bucket->_numeric_equal_or_less_than( $setup ),
132             ),
133             } );
134             }
135              
136             sub _exclusive_within_numeric_range
137             {
138 1     1   5 my( $bucket, $setup ) = @_;
139              
140 1         4 my @caller = $bucket->__caller_chain_as_list();
141              
142             $bucket->add_to_bucket( {
143             name => $setup->{name} || $caller[0]{'sub'},
144             description => "Find number within the range [$setup->{minimum}, $setup->{maximum}] exclusively",
145 1   33     14 fields => [ $setup->{field} ],
146             code => $bucket->__compose_satisfy_all(
147             $bucket->_numeric_strictly_greater_than( $setup ),
148             $bucket->_numeric_strictly_less_than( $setup ),
149             ),
150             } );
151              
152             }
153              
154             sub _numeric_equal_or_greater_than
155             {
156 1     1   4 my( $bucket, $setup ) = @_;
157              
158 1         3 my @caller = $bucket->__caller_chain_as_list();
159              
160             $bucket->add_to_bucket({
161             name => $setup->{name} || $caller[0]{'sub'},
162             description => "The number is equal to or greater than $setup->{minimum}",
163             fields => [ $setup->{field} ],
164             code => sub {
165             die {
166             message => "The number in $setup->{field} was $_[0]->{ $setup->{field} }, but should have been greater than or equal to $setup->{minimum}",
167             failed_field => $setup->{field},
168             handler => $caller[0]{'sub'},
169             } unless $_[0]->{ $setup->{field} } >= $setup->{minimum}
170 0 0   0   0 },
171 1   33     13 } );
172             }
173              
174             sub _numeric_strictly_greater_than
175             {
176 1     1   14 my( $bucket, $setup ) = @_;
177              
178 1         5 my @caller = $bucket->__caller_chain_as_list();
179              
180             $bucket->add_to_bucket({
181             name => $setup->{name} || $caller[0]{'sub'},
182             description => "The number is greater than $setup->{minimum}",
183             fields => [ $setup->{field} ],
184             code => sub {
185             die {
186             message => "The number in $setup->{field} was $_[0]->{ $setup->{field} }, but should have been strictly greater than $setup->{minimum}",
187             failed_field => $setup->{field},
188             handler => $caller[0]{'sub'},
189 0 0   0   0 } unless $_[0]->{ $setup->{field} } > $setup->{minimum};
190             },
191 1   33     29 } );
192             }
193              
194             sub _numeric_equal_or_less_than
195             {
196 1     1   4 my( $bucket, $setup ) = @_;
197              
198 1         3 my @caller = $bucket->__caller_chain_as_list();
199              
200             $bucket->add_to_bucket({
201             name => $setup->{name} || $caller[0]{'sub'},
202             description => "The number is equal to or less than $setup->{maximum}",
203             fields => [ $setup->{field} ],
204             code => sub {
205             die {
206             message => "The number in $setup->{field} was $_[0]->{ $setup->{field} }, but should have been less than or equal to $setup->{maximum}",
207             failed_field => $setup->{field},
208             handler => $caller[0]{'sub'},
209 0 0   0   0 } unless $_[0]->{ $setup->{field} } <= $setup->{maximum};
210             },
211 1   33     27 } );
212             }
213              
214             sub _numeric_strictly_less_than
215             {
216 1     1   3 my( $bucket, $setup ) = @_;
217              
218 1         4 my @caller = $bucket->__caller_chain_as_list();
219              
220             $bucket->add_to_bucket({
221             name => $setup->{name} || $caller[0]{'sub'},
222             description => "The number is less than $setup->{maximum}",
223             fields => [ $setup->{field} ],
224             code => sub {
225             die {
226             message => "The number in $setup->{field} was $_[0]->{ $setup->{field} }, but should have been strictly less than $setup->{maximum}",
227             failed_field => $setup->{field},
228             handler => $caller[0]{'sub'},
229 0 0   0     } unless $_[0]->{ $setup->{field} } < $setup->{maximum};
230             },
231 1   33     13 } );
232             }
233              
234             =back
235              
236             =head1 TO DO
237              
238             TBA
239              
240             =head1 SEE ALSO
241              
242             TBA
243              
244             =head1 SOURCE AVAILABILITY
245              
246             This source is in Github:
247              
248             https://github.com/briandfoy/brick
249              
250             =head1 AUTHOR
251              
252             brian d foy, C<< >>
253              
254             =head1 COPYRIGHT
255              
256             Copyright © 2007-2021, brian d foy . All rights reserved.
257              
258             You may redistribute this under the terms of the Artistic License 2.0.
259              
260             =cut
261              
262             1;