File Coverage

blib/lib/Business/Westpac/Types.pm
Criterion Covered Total %
statement 35 35 100.0
branch 2 2 100.0
condition n/a
subroutine 11 11 100.0
pod 1 1 100.0
total 49 49 100.0


line stmt bran cond sub pod time code
1             package Business::Westpac::Types;
2              
3             =head1 NAME
4              
5             Business::Westpac::Types
6              
7             =head1 SYNOPSIS
8              
9             use Business::Westpac::Types qw/
10             add_max_string_attribute
11             /;
12              
13             has [ qw/
14             funding_bsb_number
15             / ] => (
16             is => 'ro',
17             isa => 'BSBNumber',
18             required => 0,
19             );
20              
21             ...
22              
23             =head1 DESCRIPTION
24              
25             Package for defining type constraints for use in the Business::Westpac
26             namespace.
27              
28             =cut
29              
30 11     11   87 use strict;
  11         28  
  11         450  
31 11     11   54 use warnings;
  11         24  
  11         678  
32 11     11   69 use feature qw/ signatures /;
  11         19  
  11         1484  
33              
34 11     11   89 use Moose::Util::TypeConstraints;
  11         35  
  11         162  
35 11     11   27083 no warnings qw/ experimental::signatures /;
  11         35  
  11         574  
36              
37 11     11   7198 use DateTime::Format::DateParse; ## no critic
  11         6982154  
  11         1103  
38 11     11   6856 use Mojo::Util qw/ decamelize /;
  11         2199042  
  11         1884  
39             use Exporter::Easy (
40 11         159 OK => [ qw/
41             add_max_string_attribute
42             / ],
43 11     11   7362 );
  11         23096  
44              
45             =head1 TYPES
46              
47             =over
48              
49             =item WestpacDate
50              
51             A DateTime object, this will be coerced from the string DDMMYYYY
52              
53             =cut
54              
55             class_type 'DateTime';
56              
57             subtype 'WestpacDate'
58             => as 'DateTime';
59              
60             coerce 'WestpacDate'
61             => from 'Str'
62             => via {
63             my $date_str = $_;
64              
65             return $date_str if ref( $date_str );
66              
67             my ( $dd,$mm,$yyyy ) = ( $date_str =~ /^(\d{2})(\d{2})(\d{4})$/ );
68             return DateTime::Format::DateParse->parse_datetime( "$yyyy-$mm-$dd" );
69             };
70              
71             =item PositiveInt
72              
73             An Int greater than zero
74              
75             =cut
76              
77             subtype 'PositiveInt'
78             => as 'Int'
79             => where { $_ > 0 }
80             => message { "The number provided, $_, was not positive" }
81             ;
82              
83             =item PositiveNum
84              
85             A Num greater than zero
86              
87             =cut
88              
89             subtype 'PositiveNum'
90             => as 'Num'
91             => where { $_ > 0 }
92             => message { "The number provided, $_, was not positive" }
93             ;
94              
95             =item BSBNumber
96              
97             A Str of the form C</^\d{3}-\d{3}$/>
98              
99             =cut
100              
101             subtype 'BSBNumber'
102             => as 'Str',
103             => where { $_ =~ /^\d{3}-\d{3}$/ }
104             => message { "The BSB provided, $_, does not match \\d{3}-\\d{3}" }
105             ;
106              
107             =back
108              
109             =head1 METHODS
110              
111             =head4 add_max_string_attribute
112              
113             Helper method to allow easier definition of Str types that are limited
114             to a particular lengths. For example:
115              
116              
117             __PACKAGE__->add_max_string_attribute(
118             'RecipientNumber[20]'
119             is => 'ro',
120             required => 0,
121             );
122              
123             Is equivalent to:
124              
125             subtype 'RecipientNumber'
126             => as 'Maybe[Str]'
127             => where {
128             ! defined( $_ )
129             or length( $_ ) <= 20
130             }
131             => message {
132             "The string provided for recipient_number"
133             . " was outside 1..20 chars"
134             }
135             ;
136              
137             __PACKAGE__->meta->add_attribute( 'recipient_number',
138             isa => 'RecipientNumber',
139             predicate => "_has_recipient_number",
140             is => 'ro',
141             required => 0,
142             );
143              
144             =cut
145              
146             sub add_max_string_attribute (
147 148         440 $package,
148 148         324 $name_spec,
149 148         613 %attr_spec,
150 148     148 1 565 ) {
  148         295  
151 148         1271 my ( $subtype_name,$max_length ) = ( $name_spec =~ /^(\w+)\[(\d+)\]$/ );
152 148         879 my $attr_name = decamelize( $subtype_name );
153              
154             subtype $subtype_name
155             => as 'Maybe[Str]'
156             => where {
157 231 100   231   15997 ! defined( $_ )
158             or length( $_ ) <= $max_length
159             }
160             => message {
161 2     2   144 "The string provided for $attr_name"
162             . " was outside 1..$max_length chars"
163             }
164 148         5995 ;
165              
166 148         304206 $package->meta->add_attribute( $attr_name,
167             isa => $subtype_name,
168             predicate => "_has_$attr_name",
169             %attr_spec,
170             );
171             }
172              
173             1;