File Coverage

blib/lib/Types/TypeTiny.pm
Criterion Covered Total %
statement 299 449 62.8
branch 123 228 53.9
condition 67 99 67.6
subroutine 76 108 63.8
pod 8 27 29.6
total 573 911 60.2


line stmt bran cond sub pod time code
1             package Types::TypeTiny;
2              
3 280     280   5856 use 5.008001;
  280         982  
4 280     280   1500 use strict;
  280         1794  
  280         6301  
5 280     280   1465 use warnings;
  280         617  
  280         22528  
6              
7             our $AUTHORITY = 'cpan:TOBYINK';
8             our $VERSION = '2.004000';
9              
10             $VERSION =~ tr/_//d;
11              
12 280     280   2163 use Scalar::Util qw< blessed refaddr weaken >;
  280         708  
  280         40265  
13              
14             BEGIN {
15             *__XS = eval {
16 280         137153 require Type::Tiny::XS;
17 280         879673 'Type::Tiny::XS'->VERSION( '0.022' );
18 280         22790 1;
19             }
20             ? eval "sub () { '$Type::Tiny::XS::VERSION' }"
21 280 50   280   1095 : sub () { !!0 };
22             }
23              
24             our @EXPORT_OK = (
25             map( @{ [ $_, "is_$_", "assert_$_" ] }, __PACKAGE__->type_names ),
26             qw/to_TypeTiny/
27             );
28             our %EXPORT_TAGS = (
29             types => [ __PACKAGE__->type_names ],
30             is => [ map "is_$_", __PACKAGE__->type_names ],
31             assert => [ map "assert_$_", __PACKAGE__->type_names ],
32             );
33              
34             my %cache;
35              
36             # This `import` method is designed to avoid loading Exporter::Tiny.
37             # This is so that if you stick to only using the purely OO parts of
38             # Type::Tiny, you can skip loading the exporter.
39             #
40             sub import {
41              
42             # If this sub succeeds, it will replace itself.
43             # uncoverable subroutine
44 35 100   35   2679 return unless @_ > 1; # uncoverable statement
45 280     280   2340 no warnings "redefine"; # uncoverable statement
  280         729  
  280         65030  
46 34         789 our @ISA = qw( Exporter::Tiny ); # uncoverable statement
47 34         256 require Exporter::Tiny; # uncoverable statement
48 34         126 my $next = \&Exporter::Tiny::import; # uncoverable statement
49 34         152 *import = $next; # uncoverable statement
50 34         91 my $class = shift; # uncoverable statement
51 34 50       237 my $opts = { ref( $_[0] ) ? %{ +shift } : () }; # uncoverable statement
  0         0  
52 34   50     305 $opts->{into} ||= scalar( caller ); # uncoverable statement
53 34         151 _mkall(); # uncoverable statement
54 34         232 return $class->$next( $opts, @_ ); # uncoverable statement
55             } #/ sub import
56              
57             for ( __PACKAGE__->type_names ) { # uncoverable statement
58 0     0 0 0 eval qq{ # uncoverable statement
  0     0 0 0  
  0     0 0 0  
  0     0 0 0  
  115081     115081 0 339648  
  0     0 0 0  
  2     2 0 14  
  0     0 0 0  
  7     7 0 59  
  0     0 0 0  
  11637     11637 0 35171  
  0     0 0 0  
  0     0 0    
59             sub is_$_ { $_()->check(shift) } # uncoverable statement
60             sub assert_$_ { $_()->assert_return(shift) } # uncoverable statement
61             }; # uncoverable statement
62             } # uncoverable statement
63              
64             sub _reinstall_subs {
65              
66             # uncoverable subroutine
67 627     627   1402 my $type = shift; # uncoverable statement
68 280     280   2380 no strict 'refs'; # uncoverable statement
  280         594  
  280         10881  
69 280     280   1963 no warnings 'redefine'; # uncoverable statement
  280         808  
  280         72957  
70 627         2131 *{ 'is_' . $type->name } = $type->compiled_check; # uncoverable statement
  627         2005  
71 627         2934 *{ 'assert_' . $type->name } = \&$type; # uncoverable statement
  627         2453  
72 627         4858 $type; # uncoverable statement
73             } # uncoverable statement
74              
75             sub _mkall {
76              
77             # uncoverable subroutine
78 119 100   119   593 return unless $INC{'Type/Tiny.pm'}; # uncoverable statement
79 118         567 __PACKAGE__->get_type( $_ ) for __PACKAGE__->type_names; # uncoverable statement
80             } # uncoverable statement
81              
82             sub meta {
83 31     31 1 228 return $_[0];
84             }
85              
86             sub type_names {
87 2477     2477 1 15345 qw(
88             StringLike BoolLike
89             HashLike ArrayLike CodeLike
90             TypeTiny _ForeignTypeConstraint
91             );
92             }
93              
94             sub has_type {
95 942     942 1 2113 my %has = map +( $_ => 1 ), shift->type_names;
96 942         4459 !!$has{ $_[0] };
97             }
98              
99             sub get_type {
100 933     933 1 1794 my $self = shift;
101 933 100       2160 return unless $self->has_type( @_ );
102 280     280   2334 no strict qw(refs);
  280         725  
  280         40520  
103 932         1682 &{ $_[0] }();
  932         3760  
104             }
105              
106             sub coercion_names {
107 19     19 1 711 qw();
108             }
109              
110             sub has_coercion {
111 2     2 1 8 my %has = map +( $_ => 1 ), shift->coercion_names;
112 2         12 !!$has{ $_[0] };
113             }
114              
115             sub get_coercion {
116 1     1 1 3 my $self = shift;
117 1 50       2 return unless $self->has_coercion( @_ );
118 280     280   2160 no strict qw(refs);
  280         745  
  280         29929  
119 0         0 &{ $_[0] }(); # uncoverable statement
  0         0  
120             }
121              
122             my ( $__get_linear_isa_dfs, $tried_mro );
123             $__get_linear_isa_dfs = sub {
124             if ( !$tried_mro && eval { require mro } ) {
125             $__get_linear_isa_dfs = \&mro::get_linear_isa;
126             goto $__get_linear_isa_dfs;
127             }
128 280     280   2089 no strict 'refs';
  280         794  
  280         1311169  
129             my $classname = shift;
130             my @lin = ( $classname );
131             my %stored;
132             foreach my $parent ( @{"$classname\::ISA"} ) {
133             my $plin = $__get_linear_isa_dfs->( $parent );
134             foreach ( @$plin ) {
135             next if exists $stored{$_};
136             push( @lin, $_ );
137             $stored{$_} = 1;
138             }
139             }
140             return \@lin;
141             };
142              
143             sub _check_overload {
144 217     217   804 my $package = shift;
145 217 50       510 if ( ref $package ) {
146 217         521 $package = blessed( $package );
147 217 50       608 return !!0 if !defined $package;
148             }
149 217         326 my $op = shift;
150 217         881 my $mro = $__get_linear_isa_dfs->( $package );
151 217         463 foreach my $p ( @$mro ) {
152 253         527 my $fqmeth = $p . q{::(} . $op;
153 253 100       328 return !!1 if defined &{$fqmeth};
  253         1689  
154             }
155 178         1791 !!0;
156             } #/ sub _check_overload
157              
158             sub _get_check_overload_sub {
159 521 100   521   1072 if ( $Type::Tiny::AvoidCallbacks ) {
160             return
161 353         1689 '(sub { require overload; overload::Overloaded(ref $_[0] or $_[0]) and overload::Method((ref $_[0] or $_[0]), $_[1]) })->';
162             }
163 168         666 return 'Types::TypeTiny::_check_overload';
164             }
165              
166             sub StringLike () {
167 397 100   397 0 23135 return $cache{StringLike} if defined $cache{StringLike};
168 259         1425 require Type::Tiny;
169             my %common = (
170             name => "StringLike",
171             library => __PACKAGE__,
172             constraint => sub {
173 57 100 100 57   641 defined( $_ ) && !ref( $_ )
      100        
174             or blessed( $_ ) && _check_overload( $_, q[""] );
175             },
176             inlined => sub {
177 57     57   223 qq/defined($_[1]) && !ref($_[1]) or Scalar::Util::blessed($_[1]) && ${\ +_get_check_overload_sub() }($_[1], q[""])/;
  57         119  
178             },
179 1     1   4 type_default => sub { return '' },
180 259         3409 );
181 259         653 if ( __XS ) {
182 259         1165 my $xsub = Type::Tiny::XS::get_coderef_for( 'StringLike' );
183 259         3731 my $xsubname = Type::Tiny::XS::get_subname_for( 'StringLike' );
184 259         2049 my $inlined = $common{inlined};
185             $cache{StringLike} = "Type::Tiny"->new(
186             %common,
187             compiled_type_constraint => $xsub,
188             inlined => sub {
189            
190             # uncoverable subroutine
191 374 100 66 374   3831 ( $Type::Tiny::AvoidCallbacks or not $xsubname )
192             ? goto( $inlined )
193             : qq/$xsubname($_[1])/ # uncoverable statement
194             },
195 259         2956 );
196 259         1622 _reinstall_subs $cache{StringLike};
197             } #/ if ( __XS )
198             else {
199             $cache{StringLike} = "Type::Tiny"->new( %common );
200             }
201             } #/ sub StringLike
202              
203             sub HashLike (;@) {
204 202 100 100 202 0 23893 return $cache{HashLike} if defined( $cache{HashLike} ) && !@_;
205 121         769 require Type::Tiny;
206             my %common = (
207             name => "HashLike",
208             library => __PACKAGE__,
209             constraint => sub {
210 67 100 100 67   626 ref( $_ ) eq q[HASH]
211             or blessed( $_ ) && _check_overload( $_, q[%{}] );
212             },
213             inlined => sub {
214 67     67   234 qq/ref($_[1]) eq q[HASH] or Scalar::Util::blessed($_[1]) && ${\ +_get_check_overload_sub() }($_[1], q[\%{}])/;
  67         156  
215             },
216 1     1   23 type_default => sub { return {} },
217             constraint_generator => sub {
218 2     2   5 my $param = TypeTiny()->assert_coerce( shift );
219 2         6 my $check = $param->compiled_check;
220 2         4 if ( __XS ge '0.025' ) {
221 2         20 my $paramname = Type::Tiny::XS::is_known( $check );
222 2 50       25 my $xsub = defined($paramname)
223             ? Type::Tiny::XS::get_coderef_for( "HashLike[$paramname]" )
224             : undef;
225 2 50       109 return $xsub if $xsub;
226             }
227             sub {
228 0         0 my %hash = %$_;
229 0         0 for my $key ( sort keys %hash ) {
230 0 0       0 $check->( $hash{$key} ) or return 0;
231             }
232 0         0 return 1;
233 0         0 };
234             },
235             inline_generator => sub {
236 2     2   5 my $param = TypeTiny()->assert_coerce( shift );
237 2 50       7 return unless $param->can_be_inlined;
238 2         6 my $check = $param->compiled_check;
239 2         3 my $xsubname;
240 2         2 if ( __XS ge '0.025' ) {
241 2         6 my $paramname = Type::Tiny::XS::is_known( $check );
242 2 50       20 $xsubname = defined($paramname)
243             ? Type::Tiny::XS::get_subname_for( "HashLike[$paramname]" )
244             : undef;
245             }
246             sub {
247 23         42 my $var = pop;
248 23 100 66     116 return "$xsubname($var)" if $xsubname && !$Type::Tiny::AvoidCallbacks;
249 10         38 my $code = sprintf(
250             'do { my $ok=1; my %%h = %%{%s}; for my $k (sort keys %%h) { ($ok=0,next) unless (%s) }; $ok }',
251             $var,
252             $param->inline_check( '$h{$k}' ),
253             );
254 10         32 return ( undef, $code );
255 2         23 };
256             },
257             coercion_generator => sub {
258 1     1   3 my ( $parent, $child, $param ) = @_;
259 1 50       6 return unless $param->has_coercion;
260 1         9 my $coercible = $param->coercion->_source_type_union->compiled_check;
261 1         8 my $C = "Type::Coercion"->new( type_constraint => $child );
262             $C->add_type_coercions(
263             $parent => sub {
264 4 50       81 my $origref = @_ ? $_[0] : $_;
265 4         13 my %orig = %$origref;
266 4         17 my %new;
267 4         18 for my $k ( sort keys %orig ) {
268 8 100       87 return $origref unless $coercible->( $orig{$k} );
269 6         95 $new{$k} = $param->coerce( $orig{$k} );
270             }
271 2         47 \%new;
272             },
273 1         14 );
274 1         4 return $C;
275             },
276 121         3065 );
277 121         346 if ( __XS ) {
278 121         641 my $xsub = Type::Tiny::XS::get_coderef_for( 'HashLike' );
279 121         1905 my $xsubname = Type::Tiny::XS::get_subname_for( 'HashLike' );
280 121         1101 my $inlined = $common{inlined};
281             $cache{HashLike} = "Type::Tiny"->new(
282             %common,
283             compiled_type_constraint => $xsub,
284             inlined => sub {
285            
286             # uncoverable subroutine
287 247 100 66 247   2135 ( $Type::Tiny::AvoidCallbacks or not $xsubname )
288             ? goto( $inlined )
289             : qq/$xsubname($_[1])/ # uncoverable statement
290             },
291 121         1413 );
292 121         673 _reinstall_subs $cache{HashLike};
293             } #/ if ( __XS )
294             else {
295             $cache{HashLike} = "Type::Tiny"->new( %common );
296             }
297            
298 121 100       1193 @_ ? $cache{HashLike}->parameterize( @{ $_[0] } ) : $cache{HashLike};
  2         12  
299             } #/ sub HashLike (;@)
300              
301             sub ArrayLike (;@) {
302 203 100 100 203 0 23325 return $cache{ArrayLike} if defined( $cache{ArrayLike} ) && !@_;
303 122         802 require Type::Tiny;
304             my %common = (
305             name => "ArrayLike",
306             library => __PACKAGE__,
307             constraint => sub {
308 67 100 100 67   553 ref( $_ ) eq q[ARRAY]
309             or blessed( $_ ) && _check_overload( $_, q[@{}] );
310             },
311             inlined => sub {
312 67     67   237 qq/ref($_[1]) eq q[ARRAY] or Scalar::Util::blessed($_[1]) && ${\ +_get_check_overload_sub() }($_[1], q[\@{}])/;
  67         143  
313             },
314 1     1   7 type_default => sub { return [] },
315             constraint_generator => sub {
316 2     2   4 my $param = TypeTiny()->assert_coerce( shift );
317 2         6 my $check = $param->compiled_check;
318 2         4 if ( __XS ge '0.025' ) {
319 2         11 my $paramname = Type::Tiny::XS::is_known( $check );
320 2 50       26 my $xsub = defined($paramname)
321             ? Type::Tiny::XS::get_coderef_for( "ArrayLike[$paramname]" )
322             : undef;
323 2 50       109 return $xsub if $xsub;
324             }
325             sub {
326 0         0 my @arr = @$_;
327 0         0 for my $val ( @arr ) {
328 0 0       0 $check->( $val ) or return 0;
329             }
330 0         0 return 1;
331 0         0 };
332             },
333             inline_generator => sub {
334 2     2   6 my $param = TypeTiny()->assert_coerce( shift );
335 2 50       14 return unless $param->can_be_inlined;
336 2         6 my $check = $param->compiled_check;
337 2         8 my $xsubname;
338 2         5 if ( __XS ge '0.025' ) {
339 2         11 my $paramname = Type::Tiny::XS::is_known( $check );
340 2 50       27 $xsubname = defined($paramname)
341             ? Type::Tiny::XS::get_subname_for( "ArrayLike[$paramname]" )
342             : undef;
343             }
344             sub {
345 23         42 my $var = pop;
346 23 100 66     106 return "$xsubname($var)" if $xsubname && !$Type::Tiny::AvoidCallbacks;
347 10         27 my $code = sprintf(
348             'do { my $ok=1; for my $v (@{%s}) { ($ok=0,next) unless (%s) }; $ok }',
349             $var,
350             $param->inline_check( '$v' ),
351             );
352 10         30 return ( undef, $code );
353 2         25 };
354             },
355             coercion_generator => sub {
356 1     1   3 my ( $parent, $child, $param ) = @_;
357 1 50       10 return unless $param->has_coercion;
358 1         6 my $coercible = $param->coercion->_source_type_union->compiled_check;
359 1         7 my $C = "Type::Coercion"->new( type_constraint => $child );
360             $C->add_type_coercions(
361             $parent => sub {
362 4 50       66 my $origref = @_ ? $_[0] : $_;
363 4         10 my @orig = @$origref;
364 4         12 my @new;
365 4         8 for my $v ( @orig ) {
366 10 100       103 return $origref unless $coercible->( $v );
367 8         121 push @new, $param->coerce( $v );
368             }
369 2         34 \@new;
370             },
371 1         11 );
372 1         3 return $C;
373             },
374 122         2589 );
375 122         291 if ( __XS ) {
376 122         516 my $xsub = Type::Tiny::XS::get_coderef_for( 'ArrayLike' );
377 122         1615 my $xsubname = Type::Tiny::XS::get_subname_for( 'ArrayLike' );
378 122         2651 my $inlined = $common{inlined};
379             $cache{ArrayLike} = "Type::Tiny"->new(
380             %common,
381             compiled_type_constraint => $xsub,
382             inlined => sub {
383            
384             # uncoverable subroutine
385 248 100 66 248   2071 ( $Type::Tiny::AvoidCallbacks or not $xsubname )
386             ? goto( $inlined )
387             : qq/$xsubname($_[1])/ # uncoverable statement
388             },
389 122         1234 );
390 122         576 _reinstall_subs $cache{ArrayLike};
391             } #/ if ( __XS )
392             else {
393             $cache{ArrayLike} = "Type::Tiny"->new( %common );
394             }
395            
396 122 100       1313 @_ ? $cache{ArrayLike}->parameterize( @{ $_[0] } ) : $cache{ArrayLike};
  2         14  
397             } #/ sub ArrayLike (;@)
398              
399             if ( $] ge '5.014' ) {
400             &Scalar::Util::set_prototype( $_, ';$' ) for \&HashLike, \&ArrayLike;
401             }
402              
403             sub CodeLike () {
404 208 100   208 0 23235 return $cache{CodeLike} if $cache{CodeLike};
405 125         754 require Type::Tiny;
406             my %common = (
407             name => "CodeLike",
408             constraint => sub {
409 58 100 100 58   531 ref( $_ ) eq q[CODE]
410             or blessed( $_ ) && _check_overload( $_, q[&{}] );
411             },
412             inlined => sub {
413 58     58   203 qq/ref($_[1]) eq q[CODE] or Scalar::Util::blessed($_[1]) && ${\ +_get_check_overload_sub() }($_[1], q[\&{}])/;
  58         123  
414             },
415 1     1   9 type_default => sub { return sub {} },
416 125         1525 library => __PACKAGE__,
417             );
418 125         298 if ( __XS ) {
419 125         514 my $xsub = Type::Tiny::XS::get_coderef_for( 'CodeLike' );
420 125         1651 my $xsubname = Type::Tiny::XS::get_subname_for( 'CodeLike' );
421 125         954 my $inlined = $common{inlined};
422             $cache{CodeLike} = "Type::Tiny"->new(
423             %common,
424             compiled_type_constraint => $xsub,
425             inlined => sub {
426            
427             # uncoverable subroutine
428 242 100 66 242   2078 ( $Type::Tiny::AvoidCallbacks or not $xsubname )
429             ? goto( $inlined )
430             : qq/$xsubname($_[1])/ # uncoverable statement
431             },
432 125         1180 );
433 125         618 _reinstall_subs $cache{CodeLike};
434             } #/ if ( __XS )
435             else {
436             $cache{CodeLike} = "Type::Tiny"->new( %common );
437             }
438             } #/ sub CodeLike
439              
440             sub BoolLike () {
441 197 100   197 0 19489 return $cache{BoolLike} if $cache{BoolLike};
442 118         625 require Type::Tiny;
443             $cache{BoolLike} = "Type::Tiny"->new(
444             name => "BoolLike",
445             constraint => sub {
446             !defined( $_ )
447             or !ref( $_ ) && ( $_ eq '' || $_ eq '0' || $_ eq '1' )
448             or blessed( $_ ) && _check_overload( $_, q[bool] )
449 52 100 100 52   724 or blessed( $_ ) && _check_overload( $_, q[0+] ) && do { my $n = sprintf('%d', $_); $n==0 or $n==1 };
  2 100 66     16  
  2   100     25  
      100        
      100        
      100        
      100        
450             },
451             inlined => sub {
452 136     136   474 qq/do {
453             local \$_ = $_;
454             !defined()
455             or !ref() && ( \$_ eq '' || \$_ eq '0' || \$_ eq '1' )
456 136         314 or Scalar::Util::blessed(\$_) && ${\ +_get_check_overload_sub() }(\$_, q[bool])
457 136         276 or Scalar::Util::blessed(\$_) && ${\ +_get_check_overload_sub() }(\$_, q[0+]) && do { my \$n = sprintf('%d', $_); \$n==0 or \$n==1 }
458             }/;
459             },
460 1     1   6 type_default => sub { return !!0 },
461 118         1747 library => __PACKAGE__,
462             );
463             } #/ sub BoolLike
464              
465             sub TypeTiny () {
466 126928 100   126928 0 463309 return $cache{TypeTiny} if defined $cache{TypeTiny};
467 260         1557 require Type::Tiny;
468             $cache{TypeTiny} = "Type::Tiny"->new(
469             name => "TypeTiny",
470 58 100   58   555 constraint => sub { blessed( $_ ) && $_->isa( q[Type::Tiny] ) },
471             inlined => sub {
472 405     405   1120 my $var = $_[1];
473 405         2235 "Scalar::Util::blessed($var) && $var\->isa(q[Type::Tiny])";
474             },
475 1     1   637 type_default => sub { require Types::Standard; return Types::Standard::Any() },
  1         9  
476             library => __PACKAGE__,
477             _build_coercion => sub {
478 18     18   57 my $c = shift;
479 18         93 $c->add_type_coercions( _ForeignTypeConstraint(), \&to_TypeTiny );
480 18         85 $c->freeze;
481             },
482 260         4407 );
483             } #/ sub TypeTiny
484              
485             sub _ForeignTypeConstraint () {
486 215 100   215   21733 return $cache{_ForeignTypeConstraint} if defined $cache{_ForeignTypeConstraint};
487 118         646 require Type::Tiny;
488             $cache{_ForeignTypeConstraint} = "Type::Tiny"->new(
489             name => "_ForeignTypeConstraint",
490             constraint => \&_is_ForeignTypeConstraint,
491             inlined => sub {
492 159     159   756 qq/ref($_[1]) && do { require Types::TypeTiny; Types::TypeTiny::_is_ForeignTypeConstraint($_[1]) }/;
493             },
494 118         970 library => __PACKAGE__,
495             );
496             } #/ sub _ForeignTypeConstraint
497              
498             my %ttt_cache;
499              
500             sub _is_ForeignTypeConstraint {
501 210 50   210   1140 my $t = @_ ? $_[0] : $_;
502 210 100       538 return !!1 if ref $t eq 'CODE';
503 204 100       669 if ( my $class = blessed $t ) {
504 90 50       563 return !!0 if $class->isa( "Type::Tiny" );
505 90 50       354 return !!1 if $class->isa( "Moose::Meta::TypeConstraint" );
506 90 50       328 return !!1 if $class->isa( "MooseX::Types::TypeDecorator" );
507 90 50       370 return !!1 if $class->isa( "Validation::Class::Simple" );
508 90 50       248 return !!1 if $class->isa( "Validation::Class" );
509 90 100       366 return !!1 if $t->can( "check" );
510             }
511 199         1173 !!0;
512             } #/ sub _is_ForeignTypeConstraint
513              
514             sub to_TypeTiny {
515 145508 50   145508 1 272382 my $t = @_ ? $_[0] : $_;
516            
517 145508 100       310721 return $t unless ( my $ref = ref $t );
518 144399 100       509185 return $t if $ref =~ /^Type::Tiny\b/;
519            
520 40092 50       140034 return $ttt_cache{ refaddr( $t ) } if $ttt_cache{ refaddr( $t ) };
521            
522             #<<<
523 40092 100       93587 if ( my $class = blessed $t) {
524 50 50       414 return $t if $class->isa( "Type::Tiny" );
525 50 50       185 return _TypeTinyFromMoose( $t ) if $class eq "MooseX::Types::TypeDecorator"; # needed before MooseX::Types 0.35.
526 50 50       354 return _TypeTinyFromMoose( $t ) if $class->isa( "Moose::Meta::TypeConstraint" );
527 50 50       269 return _TypeTinyFromMoose( $t ) if $class->isa( "MooseX::Types::TypeDecorator" );
528 50 50       328 return _TypeTinyFromMouse( $t ) if $class->isa( "Mouse::Meta::TypeConstraint" );
529 50 50       337 return _TypeTinyFromValidationClass( $t ) if $class->isa( "Validation::Class::Simple" );
530 50 50       243 return _TypeTinyFromValidationClass( $t ) if $class->isa( "Validation::Class" );
531 50 100 66     674 return $t->to_TypeTiny if $t->can( "DOES" ) && $t->DOES( "Type::Library::Compiler::TypeConstraint" ) && $t->can( "to_TypeTiny" );
      66        
532 44 100       380 return _TypeTinyFromGeneric( $t ) if $t->can( "check" ); # i.e. Type::API::Constraint
533             } #/ if ( my $class = blessed...)
534             #>>>
535            
536 40083 100       109549 return _TypeTinyFromCodeRef( $t ) if $ref eq q(CODE);
537            
538 64         260 $t;
539             } #/ sub to_TypeTiny
540              
541             sub _TypeTinyFromMoose {
542 0     0   0 my $t = $_[0];
543            
544 0 0       0 if ( ref $t->{"Types::TypeTiny::to_TypeTiny"} ) {
545 0         0 return $t->{"Types::TypeTiny::to_TypeTiny"};
546             }
547            
548 0 0       0 if ( $t->name ne '__ANON__' ) {
549 0         0 require Types::Standard;
550 0         0 my $ts = 'Types::Standard'->get_type( $t->name );
551 0 0       0 return $ts if $ts->{_is_core};
552             }
553            
554             #<<<
555 0 0       0 my ( $tt_class, $tt_opts ) =
    0          
    0          
    0          
    0          
    0          
556             $t->can( 'parameterize' ) ? _TypeTinyFromMoose_parameterizable( $t ) :
557             $t->isa( 'Moose::Meta::TypeConstraint::Enum' ) ? _TypeTinyFromMoose_enum( $t ) :
558             $t->isa( 'Moose::Meta::TypeConstraint::Class' ) ? _TypeTinyFromMoose_class( $t ) :
559             $t->isa( 'Moose::Meta::TypeConstraint::Role' ) ? _TypeTinyFromMoose_role( $t ) :
560             $t->isa( 'Moose::Meta::TypeConstraint::Union' ) ? _TypeTinyFromMoose_union( $t ) :
561             $t->isa( 'Moose::Meta::TypeConstraint::DuckType' ) ? _TypeTinyFromMoose_ducktype( $t ) :
562             _TypeTinyFromMoose_baseclass( $t );
563             #>>>
564            
565             # Standard stuff to do with all type constraints from Moose,
566             # regardless of variety.
567 0         0 $tt_opts->{moose_type} = $t;
568 0         0 $tt_opts->{display_name} = $t->name;
569 0     0   0 $tt_opts->{message} = sub { $t->get_message( $_ ) }
570 0 0       0 if $t->has_message;
571            
572 0         0 my $new = $tt_class->new( %$tt_opts );
573 0         0 $ttt_cache{ refaddr( $t ) } = $new;
574 0         0 weaken( $ttt_cache{ refaddr( $t ) } );
575            
576 0 0       0 $new->{coercion} = do {
577 0         0 require Type::Coercion::FromMoose;
578 0         0 'Type::Coercion::FromMoose'->new(
579             type_constraint => $new,
580             moose_coercion => $t->coercion,
581             );
582             } if $t->has_coercion;
583            
584 0         0 return $new;
585             } #/ sub _TypeTinyFromMoose
586              
587             sub _TypeTinyFromMoose_baseclass {
588 0     0   0 my $t = shift;
589 0         0 my %opts;
590 0 0       0 $opts{parent} = to_TypeTiny( $t->parent ) if $t->has_parent;
591 0         0 $opts{constraint} = $t->constraint;
592 0     0   0 $opts{inlined} = sub { shift; $t->_inline_check( @_ ) }
  0         0  
593 0 0 0     0 if $t->can( "can_be_inlined" ) && $t->can_be_inlined;
594            
595             # Cowardly refuse to inline types that need to close over stuff
596 0 0       0 if ( $opts{inlined} ) {
597 0 0       0 my %env = %{ $t->inline_environment || {} };
  0         0  
598 0 0       0 delete( $opts{inlined} ) if keys %env;
599             }
600            
601 0         0 require Type::Tiny;
602 0         0 return 'Type::Tiny' => \%opts;
603             } #/ sub _TypeTinyFromMoose_baseclass
604              
605             sub _TypeTinyFromMoose_union {
606 0     0   0 my $t = shift;
607 0         0 my @mapped = map _TypeTinyFromMoose( $_ ), @{ $t->type_constraints };
  0         0  
608 0         0 require Type::Tiny::Union;
609 0         0 return 'Type::Tiny::Union' => { type_constraints => \@mapped };
610             }
611              
612             sub _TypeTinyFromMoose_enum {
613 0     0   0 my $t = shift;
614 0         0 require Type::Tiny::Enum;
615 0         0 return 'Type::Tiny::Enum' => { values => [ @{ $t->values } ] };
  0         0  
616             }
617              
618             sub _TypeTinyFromMoose_class {
619 0     0   0 my $t = shift;
620 0         0 require Type::Tiny::Class;
621 0         0 return 'Type::Tiny::Class' => { class => $t->class };
622             }
623              
624             sub _TypeTinyFromMoose_role {
625 0     0   0 my $t = shift;
626 0         0 require Type::Tiny::Role;
627 0         0 return 'Type::Tiny::Role' => { role => $t->role };
628             }
629              
630             sub _TypeTinyFromMoose_ducktype {
631 0     0   0 my $t = shift;
632 0         0 require Type::Tiny::Duck;
633 0         0 return 'Type::Tiny::Duck' => { methods => [ @{ $t->methods } ] };
  0         0  
634             }
635              
636             sub _TypeTinyFromMoose_parameterizable {
637 0     0   0 my $t = shift;
638 0         0 my ( $class, $opts ) = _TypeTinyFromMoose_baseclass( $t );
639             $opts->{constraint_generator} = sub {
640            
641             # convert args into Moose native types; not strictly necessary
642 0 0   0   0 my @args = map { is_TypeTiny( $_ ) ? $_->moose_type : $_ } @_;
  0         0  
643 0         0 _TypeTinyFromMoose( $t->parameterize( @args ) );
644 0         0 };
645 0         0 return ( $class, $opts );
646             } #/ sub _TypeTinyFromMoose_parameterizable
647              
648             sub _TypeTinyFromValidationClass {
649 0     0   0 my $t = $_[0];
650            
651 0         0 require Type::Tiny;
652 0         0 require Types::Standard;
653            
654 0         0 my %opts = (
655             parent => Types::Standard::HashRef(),
656             _validation_class => $t,
657             );
658            
659 0 0       0 if ( $t->VERSION >= "7.900048" ) {
660             $opts{constraint} = sub {
661 0     0   0 $t->params->clear;
662 0         0 $t->params->add( %$_ );
663 0         0 my $f = $t->filtering;
664 0         0 $t->filtering( 'off' );
665 0         0 my $r = eval { $t->validate };
  0         0  
666 0   0     0 $t->filtering( $f || 'pre' );
667 0         0 return $r;
668 0         0 };
669             $opts{message} = sub {
670 0     0   0 $t->params->clear;
671 0         0 $t->params->add( %$_ );
672 0         0 my $f = $t->filtering;
673 0         0 $t->filtering( 'off' );
674 0 0       0 my $r = ( eval { $t->validate } ? "OK" : $t->errors_to_string );
  0         0  
675 0   0     0 $t->filtering( $f || 'pre' );
676 0         0 return $r;
677 0         0 };
678             } #/ if ( $t->VERSION >= "7.900048")
679             else # need to use hackish method
680             {
681             $opts{constraint} = sub {
682 0     0   0 $t->params->clear;
683 0         0 $t->params->add( %$_ );
684 280     280   2780 no warnings "redefine";
  280         734  
  280         36319  
685 0         0 local *Validation::Class::Directive::Filters::execute_filtering = sub { $_[0] };
  0         0  
686 0         0 eval { $t->validate };
  0         0  
687 0         0 };
688             $opts{message} = sub {
689 0     0   0 $t->params->clear;
690 0         0 $t->params->add( %$_ );
691 280     280   2370 no warnings "redefine";
  280         751  
  280         325813  
692 0         0 local *Validation::Class::Directive::Filters::execute_filtering = sub { $_[0] };
  0         0  
693 0 0       0 eval { $t->validate } ? "OK" : $t->errors_to_string;
  0         0  
694 0         0 };
695             } #/ else [ if ( $t->VERSION >= "7.900048")]
696            
697 0         0 require Type::Tiny;
698 0         0 my $new = "Type::Tiny"->new( %opts );
699            
700             $new->coercion->add_type_coercions(
701             Types::Standard::HashRef() => sub {
702 0     0   0 my %params = %$_;
703 0 0       0 for my $k ( keys %params ) { delete $params{$_} unless $t->get_fields( $k ) }
  0         0  
704 0         0 $t->params->clear;
705 0         0 $t->params->add( %params );
706 0         0 eval { $t->validate };
  0         0  
707 0         0 $t->get_hash;
708             },
709 0         0 );
710            
711 0         0 $ttt_cache{ refaddr( $t ) } = $new;
712 0         0 weaken( $ttt_cache{ refaddr( $t ) } );
713 0         0 return $new;
714             } #/ sub _TypeTinyFromValidationClass
715              
716             sub _TypeTinyFromGeneric {
717 3     3   8 my $t = $_[0];
718            
719             my %opts = (
720 30 50   30   94 constraint => sub { $t->check( @_ ? @_ : $_ ) },
721 3         19 );
722            
723 2 50   2   8 $opts{message} = sub { $t->get_message( @_ ? @_ : $_ ) }
724 3 50       21 if $t->can( "get_message" );
725            
726 3 50       17 $opts{display_name} = $t->name if $t->can( "name" );
727            
728 1 50   1   80 $opts{coercion} = sub { $t->coerce( @_ ? @_ : $_ ) }
729 3 50 66     18 if $t->can( "has_coercion" )
      66        
730             && $t->has_coercion
731             && $t->can( "coerce" );
732            
733 3 0 33     30 if ( $t->can( 'can_be_inlined' )
      33        
734             && $t->can_be_inlined
735             && $t->can( 'inline_check' ) )
736             {
737 0     0   0 $opts{inlined} = sub { $t->inline_check( $_[1] ) };
  0         0  
738             }
739            
740 3         18 require Type::Tiny;
741 3         19 my $new = "Type::Tiny"->new( %opts );
742 3         12 $ttt_cache{ refaddr( $t ) } = $new;
743 3         12 weaken( $ttt_cache{ refaddr( $t ) } );
744 3         15 return $new;
745             } #/ sub _TypeTinyFromGeneric
746              
747             sub _TypeTinyFromMouse {
748 0     0   0 my $t = $_[0];
749            
750             my %opts = (
751 0 0   0   0 constraint => sub { $t->check( @_ ? @_ : $_ ) },
752 0 0   0   0 message => sub { $t->get_message( @_ ? @_ : $_ ) },
753 0         0 );
754            
755 0 0       0 $opts{display_name} = $t->name if $t->can( "name" );
756            
757 0 0   0   0 $opts{coercion} = sub { $t->coerce( @_ ? @_ : $_ ) }
758 0 0 0     0 if $t->can( "has_coercion" )
      0        
759             && $t->has_coercion
760             && $t->can( "coerce" );
761            
762 0 0       0 if ( $t->{'constraint_generator'} ) {
763             $opts{constraint_generator} = sub {
764            
765             # convert args into Moose native types; not strictly necessary
766 0 0   0   0 my @args = map { is_TypeTiny( $_ ) ? $_->mouse_type : $_ } @_;
  0         0  
767 0         0 _TypeTinyFromMouse( $t->parameterize( @args ) );
768 0         0 };
769             }
770            
771 0         0 require Type::Tiny;
772 0         0 my $new = "Type::Tiny"->new( %opts );
773 0         0 $ttt_cache{ refaddr( $t ) } = $new;
774 0         0 weaken( $ttt_cache{ refaddr( $t ) } );
775 0         0 return $new;
776             } #/ sub _TypeTinyFromMouse
777              
778             my $QFS;
779              
780             sub _TypeTinyFromCodeRef {
781 40019     40019   60693 my $t = $_[0];
782            
783             my %opts = (
784             constraint => sub {
785 93     93   139 return !!eval { $t->( $_ ) };
  93         216  
786             },
787             message => sub {
788 2     2   3 local $@;
789 2 50       4 eval { $t->( $_ ); 1 } or do { chomp $@; return $@ if $@ };
  2 100       58  
  1         8  
  1         8  
  1         12  
790 1         5 return sprintf( '%s did not pass type constraint', Type::Tiny::_dd( $_ ) );
791             },
792 40019         224867 );
793            
794 40019 100 66     243933 if ( $QFS ||= "Sub::Quote"->can( "quoted_from_sub" ) ) {
795 1 50       3 my ( undef, $perlstring, $captures ) = @{ $QFS->( $t ) || [] };
  1         5  
796 1 50       66 if ( $perlstring ) {
797 1         4 $perlstring = "!!eval{ $perlstring }";
798             $opts{inlined} = sub {
799 11     11   15 my $var = $_[1];
800 11 50       49 Sub::Quote::inlinify(
801             $perlstring,
802             $var,
803             $var eq q($_) ? '' : "local \$_ = $var;",
804             1,
805             );
806             }
807 1 50 33     9 if $perlstring && !$captures;
808             } #/ if ( $perlstring )
809             } #/ if ( $QFS ||= "Sub::Quote"...)
810            
811 40019         176295 require Type::Tiny;
812 40019         148872 my $new = "Type::Tiny"->new( %opts );
813 40019         134903 $ttt_cache{ refaddr( $t ) } = $new;
814 40019         122834 weaken( $ttt_cache{ refaddr( $t ) } );
815 40019         168243 return $new;
816             } #/ sub _TypeTinyFromCodeRef
817              
818             1;
819              
820             __END__