File Coverage

blib/lib/Types/TypeTiny.pm
Criterion Covered Total %
statement 288 437 62.0
branch 116 222 52.2
condition 47 78 60.2
subroutine 72 102 63.7
pod 8 24 33.3
total 531 863 58.7


line stmt bran cond sub pod time code
1             package Types::TypeTiny;
2              
3 273     273   5662 use 5.008001;
  273         967  
4 273     273   1598 use strict;
  273         1662  
  273         6358  
5 273     273   1528 use warnings;
  273         625  
  273         22244  
6              
7             our $AUTHORITY = 'cpan:TOBYINK';
8             our $VERSION = '2.002001';
9              
10             $VERSION =~ tr/_//d;
11              
12 273     273   2120 use Scalar::Util qw< blessed refaddr weaken >;
  273         725  
  273         40799  
13              
14             BEGIN {
15             *__XS = eval {
16 273         137292 require Type::Tiny::XS;
17 273         885195 'Type::Tiny::XS'->VERSION( '0.022' );
18 273         22785 1;
19             }
20             ? eval "sub () { '$Type::Tiny::XS::VERSION' }"
21 273 50   273   1079 : 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   2452 return unless @_ > 1; # uncoverable statement
45 273     273   2227 no warnings "redefine"; # uncoverable statement
  273         654  
  273         66690  
46 34         758 our @ISA = qw( Exporter::Tiny ); # uncoverable statement
47 34         245 require Exporter::Tiny; # uncoverable statement
48 34         143 my $next = \&Exporter::Tiny::import; # uncoverable statement
49 34         153 *import = $next; # uncoverable statement
50 34         94 my $class = shift; # uncoverable statement
51 34 50       227 my $opts = { ref( $_[0] ) ? %{ +shift } : () }; # uncoverable statement
  0         0  
52 34   50     292 $opts->{into} ||= scalar( caller ); # uncoverable statement
53 34         174 _mkall(); # uncoverable statement
54 34         287 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  
  115081     115081 0 329647  
  0     0 0 0  
  2     2 0 11  
  7     7 0 61  
  0     0 0 0  
  11536     11536 0 34717  
  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 604     604   1349 my $type = shift; # uncoverable statement
68 273     273   2302 no strict 'refs'; # uncoverable statement
  273         705  
  273         11735  
69 273     273   1917 no warnings 'redefine'; # uncoverable statement
  273         802  
  273         74818  
70 604         1934 *{ 'is_' . $type->name } = $type->compiled_check; # uncoverable statement
  604         1855  
71 604         2631 *{ 'assert_' . $type->name } = \&$type; # uncoverable statement
  604         2358  
72 604         3404 $type; # uncoverable statement
73             } # uncoverable statement
74              
75             sub _mkall {
76              
77             # uncoverable subroutine
78 115 100   115   487 return unless $INC{'Type/Tiny.pm'}; # uncoverable statement
79 114         509 __PACKAGE__->get_type( $_ ) for __PACKAGE__->type_names; # uncoverable statement
80             } # uncoverable statement
81              
82             sub meta {
83 25     25 1 226 return $_[0];
84             }
85              
86             sub type_names {
87 2259     2259 1 13057 qw( CodeLike StringLike TypeTiny HashLike ArrayLike _ForeignTypeConstraint );
88             }
89              
90             sub has_type {
91 766     766 1 1532 my %has = map +( $_ => 1 ), shift->type_names;
92 766         3538 !!$has{ $_[0] };
93             }
94              
95             sub get_type {
96 758     758 1 1493 my $self = shift;
97 758 100       1770 return unless $self->has_type( @_ );
98 273     273   2107 no strict qw(refs);
  273         737  
  273         41811  
99 757         1468 &{ $_[0] }();
  757         3263  
100             }
101              
102             sub coercion_names {
103 16     16 1 293 qw();
104             }
105              
106             sub has_coercion {
107 2     2 1 6 my %has = map +( $_ => 1 ), shift->coercion_names;
108 2         13 !!$has{ $_[0] };
109             }
110              
111             sub get_coercion {
112 1     1 1 3 my $self = shift;
113 1 50       10 return unless $self->has_coercion( @_ );
114 273     273   2025 no strict qw(refs);
  273         710  
  273         30449  
115 0         0 &{ $_[0] }(); # uncoverable statement
  0         0  
116             }
117              
118             my ( $__get_linear_isa_dfs, $tried_mro );
119             $__get_linear_isa_dfs = sub {
120             if ( !$tried_mro && eval { require mro } ) {
121             $__get_linear_isa_dfs = \&mro::get_linear_isa;
122             goto $__get_linear_isa_dfs;
123             }
124 273     273   1997 no strict 'refs';
  273         744  
  273         1271158  
125             my $classname = shift;
126             my @lin = ( $classname );
127             my %stored;
128             foreach my $parent ( @{"$classname\::ISA"} ) {
129             my $plin = $__get_linear_isa_dfs->( $parent );
130             foreach ( @$plin ) {
131             next if exists $stored{$_};
132             push( @lin, $_ );
133             $stored{$_} = 1;
134             }
135             }
136             return \@lin;
137             };
138              
139             sub _check_overload {
140 81     81   156 my $package = shift;
141 81 50       229 if ( ref $package ) {
142 81         214 $package = blessed( $package );
143 81 50       233 return !!0 if !defined $package;
144             }
145 81         136 my $op = shift;
146 81         406 my $mro = $__get_linear_isa_dfs->( $package );
147 81         189 foreach my $p ( @$mro ) {
148 93         220 my $fqmeth = $p . q{::(} . $op;
149 93 100       141 return !!1 if defined &{$fqmeth};
  93         687  
150             }
151 58         483 !!0;
152             } #/ sub _check_overload
153              
154             sub _get_check_overload_sub {
155 241 50   241   533 if ( $Type::Tiny::AvoidCallbacks ) {
156             return
157 241         1266 '(sub { require overload; overload::Overloaded(ref $_[0] or $_[0]) and overload::Method((ref $_[0] or $_[0]), $_[1]) })->';
158             }
159 0         0 return 'Types::TypeTiny::_check_overload';
160             }
161              
162             sub StringLike () {
163 380 100   380 0 21899 return $cache{StringLike} if defined $cache{StringLike};
164 248         1360 require Type::Tiny;
165             my %common = (
166             name => "StringLike",
167             library => __PACKAGE__,
168             constraint => sub {
169 55 100 100 55   545 defined( $_ ) && !ref( $_ )
      100        
170             or blessed( $_ ) && _check_overload( $_, q[""] );
171             },
172             inlined => sub {
173 55     55   215 qq/defined($_[1]) && !ref($_[1]) or Scalar::Util::blessed($_[1]) && ${\ +_get_check_overload_sub() }($_[1], q[""])/;
  55         122  
174             },
175 1     1   5 type_default => sub { return '' },
176 248         3981 );
177 248         730 if ( __XS ) {
178 248         1189 my $xsub = Type::Tiny::XS::get_coderef_for( 'StringLike' );
179 248         3513 my $xsubname = Type::Tiny::XS::get_subname_for( 'StringLike' );
180 248         1937 my $inlined = $common{inlined};
181             $cache{StringLike} = "Type::Tiny"->new(
182             %common,
183             compiled_type_constraint => $xsub,
184             inlined => sub {
185            
186             # uncoverable subroutine
187 359 100 66 359   3619 ( $Type::Tiny::AvoidCallbacks or not $xsubname )
188             ? goto( $inlined )
189             : qq/$xsubname($_[1])/ # uncoverable statement
190             },
191 248         2781 );
192 248         1515 _reinstall_subs $cache{StringLike};
193             } #/ if ( __XS )
194             else {
195             $cache{StringLike} = "Type::Tiny"->new( %common );
196             }
197             } #/ sub StringLike
198              
199             sub HashLike (;@) {
200 193 100 100 193 0 22528 return $cache{HashLike} if defined( $cache{HashLike} ) && !@_;
201 117         658 require Type::Tiny;
202             my %common = (
203             name => "HashLike",
204             library => __PACKAGE__,
205             constraint => sub {
206 65 100 100 65   609 ref( $_ ) eq q[HASH]
207             or blessed( $_ ) && _check_overload( $_, q[%{}] );
208             },
209             inlined => sub {
210 65     65   250 qq/ref($_[1]) eq q[HASH] or Scalar::Util::blessed($_[1]) && ${\ +_get_check_overload_sub() }($_[1], q[\%{}])/;
  65         159  
211             },
212 1     1   5 type_default => sub { return {} },
213             constraint_generator => sub {
214 2     2   6 my $param = TypeTiny()->assert_coerce( shift );
215 2         6 my $check = $param->compiled_check;
216 2         4 if ( __XS ge '0.025' ) {
217 2         12 my $paramname = Type::Tiny::XS::is_known( $check );
218 2 50       25 my $xsub = defined($paramname)
219             ? Type::Tiny::XS::get_coderef_for( "HashLike[$paramname]" )
220             : undef;
221 2 50       100 return $xsub if $xsub;
222             }
223             sub {
224 0         0 my %hash = %$_;
225 0         0 for my $key ( sort keys %hash ) {
226 0 0       0 $check->( $hash{$key} ) or return 0;
227             }
228 0         0 return 1;
229 0         0 };
230             },
231             inline_generator => sub {
232 2     2   5 my $param = TypeTiny()->assert_coerce( shift );
233 2 50       6 return unless $param->can_be_inlined;
234 2         7 my $check = $param->compiled_check;
235 2         4 my $xsubname;
236 2         15 if ( __XS ge '0.025' ) {
237 2         9 my $paramname = Type::Tiny::XS::is_known( $check );
238 2 50       22 $xsubname = defined($paramname)
239             ? Type::Tiny::XS::get_subname_for( "HashLike[$paramname]" )
240             : undef;
241             }
242             sub {
243 23         43 my $var = pop;
244 23 100 66     117 return "$xsubname($var)" if $xsubname && !$Type::Tiny::AvoidCallbacks;
245 10         31 my $code = sprintf(
246             'do { my $ok=1; my %%h = %%{%s}; for my $k (sort keys %%h) { ($ok=0,next) unless (%s) }; $ok }',
247             $var,
248             $param->inline_check( '$h{$k}' ),
249             );
250 10         34 return ( undef, $code );
251 2         34 };
252             },
253             coercion_generator => sub {
254 1     1   4 my ( $parent, $child, $param ) = @_;
255 1 50       4 return unless $param->has_coercion;
256 1         6 my $coercible = $param->coercion->_source_type_union->compiled_check;
257 1         10 my $C = "Type::Coercion"->new( type_constraint => $child );
258             $C->add_type_coercions(
259             $parent => sub {
260 4 50       69 my $origref = @_ ? $_[0] : $_;
261 4         14 my %orig = %$origref;
262 4         17 my %new;
263 4         16 for my $k ( sort keys %orig ) {
264 8 100       84 return $origref unless $coercible->( $orig{$k} );
265 6         88 $new{$k} = $param->coerce( $orig{$k} );
266             }
267 2         38 \%new;
268             },
269 1         9 );
270 1         3 return $C;
271             },
272 117         3131 );
273 117         927 if ( __XS ) {
274 117         510 my $xsub = Type::Tiny::XS::get_coderef_for( 'HashLike' );
275 117         1679 my $xsubname = Type::Tiny::XS::get_subname_for( 'HashLike' );
276 117         939 my $inlined = $common{inlined};
277             $cache{HashLike} = "Type::Tiny"->new(
278             %common,
279             compiled_type_constraint => $xsub,
280             inlined => sub {
281            
282             # uncoverable subroutine
283 239 100 66 239   1884 ( $Type::Tiny::AvoidCallbacks or not $xsubname )
284             ? goto( $inlined )
285             : qq/$xsubname($_[1])/ # uncoverable statement
286             },
287 117         1199 );
288 117         551 _reinstall_subs $cache{HashLike};
289             } #/ if ( __XS )
290             else {
291             $cache{HashLike} = "Type::Tiny"->new( %common );
292             }
293            
294 117 100       1136 @_ ? $cache{HashLike}->parameterize( @{ $_[0] } ) : $cache{HashLike};
  2         14  
295             } #/ sub HashLike (;@)
296              
297             sub ArrayLike (;@) {
298 194 100 100 194 0 23111 return $cache{ArrayLike} if defined( $cache{ArrayLike} ) && !@_;
299 118         682 require Type::Tiny;
300             my %common = (
301             name => "ArrayLike",
302             library => __PACKAGE__,
303             constraint => sub {
304 65 100 100 65   556 ref( $_ ) eq q[ARRAY]
305             or blessed( $_ ) && _check_overload( $_, q[@{}] );
306             },
307             inlined => sub {
308 65     65   223 qq/ref($_[1]) eq q[ARRAY] or Scalar::Util::blessed($_[1]) && ${\ +_get_check_overload_sub() }($_[1], q[\@{}])/;
  65         136  
309             },
310 1     1   7 type_default => sub { return [] },
311             constraint_generator => sub {
312 2     2   8 my $param = TypeTiny()->assert_coerce( shift );
313 2         7 my $check = $param->compiled_check;
314 2         5 if ( __XS ge '0.025' ) {
315 2         9 my $paramname = Type::Tiny::XS::is_known( $check );
316 2 50       22 my $xsub = defined($paramname)
317             ? Type::Tiny::XS::get_coderef_for( "ArrayLike[$paramname]" )
318             : undef;
319 2 50       99 return $xsub if $xsub;
320             }
321             sub {
322 0         0 my @arr = @$_;
323 0         0 for my $val ( @arr ) {
324 0 0       0 $check->( $val ) or return 0;
325             }
326 0         0 return 1;
327 0         0 };
328             },
329             inline_generator => sub {
330 2     2   6 my $param = TypeTiny()->assert_coerce( shift );
331 2 50       6 return unless $param->can_be_inlined;
332 2         6 my $check = $param->compiled_check;
333 2         5 my $xsubname;
334 2         5 if ( __XS ge '0.025' ) {
335 2         7 my $paramname = Type::Tiny::XS::is_known( $check );
336 2 50       30 $xsubname = defined($paramname)
337             ? Type::Tiny::XS::get_subname_for( "ArrayLike[$paramname]" )
338             : undef;
339             }
340             sub {
341 23         44 my $var = pop;
342 23 100 66     126 return "$xsubname($var)" if $xsubname && !$Type::Tiny::AvoidCallbacks;
343 10         27 my $code = sprintf(
344             'do { my $ok=1; for my $v (@{%s}) { ($ok=0,next) unless (%s) }; $ok }',
345             $var,
346             $param->inline_check( '$v' ),
347             );
348 10         29 return ( undef, $code );
349 2         24 };
350             },
351             coercion_generator => sub {
352 1     1   3 my ( $parent, $child, $param ) = @_;
353 1 50       5 return unless $param->has_coercion;
354 1         5 my $coercible = $param->coercion->_source_type_union->compiled_check;
355 1         10 my $C = "Type::Coercion"->new( type_constraint => $child );
356             $C->add_type_coercions(
357             $parent => sub {
358 4 50       72 my $origref = @_ ? $_[0] : $_;
359 4         10 my @orig = @$origref;
360 4         12 my @new;
361 4         8 for my $v ( @orig ) {
362 10 100       102 return $origref unless $coercible->( $v );
363 8         101 push @new, $param->coerce( $v );
364             }
365 2         43 \@new;
366             },
367 1         19 );
368 1         9 return $C;
369             },
370 118         2280 );
371 118         282 if ( __XS ) {
372 118         496 my $xsub = Type::Tiny::XS::get_coderef_for( 'ArrayLike' );
373 118         1691 my $xsubname = Type::Tiny::XS::get_subname_for( 'ArrayLike' );
374 118         903 my $inlined = $common{inlined};
375             $cache{ArrayLike} = "Type::Tiny"->new(
376             %common,
377             compiled_type_constraint => $xsub,
378             inlined => sub {
379            
380             # uncoverable subroutine
381 240 100 66 240   2012 ( $Type::Tiny::AvoidCallbacks or not $xsubname )
382             ? goto( $inlined )
383             : qq/$xsubname($_[1])/ # uncoverable statement
384             },
385 118         1125 );
386 118         583 _reinstall_subs $cache{ArrayLike};
387             } #/ if ( __XS )
388             else {
389             $cache{ArrayLike} = "Type::Tiny"->new( %common );
390             }
391            
392 118 100       1192 @_ ? $cache{ArrayLike}->parameterize( @{ $_[0] } ) : $cache{ArrayLike};
  2         11  
393             } #/ sub ArrayLike (;@)
394              
395             if ( $] ge '5.014' ) {
396             &Scalar::Util::set_prototype( $_, ';$' ) for \&HashLike, \&ArrayLike;
397             }
398              
399             sub CodeLike () {
400 199 100   199 0 20939 return $cache{CodeLike} if $cache{CodeLike};
401 121         629 require Type::Tiny;
402             my %common = (
403             name => "CodeLike",
404             constraint => sub {
405 56 100 100 56   502 ref( $_ ) eq q[CODE]
406             or blessed( $_ ) && _check_overload( $_, q[&{}] );
407             },
408             inlined => sub {
409 56     56   191 qq/ref($_[1]) eq q[CODE] or Scalar::Util::blessed($_[1]) && ${\ +_get_check_overload_sub() }($_[1], q[\&{}])/;
  56         112  
410             },
411 1     1   15 type_default => sub { return sub {} },
412 121         1871 library => __PACKAGE__,
413             );
414 121         314 if ( __XS ) {
415 121         796 my $xsub = Type::Tiny::XS::get_coderef_for( 'CodeLike' );
416 121         2205 my $xsubname = Type::Tiny::XS::get_subname_for( 'CodeLike' );
417 121         1060 my $inlined = $common{inlined};
418             $cache{CodeLike} = "Type::Tiny"->new(
419             %common,
420             compiled_type_constraint => $xsub,
421             inlined => sub {
422            
423             # uncoverable subroutine
424 234 100 66 234   2075 ( $Type::Tiny::AvoidCallbacks or not $xsubname )
425             ? goto( $inlined )
426             : qq/$xsubname($_[1])/ # uncoverable statement
427             },
428 121         1340 );
429 121         643 _reinstall_subs $cache{CodeLike};
430             } #/ if ( __XS )
431             else {
432             $cache{CodeLike} = "Type::Tiny"->new( %common );
433             }
434             } #/ sub CodeLike
435              
436             sub TypeTiny () {
437 126818 100   126818 0 472790 return $cache{TypeTiny} if defined $cache{TypeTiny};
438 249         1507 require Type::Tiny;
439             $cache{TypeTiny} = "Type::Tiny"->new(
440             name => "TypeTiny",
441 56 100   56   500 constraint => sub { blessed( $_ ) && $_->isa( q[Type::Tiny] ) },
442             inlined => sub {
443 383     383   994 my $var = $_[1];
444 383         2134 "Scalar::Util::blessed($var) && $var\->isa(q[Type::Tiny])";
445             },
446 1     1   642 type_default => sub { require Types::Standard; return Types::Standard::Any() },
  1         8  
447             library => __PACKAGE__,
448             _build_coercion => sub {
449 15     15   57 my $c = shift;
450 15         83 $c->add_type_coercions( _ForeignTypeConstraint(), \&to_TypeTiny );
451 15         105 $c->freeze;
452             },
453 249         4192 );
454             } #/ sub TypeTiny
455              
456             sub _ForeignTypeConstraint () {
457 203 100   203   20894 return $cache{_ForeignTypeConstraint} if defined $cache{_ForeignTypeConstraint};
458 114         671 require Type::Tiny;
459             $cache{_ForeignTypeConstraint} = "Type::Tiny"->new(
460             name => "_ForeignTypeConstraint",
461             constraint => \&_is_ForeignTypeConstraint,
462             inlined => sub {
463 146     146   672 qq/ref($_[1]) && do { require Types::TypeTiny; Types::TypeTiny::_is_ForeignTypeConstraint($_[1]) }/;
464             },
465 114         949 library => __PACKAGE__,
466             );
467             } #/ sub _ForeignTypeConstraint
468              
469             my %ttt_cache;
470              
471             sub _is_ForeignTypeConstraint {
472 200 50   200   1010 my $t = @_ ? $_[0] : $_;
473 200 100       535 return !!1 if ref $t eq 'CODE';
474 194 100       596 if ( my $class = blessed $t ) {
475 80 50       450 return !!0 if $class->isa( "Type::Tiny" );
476 80 50       270 return !!1 if $class->isa( "Moose::Meta::TypeConstraint" );
477 80 50       269 return !!1 if $class->isa( "MooseX::Types::TypeDecorator" );
478 80 50       297 return !!1 if $class->isa( "Validation::Class::Simple" );
479 80 50       257 return !!1 if $class->isa( "Validation::Class" );
480 80 100       323 return !!1 if $t->can( "check" );
481             }
482 189         1013 !!0;
483             } #/ sub _is_ForeignTypeConstraint
484              
485             sub to_TypeTiny {
486 144626 50   144626 1 273544 my $t = @_ ? $_[0] : $_;
487            
488 144626 100       311527 return $t unless ( my $ref = ref $t );
489 143517 100       514164 return $t if $ref =~ /^Type::Tiny\b/;
490            
491 40092 50       136836 return $ttt_cache{ refaddr( $t ) } if $ttt_cache{ refaddr( $t ) };
492            
493             #<<<
494 40092 100       99453 if ( my $class = blessed $t) {
495 50 50       411 return $t if $class->isa( "Type::Tiny" );
496 50 50       163 return _TypeTinyFromMoose( $t ) if $class eq "MooseX::Types::TypeDecorator"; # needed before MooseX::Types 0.35.
497 50 50       297 return _TypeTinyFromMoose( $t ) if $class->isa( "Moose::Meta::TypeConstraint" );
498 50 50       273 return _TypeTinyFromMoose( $t ) if $class->isa( "MooseX::Types::TypeDecorator" );
499 50 50       282 return _TypeTinyFromMouse( $t ) if $class->isa( "Mouse::Meta::TypeConstraint" );
500 50 50       273 return _TypeTinyFromValidationClass( $t ) if $class->isa( "Validation::Class::Simple" );
501 50 50       284 return _TypeTinyFromValidationClass( $t ) if $class->isa( "Validation::Class" );
502 50 100 66     694 return $t->to_TypeTiny if $t->can( "DOES" ) && $t->DOES( "Type::Library::Compiler::TypeConstraint" ) && $t->can( "to_TypeTiny" );
      66        
503 44 100       349 return _TypeTinyFromGeneric( $t ) if $t->can( "check" ); # i.e. Type::API::Constraint
504             } #/ if ( my $class = blessed...)
505             #>>>
506            
507 40083 100       112495 return _TypeTinyFromCodeRef( $t ) if $ref eq q(CODE);
508            
509 64         291 $t;
510             } #/ sub to_TypeTiny
511              
512             sub _TypeTinyFromMoose {
513 0     0   0 my $t = $_[0];
514            
515 0 0       0 if ( ref $t->{"Types::TypeTiny::to_TypeTiny"} ) {
516 0         0 return $t->{"Types::TypeTiny::to_TypeTiny"};
517             }
518            
519 0 0       0 if ( $t->name ne '__ANON__' ) {
520 0         0 require Types::Standard;
521 0         0 my $ts = 'Types::Standard'->get_type( $t->name );
522 0 0       0 return $ts if $ts->{_is_core};
523             }
524            
525             #<<<
526 0 0       0 my ( $tt_class, $tt_opts ) =
    0          
    0          
    0          
    0          
    0          
527             $t->can( 'parameterize' ) ? _TypeTinyFromMoose_parameterizable( $t ) :
528             $t->isa( 'Moose::Meta::TypeConstraint::Enum' ) ? _TypeTinyFromMoose_enum( $t ) :
529             $t->isa( 'Moose::Meta::TypeConstraint::Class' ) ? _TypeTinyFromMoose_class( $t ) :
530             $t->isa( 'Moose::Meta::TypeConstraint::Role' ) ? _TypeTinyFromMoose_role( $t ) :
531             $t->isa( 'Moose::Meta::TypeConstraint::Union' ) ? _TypeTinyFromMoose_union( $t ) :
532             $t->isa( 'Moose::Meta::TypeConstraint::DuckType' ) ? _TypeTinyFromMoose_ducktype( $t ) :
533             _TypeTinyFromMoose_baseclass( $t );
534             #>>>
535            
536             # Standard stuff to do with all type constraints from Moose,
537             # regardless of variety.
538 0         0 $tt_opts->{moose_type} = $t;
539 0         0 $tt_opts->{display_name} = $t->name;
540 0     0   0 $tt_opts->{message} = sub { $t->get_message( $_ ) }
541 0 0       0 if $t->has_message;
542            
543 0         0 my $new = $tt_class->new( %$tt_opts );
544 0         0 $ttt_cache{ refaddr( $t ) } = $new;
545 0         0 weaken( $ttt_cache{ refaddr( $t ) } );
546            
547 0 0       0 $new->{coercion} = do {
548 0         0 require Type::Coercion::FromMoose;
549 0         0 'Type::Coercion::FromMoose'->new(
550             type_constraint => $new,
551             moose_coercion => $t->coercion,
552             );
553             } if $t->has_coercion;
554            
555 0         0 return $new;
556             } #/ sub _TypeTinyFromMoose
557              
558             sub _TypeTinyFromMoose_baseclass {
559 0     0   0 my $t = shift;
560 0         0 my %opts;
561 0 0       0 $opts{parent} = to_TypeTiny( $t->parent ) if $t->has_parent;
562 0         0 $opts{constraint} = $t->constraint;
563 0     0   0 $opts{inlined} = sub { shift; $t->_inline_check( @_ ) }
  0         0  
564 0 0 0     0 if $t->can( "can_be_inlined" ) && $t->can_be_inlined;
565            
566             # Cowardly refuse to inline types that need to close over stuff
567 0 0       0 if ( $opts{inlined} ) {
568 0 0       0 my %env = %{ $t->inline_environment || {} };
  0         0  
569 0 0       0 delete( $opts{inlined} ) if keys %env;
570             }
571            
572 0         0 require Type::Tiny;
573 0         0 return 'Type::Tiny' => \%opts;
574             } #/ sub _TypeTinyFromMoose_baseclass
575              
576             sub _TypeTinyFromMoose_union {
577 0     0   0 my $t = shift;
578 0         0 my @mapped = map _TypeTinyFromMoose( $_ ), @{ $t->type_constraints };
  0         0  
579 0         0 require Type::Tiny::Union;
580 0         0 return 'Type::Tiny::Union' => { type_constraints => \@mapped };
581             }
582              
583             sub _TypeTinyFromMoose_enum {
584 0     0   0 my $t = shift;
585 0         0 require Type::Tiny::Enum;
586 0         0 return 'Type::Tiny::Enum' => { values => [ @{ $t->values } ] };
  0         0  
587             }
588              
589             sub _TypeTinyFromMoose_class {
590 0     0   0 my $t = shift;
591 0         0 require Type::Tiny::Class;
592 0         0 return 'Type::Tiny::Class' => { class => $t->class };
593             }
594              
595             sub _TypeTinyFromMoose_role {
596 0     0   0 my $t = shift;
597 0         0 require Type::Tiny::Role;
598 0         0 return 'Type::Tiny::Role' => { role => $t->role };
599             }
600              
601             sub _TypeTinyFromMoose_ducktype {
602 0     0   0 my $t = shift;
603 0         0 require Type::Tiny::Duck;
604 0         0 return 'Type::Tiny::Duck' => { methods => [ @{ $t->methods } ] };
  0         0  
605             }
606              
607             sub _TypeTinyFromMoose_parameterizable {
608 0     0   0 my $t = shift;
609 0         0 my ( $class, $opts ) = _TypeTinyFromMoose_baseclass( $t );
610             $opts->{constraint_generator} = sub {
611            
612             # convert args into Moose native types; not strictly necessary
613 0 0   0   0 my @args = map { is_TypeTiny( $_ ) ? $_->moose_type : $_ } @_;
  0         0  
614 0         0 _TypeTinyFromMoose( $t->parameterize( @args ) );
615 0         0 };
616 0         0 return ( $class, $opts );
617             } #/ sub _TypeTinyFromMoose_parameterizable
618              
619             sub _TypeTinyFromValidationClass {
620 0     0   0 my $t = $_[0];
621            
622 0         0 require Type::Tiny;
623 0         0 require Types::Standard;
624            
625 0         0 my %opts = (
626             parent => Types::Standard::HashRef(),
627             _validation_class => $t,
628             );
629            
630 0 0       0 if ( $t->VERSION >= "7.900048" ) {
631             $opts{constraint} = sub {
632 0     0   0 $t->params->clear;
633 0         0 $t->params->add( %$_ );
634 0         0 my $f = $t->filtering;
635 0         0 $t->filtering( 'off' );
636 0         0 my $r = eval { $t->validate };
  0         0  
637 0   0     0 $t->filtering( $f || 'pre' );
638 0         0 return $r;
639 0         0 };
640             $opts{message} = sub {
641 0     0   0 $t->params->clear;
642 0         0 $t->params->add( %$_ );
643 0         0 my $f = $t->filtering;
644 0         0 $t->filtering( 'off' );
645 0 0       0 my $r = ( eval { $t->validate } ? "OK" : $t->errors_to_string );
  0         0  
646 0   0     0 $t->filtering( $f || 'pre' );
647 0         0 return $r;
648 0         0 };
649             } #/ if ( $t->VERSION >= "7.900048")
650             else # need to use hackish method
651             {
652             $opts{constraint} = sub {
653 0     0   0 $t->params->clear;
654 0         0 $t->params->add( %$_ );
655 273     273   2599 no warnings "redefine";
  273         750  
  273         38105  
656 0         0 local *Validation::Class::Directive::Filters::execute_filtering = sub { $_[0] };
  0         0  
657 0         0 eval { $t->validate };
  0         0  
658 0         0 };
659             $opts{message} = sub {
660 0     0   0 $t->params->clear;
661 0         0 $t->params->add( %$_ );
662 273     273   2223 no warnings "redefine";
  273         714  
  273         338480  
663 0         0 local *Validation::Class::Directive::Filters::execute_filtering = sub { $_[0] };
  0         0  
664 0 0       0 eval { $t->validate } ? "OK" : $t->errors_to_string;
  0         0  
665 0         0 };
666             } #/ else [ if ( $t->VERSION >= "7.900048")]
667            
668 0         0 require Type::Tiny;
669 0         0 my $new = "Type::Tiny"->new( %opts );
670            
671             $new->coercion->add_type_coercions(
672             Types::Standard::HashRef() => sub {
673 0     0   0 my %params = %$_;
674 0 0       0 for my $k ( keys %params ) { delete $params{$_} unless $t->get_fields( $k ) }
  0         0  
675 0         0 $t->params->clear;
676 0         0 $t->params->add( %params );
677 0         0 eval { $t->validate };
  0         0  
678 0         0 $t->get_hash;
679             },
680 0         0 );
681            
682 0         0 $ttt_cache{ refaddr( $t ) } = $new;
683 0         0 weaken( $ttt_cache{ refaddr( $t ) } );
684 0         0 return $new;
685             } #/ sub _TypeTinyFromValidationClass
686              
687             sub _TypeTinyFromGeneric {
688 3     3   5 my $t = $_[0];
689            
690             my %opts = (
691 30 50   30   84 constraint => sub { $t->check( @_ ? @_ : $_ ) },
692 3         13 );
693            
694 2 50   2   8 $opts{message} = sub { $t->get_message( @_ ? @_ : $_ ) }
695 3 50       18 if $t->can( "get_message" );
696            
697 3 50       13 $opts{display_name} = $t->name if $t->can( "name" );
698            
699 1 50   1   88 $opts{coercion} = sub { $t->coerce( @_ ? @_ : $_ ) }
700 3 50 66     18 if $t->can( "has_coercion" )
      66        
701             && $t->has_coercion
702             && $t->can( "coerce" );
703            
704 3 0 33     28 if ( $t->can( 'can_be_inlined' )
      33        
705             && $t->can_be_inlined
706             && $t->can( 'inline_check' ) )
707             {
708 0     0   0 $opts{inlined} = sub { $t->inline_check( $_[1] ) };
  0         0  
709             }
710            
711 3         16 require Type::Tiny;
712 3         15 my $new = "Type::Tiny"->new( %opts );
713 3         13 $ttt_cache{ refaddr( $t ) } = $new;
714 3         11 weaken( $ttt_cache{ refaddr( $t ) } );
715 3         15 return $new;
716             } #/ sub _TypeTinyFromGeneric
717              
718             sub _TypeTinyFromMouse {
719 0     0   0 my $t = $_[0];
720            
721             my %opts = (
722 0 0   0   0 constraint => sub { $t->check( @_ ? @_ : $_ ) },
723 0 0   0   0 message => sub { $t->get_message( @_ ? @_ : $_ ) },
724 0         0 );
725            
726 0 0       0 $opts{display_name} = $t->name if $t->can( "name" );
727            
728 0 0   0   0 $opts{coercion} = sub { $t->coerce( @_ ? @_ : $_ ) }
729 0 0 0     0 if $t->can( "has_coercion" )
      0        
730             && $t->has_coercion
731             && $t->can( "coerce" );
732            
733 0 0       0 if ( $t->{'constraint_generator'} ) {
734             $opts{constraint_generator} = sub {
735            
736             # convert args into Moose native types; not strictly necessary
737 0 0   0   0 my @args = map { is_TypeTiny( $_ ) ? $_->mouse_type : $_ } @_;
  0         0  
738 0         0 _TypeTinyFromMouse( $t->parameterize( @args ) );
739 0         0 };
740             }
741            
742 0         0 require Type::Tiny;
743 0         0 my $new = "Type::Tiny"->new( %opts );
744 0         0 $ttt_cache{ refaddr( $t ) } = $new;
745 0         0 weaken( $ttt_cache{ refaddr( $t ) } );
746 0         0 return $new;
747             } #/ sub _TypeTinyFromMouse
748              
749             my $QFS;
750              
751             sub _TypeTinyFromCodeRef {
752 40019     40019   59649 my $t = $_[0];
753            
754             my %opts = (
755             constraint => sub {
756 93     93   125 return !!eval { $t->( $_ ) };
  93         191  
757             },
758             message => sub {
759 2     2   4 local $@;
760 2 50       3 eval { $t->( $_ ); 1 } or do { chomp $@; return $@ if $@ };
  2 100       8  
  1         6  
  1         8  
  1         12  
761 1         4 return sprintf( '%s did not pass type constraint', Type::Tiny::_dd( $_ ) );
762             },
763 40019         212731 );
764            
765 40019 100 66     230397 if ( $QFS ||= "Sub::Quote"->can( "quoted_from_sub" ) ) {
766 1 50       3 my ( undef, $perlstring, $captures ) = @{ $QFS->( $t ) || [] };
  1         4  
767 1 50       70 if ( $perlstring ) {
768 1         4 $perlstring = "!!eval{ $perlstring }";
769             $opts{inlined} = sub {
770 11     11   15 my $var = $_[1];
771 11 50       45 Sub::Quote::inlinify(
772             $perlstring,
773             $var,
774             $var eq q($_) ? '' : "local \$_ = $var;",
775             1,
776             );
777             }
778 1 50 33     11 if $perlstring && !$captures;
779             } #/ if ( $perlstring )
780             } #/ if ( $QFS ||= "Sub::Quote"...)
781            
782 40019         160121 require Type::Tiny;
783 40019         142401 my $new = "Type::Tiny"->new( %opts );
784 40019         124372 $ttt_cache{ refaddr( $t ) } = $new;
785 40019         110606 weaken( $ttt_cache{ refaddr( $t ) } );
786 40019         170711 return $new;
787             } #/ sub _TypeTinyFromCodeRef
788              
789             1;
790              
791             __END__