File Coverage

blib/lib/GeoIP2/Types.pm
Criterion Covered Total %
statement 60 60 100.0
branch 8 8 100.0
condition 9 9 100.0
subroutine 31 31 100.0
pod 0 20 0.0
total 108 128 84.3


line stmt bran cond sub pod time code
1             package GeoIP2::Types;
2              
3 13     13   135273 use strict;
  13         23  
  13         337  
4 13     13   67 use warnings;
  13         27  
  13         409  
5              
6             our $VERSION = '2.006002';
7              
8 13     13   2169 use Data::Validate::IP ();
  13         146281  
  13         251  
9 13     13   4417 use GeoIP2::Error::Type;
  13         37  
  13         349  
10 13     13   5828 use List::SomeUtils ();
  13         70220  
  13         284  
11 13     13   92 use Scalar::Util ();
  13         26  
  13         241  
12 13     13   61 use Sub::Quote qw( quote_sub );
  13         21  
  13         567  
13 13     13   5725 use URI;
  13         49643  
  13         373  
14              
15 13     13   88 use namespace::clean;
  13         25  
  13         107  
16              
17 13     13   2566 use Exporter qw( import );
  13         26  
  13         9179  
18              
19             our @EXPORT_OK = qw(
20             ArrayRef
21             Bool
22             BoolCoercion
23             HTTPStatus
24             HashRef
25             IPAddress
26             JSONObject
27             LocalesArrayRef
28             MaxMindID
29             MaxMindLicenseKey
30             MaybeStr
31             NameHashRef
32             NonNegativeInt
33             Num
34             PositiveInt
35             Str
36             URIObject
37             UserAgentObject
38             object_can_type
39             object_isa_type
40             );
41              
42             our %EXPORT_TAGS = ( all => \@EXPORT_OK );
43              
44             ## no critic (NamingConventions::Capitalization, ValuesAndExpressions::ProhibitImplicitNewlines)
45             sub ArrayRef () {
46 20     20 0 59 return quote_sub(
47             q{ GeoIP2::Types::_tc_fail( $_[0], 'ArrayRef' )
48             unless defined $_[0]
49             && ref $_[0]
50             && Scalar::Util::reftype( $_[0] ) eq 'ARRAY'
51             && ! Scalar::Util::blessed( $_[0] ); }
52             );
53             }
54              
55             sub Bool () {
56 32     32 0 8155 return quote_sub(
57             q{ GeoIP2::Types::_tc_fail( $_[0], 'Bool' )
58             unless ( ( defined $_[0] && !ref $_[0] && $_[0] =~ /^(?:0|1|)$/ )
59             || !defined $_[0] ); }
60             );
61             }
62              
63             sub BoolCoercion () {
64 24     24 0 2760 return quote_sub(
65             q{ defined $_[0] && Scalar::Util::blessed($_[0])
66             && ( $_[0]->isa('JSON::Boolean')
67             || $_[0]->isa('JSON::PP::Boolean')
68             || $_[0]->isa('JSON::XS::Boolean')
69             || $_[0]->isa('Cpanel::JSON::XS::Boolean')
70             )
71             ? $_[0] + 0 : $_[0] }
72             );
73             }
74              
75             sub HTTPStatus () {
76 2     2 0 2526 return quote_sub(
77             q{ GeoIP2::Types::_tc_fail( $_[0], 'HTTPStatus' )
78             unless defined $_[0]
79             && ! ref $_[0]
80             && $_[0] =~ /^[2345]\d\d$/ }
81             );
82             }
83              
84             sub HashRef () {
85 288     288 0 3131 return quote_sub(
86             q{ GeoIP2::Types::_tc_fail( $_[0], 'HashRef' )
87             unless defined $_[0]
88             && ref $_[0]
89             && Scalar::Util::reftype( $_[0] ) eq 'HASH'
90             && ! Scalar::Util::blessed( $_[0] ); }
91             );
92             }
93              
94             sub IPAddress {
95 13     13 0 2535 return quote_sub(
96             q{ GeoIP2::Types::_tc_fail( $_[0], 'IPAddress' )
97             unless Data::Validate::IP::is_ip( $_[0] ); }
98             );
99             }
100              
101             sub JSONObject () {
102 2     2 0 2467 return quote_sub(q{ GeoIP2::Types::object_can_type( $_[0], 'decode' ) });
103             }
104              
105             {
106             ## no critic (Variables::ProhibitPackageVars)
107             our %_SupportedLangs = map { $_ => 1 } qw(
108             de
109             en
110             es
111             fr
112             ja
113             pt-BR
114             ru
115             zh-CN
116             );
117              
118             sub LocalesArrayRef () {
119 13     13 0 2799 return quote_sub(
120             q{ GeoIP2::Types::_tc_fail( $_[0], 'LocalesArrayRef' )
121             unless ref $_[0]
122             && Scalar::Util::reftype( $_[0] ) eq 'ARRAY'
123             && !Scalar::Util::blessed( $_[0] )
124             && List::SomeUtils::all(
125             sub { defined $_ && !ref $_ && $GeoIP2::Types::_SupportedLangs{$_} },
126             @{ $_[0] }
127             ); }
128             );
129             }
130             }
131              
132             # Same as PositiveInt
133             sub MaxMindID () {
134 2     2 0 2553 return quote_sub(
135             q{ GeoIP2::Types::_tc_fail( $_[0], 'MaxMindID' )
136             unless defined $_[0]
137             && ! ref $_[0]
138             && $_[0] =~ /^\d+$/
139             && $_[0] > 0; }
140             );
141             }
142              
143             sub MaxMindLicenseKey () {
144 2     2 0 2522 return quote_sub(
145             q{ GeoIP2::Types::_tc_fail( $_[0], 'MaxMindLicenseKey' )
146             unless defined $_[0]
147             && ! ref $_[0]
148             && $_[0] =~ /^\S{12,}$/; }
149             );
150             }
151              
152             sub MaybeStr () {
153 13     13 0 2639 return quote_sub(
154             q{ GeoIP2::Types::_tc_fail( $_[0], 'StrOrUndef' )
155             unless !ref $_[0]; }
156             );
157             }
158              
159             sub NameHashRef () {
160 13     13 0 2526 return quote_sub(
161             q{ GeoIP2::Types::_tc_fail( $_[0], 'NameHashRef' )
162             unless ref $_[0]
163             && Scalar::Util::reftype( $_[0] ) eq 'HASH'
164             && ! Scalar::Util::blessed( $_[0] )
165             && &List::SomeUtils::all( sub { defined $_ && ! ref $_ }, values %{ $_[0] } ); }
166             );
167             }
168              
169             sub NonNegativeInt () {
170 109     109 0 2849 return quote_sub(
171             q{ GeoIP2::Types::_tc_fail( $_[0], 'NonNegativeInt' )
172             unless defined $_[0]
173             && ! ref $_[0]
174             && $_[0] =~ /^\d+$/
175             && $_[0] >= 0; }
176             );
177             }
178              
179             sub Num () {
180 25     25 0 2611 return quote_sub(
181             q{ GeoIP2::Types::_tc_fail( $_[0], 'Num' )
182             unless defined $_[0]
183             && ! ref $_[0]
184             && $_[0] =~ /^-?\d+(\.\d+)?$/; }
185             );
186             }
187              
188             sub PositiveInt () {
189 71     71 0 2706 return quote_sub(
190             q{ GeoIP2::Types::_tc_fail( $_[0], 'PositiveInt' )
191             unless defined $_[0]
192             && ! ref $_[0]
193             && $_[0] =~ /^\d+$/
194             && $_[0] > 0; }
195             );
196             }
197              
198             sub Str () {
199 202     202 0 3067 return quote_sub(
200             q{ GeoIP2::Types::_tc_fail( $_[0], 'Str' )
201             unless defined $_[0]
202             && ! ref $_[0]; }
203             );
204             }
205              
206             sub URIObject () {
207 3     3 0 2616 return quote_sub(q{ GeoIP2::Types::object_isa_type( $_[0], 'URI' ) });
208             }
209              
210             sub UserAgentObject () {
211 2     2 0 2901 return quote_sub(
212             q{ GeoIP2::Types::object_can_type( $_[0], 'agent', 'request' ) });
213             }
214              
215             ## use critic
216              
217             sub object_can_type {
218 57     57 0 63845 my $thing = shift;
219 57         109 my @methods = @_;
220              
221 57 100 100     305 _tc_fail( $thing, 'Object' )
222             unless defined $thing
223             && Scalar::Util::blessed($thing);
224              
225 36         71 for my $method (@methods) {
226 53 100       664 _tc_fail( $thing, "Object which ->can($method)" )
227             unless $thing->can($method);
228             }
229             }
230              
231             sub object_isa_type {
232 119     119 0 205854 my $thing = shift;
233 119         192 my $class = shift;
234              
235 119 100 100     2549 _tc_fail( $thing, "$class Object" )
      100        
236             unless defined $thing
237             && Scalar::Util::blessed($thing)
238             && $thing->isa($class);
239             }
240              
241             sub _tc_fail {
242 152     152   304215 my $value = shift;
243 152         208 my $type = shift;
244              
245 152 100       287 $value
246             = !defined $value
247             ? 'undef'
248             : $value;
249              
250 152         671 GeoIP2::Error::Type->throw(
251             message => "$value is not a valid $type",
252             type => $type,
253             value => $value
254             );
255             }
256              
257             1;