File Coverage

lib/Types/Standard/StrMatch.pm
Criterion Covered Total %
statement 63 63 100.0
branch 23 26 88.4
condition 8 9 88.8
subroutine 17 17 100.0
pod n/a
total 111 115 96.5


line stmt bran cond sub pod time code
1             # INTERNAL MODULE: guts for StrMatch type from Types::Standard.
2              
3             package Types::Standard::StrMatch;
4              
5 11     11   246 use 5.008001;
  11         75  
6 11     11   76 use strict;
  11         25  
  11         253  
7 11     11   62 use warnings;
  11         38  
  11         579  
8              
9             BEGIN {
10 11     11   71 $Types::Standard::StrMatch::AUTHORITY = 'cpan:TOBYINK';
11 11         451 $Types::Standard::StrMatch::VERSION = '2.004000';
12             }
13              
14             $Types::Standard::StrMatch::VERSION =~ tr/_//d;
15              
16 11     11   73 use Type::Tiny ();
  11         25  
  11         233  
17 11     11   64 use Types::Standard ();
  11         24  
  11         213  
18 11     11   80 use Types::TypeTiny ();
  11         29  
  11         767  
19              
20 2     2   29 sub _croak ($;@) { require Error::TypeTiny; goto \&Error::TypeTiny::croak }
  2         11  
21              
22 11     11   70 no warnings;
  11         30  
  11         10091  
23              
24             our %expressions;
25             my $has_regexp_util;
26             my $serialize_regexp = sub {
27             $has_regexp_util = eval {
28             require Regexp::Util;
29             Regexp::Util->VERSION( '0.003' );
30             1;
31             } || 0 unless defined $has_regexp_util;
32            
33             my $re = shift;
34             my $serialized;
35             if ( $has_regexp_util ) {
36             $serialized = eval { Regexp::Util::serialize_regexp( $re ) };
37             }
38            
39             unless ( defined $serialized ) {
40             my $key = sprintf( '%s|%s', ref( $re ), $re );
41             $expressions{$key} = $re;
42             $serialized = sprintf(
43             '$Types::Standard::StrMatch::expressions{%s}',
44             B::perlstring( $key )
45             );
46             }
47            
48             return $serialized;
49             };
50              
51             sub __constraint_generator {
52 33 50   33   152 return Types::Standard->meta->get_type( 'StrMatch' ) unless @_;
53            
54 33         98 my ( $regexp, $checker ) = @_;
55            
56 33 100       199 Types::Standard::is_RegexpRef( $regexp )
57             or _croak(
58             "First parameter to StrMatch[`a] expected to be a Regexp; got $regexp" );
59            
60 32 100       332 if ( @_ > 1 ) {
61 5         19 $checker = Types::TypeTiny::to_TypeTiny( $checker );
62 5 100       113 Types::TypeTiny::is_TypeTiny( $checker )
63             or _croak(
64             "Second parameter to StrMatch[`a] expected to be a type constraint; got $checker"
65             );
66             }
67            
68             $checker
69             ? sub {
70 24     24   48 my $value = shift;
71 24 50       59 return if ref( $value );
72 24         150 my @m = ( $value =~ $regexp );
73 24         83 $checker->check( \@m );
74             }
75             : sub {
76 30     30   57 my $value = shift;
77 30   66     313 !ref( $value ) and !!( $value =~ $regexp );
78 31 100       229 };
79             } #/ sub __constraint_generator
80              
81             sub __inline_generator {
82 31     31   205 require B;
83 31         93 my ( $regexp, $checker ) = @_;
84 31 50       103 my $serialized_re = $regexp->$serialize_regexp or return;
85            
86 31 100       113 if ( $checker ) {
87 4 100       20 return unless $checker->can_be_inlined;
88            
89             return sub {
90 24     24   47 my $v = $_[1];
91 24 100 100     97 if ( $Type::Tiny::AvoidCallbacks
92             and $serialized_re =~ /Types::Standard::StrMatch::expressions/ )
93             {
94 1         8 require Carp;
95 1         93 Carp::carp(
96             "Cannot serialize regexp without callbacks; serializing using callbacks" );
97             }
98             sprintf
99 24         115 "!ref($v) and do { my \$m = [$v =~ %s]; %s }",
100             $serialized_re,
101             $checker->inline_check( '$m' ),
102             ;
103 3         47 };
104             } #/ if ( $checker )
105             else {
106 27         68 my $regexp_string = "$regexp";
107 27 100       148 if ( $regexp_string =~ /\A\(\?\^u?:\\A(\.+)\)\z/ ) {
108 1         10 my $length = length $1;
109 1     7   9 return sub { "!ref($_) and length($_)>=$length" };
  7         34  
110             }
111            
112 26 100       89 if ( $regexp_string =~ /\A\(\?\^u?:\\A(\.+)\\z\)\z/ ) {
113 1         5 my $length = length $1;
114 1     7   8 return sub { "!ref($_) and length($_)==$length" };
  7         39  
115             }
116            
117             return sub {
118 170     170   287 my $v = $_[1];
119 170 100 100     492 if ( $Type::Tiny::AvoidCallbacks
120             and $serialized_re =~ /Types::Standard::StrMatch::expressions/ )
121             {
122 6         31 require Carp;
123 6         740 Carp::carp(
124             "Cannot serialize regexp without callbacks; serializing using callbacks" );
125             }
126 170         700 "!ref($v) and !!( $v =~ $serialized_re )";
127 25         206 };
128             } #/ else [ if ( $checker ) ]
129             } #/ sub __inline_generator
130              
131             1;