File Coverage

blib/lib/HTML/FormHandler/Types.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


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