File Coverage

blib/lib/Number/Phone/BR.pm
Criterion Covered Total %
statement 46 61 75.4
branch 19 24 79.1
condition 6 12 50.0
subroutine 10 24 41.6
pod 16 18 88.8
total 97 139 69.7


line stmt bran cond sub pod time code
1             package Number::Phone::BR;
2             # ABSTRACT: Brazilian phone numbers
3 4     4   86455 use Moo;
  4         76322  
  4         27  
4 4     4   7966 use Carp qw/confess/;
  4         23  
  4         277  
5 4     4   2563 use Number::Phone::BR::Areas qw/code2name mobile_phone_digits_by_area/;
  4         11  
  4         3854  
6             extends 'Moo::Object', 'Number::Phone';
7              
8             our $VERSION = '0.001'; # VERSION
9              
10 8     8 1 31 sub country { 'BR' }
11 8     8 1 21314 sub country_code { 55 }
12              
13             has subscriber => ( is => 'ro' );
14              
15             has areacode => ( is => 'ro' );
16             has areaname => ( is => 'ro' );
17              
18             has is_mobile => ( is => 'ro' );
19             has is_valid => ( is => 'ro' );
20             has is_fixed_line => ( is => 'ro' );
21              
22             has _original_number => ( is => 'ro' );
23              
24             sub BUILDARGS {
25 13     13 0 36975 my ($class, $number) = @_;
26 13         29 my ($areacode, $subscriber);
27              
28 13         65 my %args = ( _original_number => $number );
29              
30 13 100       53 my $number_sane = _sanitize_number($number)
31             or return \%args;
32              
33 12         49 $number_sane =~ s{ \( ([0-9]+) \) }{}x;
34              
35 12 100       46 if ( $areacode = $1 ) {
36 3         11 $areacode =~ s/^0//;
37 3         7 $subscriber = $number_sane;
38             }
39             else {
40 9         31 $number_sane =~ s{^0}{};
41              
42 9         30 $areacode = substr $number_sane, 0, 2;
43 9         24 $subscriber = substr $number_sane, 2;
44             }
45              
46 12 100       67 my $areaname = code2name($areacode)
47             or return \%args;
48              
49 10         41 my $is_mobile = _validate_mobile( $areacode, $subscriber );
50 10 100       50 my $is_fixed_line = $is_mobile ? 0 : _validate_fixed_line( $subscriber );
51 10   66     49 my $is_valid = $is_mobile || $is_fixed_line;
52              
53 10 50       225 %args = (%args,
54             areacode => $areacode,
55             areaname => $areaname,
56             subscriber => $subscriber,
57             is_mobile => $is_mobile,
58             is_fixed_line => $is_fixed_line,
59             is_valid => $is_valid,
60             ) if $is_valid;
61              
62 10         421 return \%args;
63             }
64              
65             sub BUILD {
66 13     13 0 566 my $self = shift;
67              
68             # Breaks compat with Number::Phone
69 13 100       1292 $self->is_valid
70             or confess "Not a valid Brazilian phone number: " . $self->_original_number;
71             }
72              
73             sub _sanitize_number {
74 13     13   29 my $number = shift;
75              
76 13 50       51 return '' unless $number;
77              
78 13         27 my $number_sane = $number;
79              
80             # remove stuff we don't need
81 13         236 $number_sane =~ s{[\- \s]}{}gx;
82              
83             # strip country code
84 13         44 $number_sane =~ s{^\+55}{}gx;
85              
86 13 100       79 return '' if $number_sane =~ m|\+|;
87              
88 12         53 return $number_sane;
89             }
90              
91             sub _validate_mobile {
92 10     10   27 my ($code, $number) = @_;
93              
94 10         49 my $digits = mobile_phone_digits_by_area($code);
95              
96 10         34 my $f = substr $number, 0, 1;
97              
98 10 100 66     85 if ($digits == 9 && $f ne '9') {
99 9         24 return 0;
100             }
101              
102 1 50 33     16 if ($f ne '6' && $f ne '8' && $f ne '9') {
      33        
103 0         0 return 0;
104             }
105              
106 1 50       51 return $number =~ m|^[0-9]{$digits}$| ? 1 : 0;
107             }
108              
109             sub _validate_fixed_line {
110 9     9   20 my ($number) = @_;
111              
112 9 50       55 return $number =~ m|^[2-5][0-9]{7}$| ? 1 : 0;
113             }
114              
115             # TODO: 0800, 0300 ?
116 0     0 1   sub is_tollfree { }
117              
118             # TODO: 190, etc
119 0     0 1   sub is_network_service { }
120              
121             # XXX: all of these return undef, because I have no idea how to implement them,
122             # or even if it is possible at all in Brazil.
123 0     0 1   sub is_allocated { }
124 0     0 1   sub is_in_use { }
125 0     0 1   sub is_geographic { }
126 0     0 1   sub is_pager { }
127 0     0 1   sub is_ipphone { }
128 0     0 1   sub is_isdn { }
129 0     0 1   sub is_specialrate { }
130 0     0 1   sub is_adult { }
131 0     0 1   sub is_international { }
132 0     0 1   sub is_personal { }
133 0     0 1   sub is_corporate { }
134 0     0 1   sub is_government { }
135              
136             1;
137              
138             __END__