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 12     12   313 use 5.008001;
  12         46  
6 12     12   78 use strict;
  12         24  
  12         321  
7 12     12   62 use warnings;
  12         25  
  12         574  
8              
9             BEGIN {
10 12     12   45 $Types::Standard::StrMatch::AUTHORITY = 'cpan:TOBYINK';
11 12         447 $Types::Standard::StrMatch::VERSION = '2.003_000';
12             }
13              
14             $Types::Standard::StrMatch::VERSION =~ tr/_//d;
15              
16 12     12   73 use Type::Tiny ();
  12         27  
  12         247  
17 12     12   75 use Types::Standard ();
  12         25  
  12         234  
18 12     12   58 use Types::TypeTiny ();
  12         25  
  12         725  
19              
20 2     2   31 sub _croak ($;@) { require Error::TypeTiny; goto \&Error::TypeTiny::croak }
  2         14  
21              
22 12     12   76 no warnings;
  12         24  
  12         10881  
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 35 50   35   116 return Types::Standard->meta->get_type( 'StrMatch' ) unless @_;
53            
54 35         87 my ( $regexp, $checker ) = @_;
55            
56 35 100       145 Types::Standard::is_RegexpRef( $regexp )
57             or _croak(
58             "First parameter to StrMatch[`a] expected to be a Regexp; got $regexp" );
59            
60 34 100       310 if ( @_ > 1 ) {
61 5         21 $checker = Types::TypeTiny::to_TypeTiny( $checker );
62 5 100       109 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   50 my $value = shift;
71 24 50       59 return if ref( $value );
72 24         153 my @m = ( $value =~ $regexp );
73 24         80 $checker->check( \@m );
74             }
75             : sub {
76 30     30   92 my $value = shift;
77 30   66     363 !ref( $value ) and !!( $value =~ $regexp );
78 33 100       201 };
79             } #/ sub __constraint_generator
80              
81             sub __inline_generator {
82 33     33   173 require B;
83 33         85 my ( $regexp, $checker ) = @_;
84 33 50       116 my $serialized_re = $regexp->$serialize_regexp or return;
85            
86 33 100       102 if ( $checker ) {
87 4 100       17 return unless $checker->can_be_inlined;
88            
89             return sub {
90 24     24   46 my $v = $_[1];
91 24 100 100     92 if ( $Type::Tiny::AvoidCallbacks
92             and $serialized_re =~ /Types::Standard::StrMatch::expressions/ )
93             {
94 1         12 require Carp;
95 1         99 Carp::carp(
96             "Cannot serialize regexp without callbacks; serializing using callbacks" );
97             }
98             sprintf
99 24         125 "!ref($v) and do { my \$m = [$v =~ %s]; %s }",
100             $serialized_re,
101             $checker->inline_check( '$m' ),
102             ;
103 3         37 };
104             } #/ if ( $checker )
105             else {
106 29         64 my $regexp_string = "$regexp";
107 29 100       139 if ( $regexp_string =~ /\A\(\?\^u?:\\A(\.+)\)\z/ ) {
108 1         4 my $length = length $1;
109 1     7   9 return sub { "!ref($_) and length($_)>=$length" };
  7         27  
110             }
111            
112 28 100       96 if ( $regexp_string =~ /\A\(\?\^u?:\\A(\.+)\\z\)\z/ ) {
113 1         35 my $length = length $1;
114 1     7   10 return sub { "!ref($_) and length($_)==$length" };
  7         34  
115             }
116            
117             return sub {
118 176     176   343 my $v = $_[1];
119 176 100 100     503 if ( $Type::Tiny::AvoidCallbacks
120             and $serialized_re =~ /Types::Standard::StrMatch::expressions/ )
121             {
122 6         34 require Carp;
123 6         724 Carp::carp(
124             "Cannot serialize regexp without callbacks; serializing using callbacks" );
125             }
126 176         742 "!ref($v) and !!( $v =~ $serialized_re )";
127 27         193 };
128             } #/ else [ if ( $checker ) ]
129             } #/ sub __inline_generator
130              
131             1;