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   261 use 5.008001;
  11         42  
6 11     11   63 use strict;
  11         22  
  11         293  
7 11     11   54 use warnings;
  11         22  
  11         561  
8              
9             BEGIN {
10 11     11   35 $Types::Standard::StrMatch::AUTHORITY = 'cpan:TOBYINK';
11 11         449 $Types::Standard::StrMatch::VERSION = '2.002001';
12             }
13              
14             $Types::Standard::StrMatch::VERSION =~ tr/_//d;
15              
16 11     11   105 use Type::Tiny ();
  11         40  
  11         251  
17 11     11   72 use Types::Standard ();
  11         21  
  11         186  
18 11     11   63 use Types::TypeTiny ();
  11         35  
  11         693  
19              
20 2     2   483 sub _croak ($;@) { require Error::TypeTiny; goto \&Error::TypeTiny::croak }
  2         11  
21              
22 11     11   102 no warnings;
  11         32  
  11         10045  
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   122 return Types::Standard->meta->get_type( 'StrMatch' ) unless @_;
53            
54 33         78 my ( $regexp, $checker ) = @_;
55            
56 33 100       133 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       342 if ( @_ > 1 ) {
61 5         17 $checker = Types::TypeTiny::to_TypeTiny( $checker );
62 5 100       128 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   43 my $value = shift;
71 24 50       56 return if ref( $value );
72 24         185 my @m = ( $value =~ $regexp );
73 24         83 $checker->check( \@m );
74             }
75             : sub {
76 30     30   57 my $value = shift;
77 30   66     337 !ref( $value ) and !!( $value =~ $regexp );
78 31 100       202 };
79             } #/ sub __constraint_generator
80              
81             sub __inline_generator {
82 31     31   196 require B;
83 31         81 my ( $regexp, $checker ) = @_;
84 31 50       93 my $serialized_re = $regexp->$serialize_regexp or return;
85            
86 31 100       92 if ( $checker ) {
87 4 100       16 return unless $checker->can_be_inlined;
88            
89             return sub {
90 24     24   44 my $v = $_[1];
91 24 100 100     112 if ( $Type::Tiny::AvoidCallbacks
92             and $serialized_re =~ /Types::Standard::StrMatch::expressions/ )
93             {
94 1         7 require Carp;
95 1         70 Carp::carp(
96             "Cannot serialize regexp without callbacks; serializing using callbacks" );
97             }
98             sprintf
99 24         145 "!ref($v) and do { my \$m = [$v =~ %s]; %s }",
100             $serialized_re,
101             $checker->inline_check( '$m' ),
102             ;
103 3         38 };
104             } #/ if ( $checker )
105             else {
106 27         82 my $regexp_string = "$regexp";
107 27 100       93 if ( $regexp_string =~ /\A\(\?\^u?:\\A(\.+)\)\z/ ) {
108 1         4 my $length = length $1;
109 1     7   11 return sub { "!ref($_) and length($_)>=$length" };
  7         30  
110             }
111            
112 26 100       75 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         31  
115             }
116            
117             return sub {
118 170     170   279 my $v = $_[1];
119 170 100 100     509 if ( $Type::Tiny::AvoidCallbacks
120             and $serialized_re =~ /Types::Standard::StrMatch::expressions/ )
121             {
122 6         31 require Carp;
123 6         508 Carp::carp(
124             "Cannot serialize regexp without callbacks; serializing using callbacks" );
125             }
126 170         1007 "!ref($v) and !!( $v =~ $serialized_re )";
127 25         172 };
128             } #/ else [ if ( $checker ) ]
129             } #/ sub __inline_generator
130              
131             1;