File Coverage

blib/lib/HTML/FormHandler/Types.pm
Criterion Covered Total %
statement 15 15 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 20 20 100.0


line stmt bran cond sub pod time code
1             package HTML::FormHandler::Types;
2             # ABSTRACT: Moose type constraints
3             $HTML::FormHandler::Types::VERSION = '0.40067';
4 4     4   166979 use strict;
  4         8  
  4         94  
5 4     4   14 use warnings;
  4         5  
  4         171  
6              
7 4         41 use MooseX::Types -declare => [
8             'PositiveNum', 'PositiveInt', 'NegativeNum', 'NegativeInt',
9             'SingleDigit', 'SimpleStr', 'NonEmptySimpleStr', 'Password',
10             'StrongPassword', 'NonEmptyStr', 'Email', 'State',
11             'Zip', 'IPAddress', 'NoSpaces', 'WordChars',
12             'NotAllDigits', 'Printable', 'PrintableAndNewline', 'SingleWord',
13             'Collapse', 'Upper', 'Lower', 'Trim',
14 4     4   1742 ];
  4         1080095  
15              
16             our $class_messages = {
17             PositiveNum => "Must be a positive number",
18             PositiveInt => "Must be a positive integer",
19             NegativeNum => "Must be a negative number",
20             NegativeInt => "Must be a negative integer",
21             SingleDigit => "Must be a single digit",
22             SimpleStr => 'Must be a single line of no more than 255 chars',
23             NonEmptySimpleStr => "Must be a non-empty single line of no more than 255 chars",
24             Password => "Must be between 4 and 255 chars",
25             StrongPassword =>"Must be between 8 and 255 chars, and contain a non-alpha char",
26             NonEmptyStr => "Must not be empty",
27             State => "Not a valid state",
28             Email => "Email is not valid",
29             Zip => "Zip is not valid",
30             IPAddress => "Not a valid IP address",
31             NoSpaces =>'Must not contain spaces',
32             WordChars => 'Must be made up of letters, digits, and underscores',
33             NotAllDigits => 'Must not be all digits',
34             Printable => 'Field contains non-printable characters',
35             PrintableAndNewline => 'Field contains non-printable characters',
36             SingleWord => 'Field must contain a single word',
37             };
38              
39 4     4   39397 use MooseX::Types::Moose ( 'Str', 'Num', 'Int' );
  4         40563  
  4         35  
40              
41              
42             subtype PositiveNum, as Num, where { $_ >= 0 }, message { "Must be a positive number" };
43              
44             subtype PositiveInt, as Int, where { $_ >= 0 }, message { "Must be a positive integer" };
45              
46             subtype NegativeNum, as Num, where { $_ <= 0 }, message { "Must be a negative number" };
47              
48             subtype NegativeInt, as Int, where { $_ <= 0 }, message { "Must be a negative integer" };
49              
50             subtype SingleDigit, as PositiveInt, where { $_ <= 9 }, message { "Must be a single digit" };
51              
52             subtype SimpleStr,
53             as Str,
54             where { ( length($_) <= 255 ) && ( $_ !~ m/\n/ ) },
55             message { $class_messages->{SimpleStr} };
56              
57             subtype NonEmptySimpleStr,
58             as SimpleStr,
59             where { length($_) > 0 },
60             message { $class_messages->{NonEmptySimpleStr} };
61              
62             subtype Password,
63             as NonEmptySimpleStr,
64             where { length($_) >= 4 && length($_) <= 255 },
65             message { $class_messages->{Password} };
66              
67             subtype StrongPassword,
68             as Password,
69             where { ( length($_) >= 8 ) && length($_) <= 255 && (m/[^a-zA-Z]/) },
70             message { $class_messages->{StrongPassword} };
71              
72             subtype NonEmptyStr, as Str, where { length($_) > 0 }, message { $class_messages->{NonEmptyStr} };
73              
74             subtype State, as Str, where {
75             my $value = $_;
76             my $state = <<EOF;
77             AL AK AZ AR CA CO CT DE FL GA HI ID IL IN IA KS KY LA ME MD
78             MA MI MN MS MO MT NE NV NH NJ NM NY NC ND OH OK OR PA PR RI
79             SC SD TN TX UT VT VA WA WV WI WY DC AP FP FPO APO GU VI
80             EOF
81             return ( $state =~ /\b($value)\b/i );
82             }, message { $class_messages->{State} };
83              
84             subtype Email, as Str, where {
85             my $value = shift;
86             require Email::Valid;
87             my $valid;
88             return ( $valid = Email::Valid->address($value) ) &&
89             ( $valid eq $value );
90             }, message { $class_messages->{Email} };
91              
92             subtype Zip,
93             as Str,
94             where { /^(\s*\d{5}(?:[-]\d{4})?\s*)$/ },
95             message { $class_messages->{Zip} };
96              
97             subtype IPAddress, as Str, where {
98             /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
99             }, message { $class_messages->{IPAddress} };
100              
101             subtype NoSpaces,
102             as Str,
103             where { ! /\s/ },
104             message { $class_messages->{NoSpaces} };
105              
106             subtype WordChars,
107             as Str,
108             where { ! /\W/ },
109             message { $class_messages->{WordChars} };
110              
111             subtype NotAllDigits,
112             as Str,
113             where { ! /^\d+$/ },
114             message { $class_messages->{NotAllDigits} };
115              
116             subtype Printable,
117             as Str,
118 4     4   19486 where { /^\p{IsPrint}*\z/ },
  4         29  
  4         53  
119             message { $class_messages->{Printable} };
120              
121             subtype PrintableAndNewline,
122             as Str,
123             where { /^[\p{IsPrint}\n]*\z/ },
124             message { $class_messages->{PrintableAndNewline} };
125              
126             subtype SingleWord,
127             as Str,
128             where { /^\w*\z/ },
129             message { $class_messages->{SingleWord} };
130              
131             subtype Collapse,
132             as Str,
133             where{ ! /\s{2,}/ };
134              
135             coerce Collapse,
136             from Str,
137             via { s/\s+/ /g; return $_; };
138              
139             subtype Lower,
140             as Str,
141             where { ! /[[:upper:]]/ };
142              
143             coerce Lower,
144             from Str,
145             via { lc };
146              
147             subtype Upper,
148             as Str,
149             where { ! /[[:lower:]]/ };
150              
151             coerce Upper,
152             from Str,
153             via { uc };
154              
155             subtype Trim,
156             as Str,
157             where { ! /^\s+/ &&
158             ! /\s+$/ };
159              
160             coerce Trim,
161             from Str,
162             via { s/^\s+// &&
163             s/\s+$//;
164             return $_; };
165              
166             1;
167              
168             __END__
169              
170             =pod
171              
172             =encoding UTF-8
173              
174             =head1 NAME
175              
176             HTML::FormHandler::Types - Moose type constraints
177              
178             =head1 VERSION
179              
180             version 0.40067
181              
182             =head1 SYNOPSIS
183              
184             These types are provided by MooseX::Types. These types must not be quoted
185             when they are used:
186              
187             has 'posint' => ( is => 'rw', isa => PositiveInt);
188             has_field 'email' => ( apply => [ Email ] );
189              
190             Types declared using Moose::Util::TypeConstraints, on the other hand,
191             must be quoted:
192              
193             has_field 'text_both' => ( apply => [ PositiveInt, 'GreaterThan10' ] );
194              
195             To import these types into your forms, you must either specify (':all')
196             or list the types you want to use:
197              
198             use HTML::FormHandler::Types (':all');
199              
200             or:
201              
202             use HTML::FormHandler::Types ('Email', 'PositiveInt');
203              
204             =head1 DESCRIPTION
205              
206             It would be possible to import the MooseX types (Common, etc), but for now
207             we'll just re-implement them here in order to be able to change the
208             messages and keep control of what types we provide.
209              
210             From MooseX::Types::Common:
211              
212             'PositiveNum', 'PositiveInt', 'NegativeNum', 'NegativeInt', 'SingleDigit',
213             'SimpleStr', 'NonEmptySimpleStr', 'Password', 'StrongPassword', 'NonEmptyStr',
214              
215             =head1 Type Constraints
216              
217             These types check the value and issue an error message.
218              
219             =over
220              
221             =item Email
222              
223             Uses Email::Valid
224              
225             =item State
226              
227             Checks that the state is in a list of two uppercase letters.
228              
229             =item Zip
230              
231             =item IPAddress
232              
233             Must be a valid IPv4 address.
234              
235             =item NoSpaces
236              
237             No spaces in string allowed.
238              
239             =item WordChars
240              
241             Must be made up of letters, digits, and underscores.
242              
243             =item NotAllDigits
244              
245             Might be useful for passwords.
246              
247             =item Printable
248              
249             Must not contain non-printable characters.
250              
251             =item SingleWord
252              
253             Contains a single word.
254              
255             =back
256              
257             =head2 Type Coercions
258              
259             These types will transform the value without an error message;
260              
261             =over
262              
263             =item Collapse
264              
265             Replaces multiple spaces with a single space
266              
267             =item Upper
268              
269             Makes the string all upper case
270              
271             =item Lower
272              
273             Makes the string all lower case
274              
275             =item Trim
276              
277             Trims the string of starting and ending spaces
278              
279             =back
280              
281             =head1 AUTHOR
282              
283             FormHandler Contributors - see HTML::FormHandler
284              
285             =head1 COPYRIGHT AND LICENSE
286              
287             This software is copyright (c) 2016 by Gerda Shank.
288              
289             This is free software; you can redistribute it and/or modify it under
290             the same terms as the Perl 5 programming language system itself.
291              
292             =cut