Beginning of dzilization
[gitmo/Moose.git] / lib / Moose / Util / TypeConstraints.pm
1
2 package Moose::Util::TypeConstraints;
3
4 use Carp ();
5 use List::MoreUtils qw( all any );
6 use Scalar::Util qw( blessed reftype );
7 use Moose::Exporter;
8
9 our $AUTHORITY = 'cpan:STEVAN';
10
11 ## --------------------------------------------------------
12 # Prototyped subs must be predeclared because we have a
13 # circular dependency with Moose::Meta::Attribute et. al.
14 # so in case of us being use'd first the predeclaration
15 # ensures the prototypes are in scope when consumers are
16 # compiled.
17
18 # dah sugah!
19 sub where (&);
20 sub via (&);
21 sub message (&);
22 sub optimize_as (&);
23
24 ## --------------------------------------------------------
25
26 use Moose::Deprecated;
27 use Moose::Meta::TypeConstraint;
28 use Moose::Meta::TypeConstraint::Union;
29 use Moose::Meta::TypeConstraint::Parameterized;
30 use Moose::Meta::TypeConstraint::Parameterizable;
31 use Moose::Meta::TypeConstraint::Class;
32 use Moose::Meta::TypeConstraint::Role;
33 use Moose::Meta::TypeConstraint::Enum;
34 use Moose::Meta::TypeConstraint::DuckType;
35 use Moose::Meta::TypeCoercion;
36 use Moose::Meta::TypeCoercion::Union;
37 use Moose::Meta::TypeConstraint::Registry;
38 use Moose::Util::TypeConstraints::OptimizedConstraints;
39
40 Moose::Exporter->setup_import_methods(
41     as_is => [
42         qw(
43             type subtype class_type role_type maybe_type duck_type
44             as where message optimize_as
45             coerce from via
46             enum
47             find_type_constraint
48             register_type_constraint
49             match_on_type )
50     ],
51 );
52
53 ## --------------------------------------------------------
54 ## type registry and some useful functions for it
55 ## --------------------------------------------------------
56
57 my $REGISTRY = Moose::Meta::TypeConstraint::Registry->new;
58
59 sub get_type_constraint_registry {$REGISTRY}
60 sub list_all_type_constraints    { keys %{ $REGISTRY->type_constraints } }
61
62 sub export_type_constraints_as_functions {
63     my $pkg = caller();
64     no strict 'refs';
65     foreach my $constraint ( keys %{ $REGISTRY->type_constraints } ) {
66         my $tc = $REGISTRY->get_type_constraint($constraint)
67             ->_compiled_type_constraint;
68         *{"${pkg}::${constraint}"}
69             = sub { $tc->( $_[0] ) ? 1 : undef };    # the undef is for compat
70     }
71 }
72
73 sub create_type_constraint_union {
74     my @type_constraint_names;
75
76     if ( scalar @_ == 1 && _detect_type_constraint_union( $_[0] ) ) {
77         @type_constraint_names = _parse_type_constraint_union( $_[0] );
78     }
79     else {
80         @type_constraint_names = @_;
81     }
82
83     ( scalar @type_constraint_names >= 2 )
84         || __PACKAGE__->_throw_error(
85         "You must pass in at least 2 type names to make a union");
86
87     my @type_constraints = map {
88         find_or_parse_type_constraint($_)
89             || __PACKAGE__->_throw_error(
90             "Could not locate type constraint ($_) for the union");
91     } @type_constraint_names;
92
93     return Moose::Meta::TypeConstraint::Union->new(
94         type_constraints => \@type_constraints );
95 }
96
97 sub create_parameterized_type_constraint {
98     my $type_constraint_name = shift;
99     my ( $base_type, $type_parameter )
100         = _parse_parameterized_type_constraint($type_constraint_name);
101
102     ( defined $base_type && defined $type_parameter )
103         || __PACKAGE__->_throw_error(
104         "Could not parse type name ($type_constraint_name) correctly");
105
106     if ( $REGISTRY->has_type_constraint($base_type) ) {
107         my $base_type_tc = $REGISTRY->get_type_constraint($base_type);
108         return _create_parameterized_type_constraint(
109             $base_type_tc,
110             $type_parameter
111         );
112     }
113     else {
114         __PACKAGE__->_throw_error(
115             "Could not locate the base type ($base_type)");
116     }
117 }
118
119 sub _create_parameterized_type_constraint {
120     my ( $base_type_tc, $type_parameter ) = @_;
121     if ( $base_type_tc->can('parameterize') ) {
122         return $base_type_tc->parameterize($type_parameter);
123     }
124     else {
125         return Moose::Meta::TypeConstraint::Parameterized->new(
126             name   => $base_type_tc->name . '[' . $type_parameter . ']',
127             parent => $base_type_tc,
128             type_parameter =>
129                 find_or_create_isa_type_constraint($type_parameter),
130         );
131     }
132 }
133
134 #should we also support optimized checks?
135 sub create_class_type_constraint {
136     my ( $class, $options ) = @_;
137
138 # too early for this check
139 #find_type_constraint("ClassName")->check($class)
140 #    || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
141
142     my %options = (
143         class => $class,
144         name  => $class,
145         %{ $options || {} },
146     );
147
148     $options{name} ||= "__ANON__";
149
150     Moose::Meta::TypeConstraint::Class->new(%options);
151 }
152
153 sub create_role_type_constraint {
154     my ( $role, $options ) = @_;
155
156 # too early for this check
157 #find_type_constraint("ClassName")->check($class)
158 #    || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
159
160     my %options = (
161         role => $role,
162         name => $role,
163         %{ $options || {} },
164     );
165
166     $options{name} ||= "__ANON__";
167
168     Moose::Meta::TypeConstraint::Role->new(%options);
169 }
170
171 sub find_or_create_type_constraint {
172     my ( $type_constraint_name, $options_for_anon_type ) = @_;
173
174     if ( my $constraint
175         = find_or_parse_type_constraint($type_constraint_name) ) {
176         return $constraint;
177     }
178     elsif ( defined $options_for_anon_type ) {
179
180         # NOTE:
181         # if there is no $options_for_anon_type
182         # specified, then we assume they don't
183         # want to create one, and return nothing.
184
185         # otherwise assume that we should create
186         # an ANON type with the $options_for_anon_type
187         # options which can be passed in. It should
188         # be noted that these don't get registered
189         # so we need to return it.
190         # - SL
191         return Moose::Meta::TypeConstraint->new(
192             name => '__ANON__',
193             %{$options_for_anon_type}
194         );
195     }
196
197     return;
198 }
199
200 sub find_or_create_isa_type_constraint {
201     my $type_constraint_name = shift;
202     find_or_parse_type_constraint($type_constraint_name)
203         || create_class_type_constraint($type_constraint_name);
204 }
205
206 sub find_or_create_does_type_constraint {
207     my $type_constraint_name = shift;
208     find_or_parse_type_constraint($type_constraint_name)
209         || create_role_type_constraint($type_constraint_name);
210 }
211
212 sub find_or_parse_type_constraint {
213     my $type_constraint_name = normalize_type_constraint_name(shift);
214     my $constraint;
215
216     if ( $constraint = find_type_constraint($type_constraint_name) ) {
217         return $constraint;
218     }
219     elsif ( _detect_type_constraint_union($type_constraint_name) ) {
220         $constraint = create_type_constraint_union($type_constraint_name);
221     }
222     elsif ( _detect_parameterized_type_constraint($type_constraint_name) ) {
223         $constraint
224             = create_parameterized_type_constraint($type_constraint_name);
225     }
226     else {
227         return;
228     }
229
230     $REGISTRY->add_type_constraint($constraint);
231     return $constraint;
232 }
233
234 sub normalize_type_constraint_name {
235     my $type_constraint_name = shift;
236     $type_constraint_name =~ s/\s//g;
237     return $type_constraint_name;
238 }
239
240 sub _confess {
241     my $error = shift;
242
243     local $Carp::CarpLevel = $Carp::CarpLevel + 1;
244     Carp::confess($error);
245 }
246
247 ## --------------------------------------------------------
248 ## exported functions ...
249 ## --------------------------------------------------------
250
251 sub find_type_constraint {
252     my $type = shift;
253
254     if ( blessed $type and $type->isa("Moose::Meta::TypeConstraint") ) {
255         return $type;
256     }
257     else {
258         return unless $REGISTRY->has_type_constraint($type);
259         return $REGISTRY->get_type_constraint($type);
260     }
261 }
262
263 sub register_type_constraint {
264     my $constraint = shift;
265     __PACKAGE__->_throw_error("can't register an unnamed type constraint")
266         unless defined $constraint->name;
267     $REGISTRY->add_type_constraint($constraint);
268     return $constraint;
269 }
270
271 # type constructors
272
273 sub type {
274
275     # back-compat version, called without sugar
276     if ( !any { ( reftype($_) || '' ) eq 'HASH' } @_ ) {
277         Moose::Deprecated::deprecated(
278             feature => 'type without sugar',
279             message =>
280                 'Calling type() with a simple list of parameters is deprecated'
281         );
282
283         return _create_type_constraint( $_[0], undef, $_[1] );
284     }
285
286     my $name = shift;
287
288     my %p = map { %{$_} } @_;
289
290     return _create_type_constraint(
291         $name, undef, $p{where}, $p{message},
292         $p{optimize_as}
293     );
294 }
295
296 sub subtype {
297
298     # crazy back-compat code for being called without sugar ...
299     #
300     # subtype 'Parent', sub { where };
301     if ( scalar @_ == 2 && ( reftype( $_[1] ) || '' ) eq 'CODE' ) {
302         Moose::Deprecated::deprecated(
303             feature => 'subtype without sugar',
304             message =>
305                 'Calling subtype() with a simple list of parameters is deprecated'
306         );
307
308         return _create_type_constraint( undef, @_ );
309     }
310
311     # subtype 'Parent', sub { where }, sub { message };
312     # subtype 'Parent', sub { where }, sub { message }, sub { optimized };
313     if ( scalar @_ >= 3 && all { ( reftype($_) || '' ) eq 'CODE' }
314         @_[ 1 .. $#_ ] ) {
315         Moose::Deprecated::deprecated(
316             feature => 'subtype without sugar',
317             message =>
318                 'Calling subtype() with a simple list of parameters is deprecated'
319         );
320
321         return _create_type_constraint( undef, @_ );
322     }
323
324     # subtype 'Name', 'Parent', ...
325     if ( scalar @_ >= 2 && all { !ref } @_[ 0, 1 ] ) {
326         Moose::Deprecated::deprecated(
327             feature => 'subtype without sugar',
328             message =>
329                 'Calling subtype() with a simple list of parameters is deprecated'
330         );
331
332         return _create_type_constraint(@_);
333     }
334
335     if ( @_ == 1 && !ref $_[0] ) {
336         __PACKAGE__->_throw_error(
337             'A subtype cannot consist solely of a name, it must have a parent'
338         );
339     }
340
341     # The blessed check is mostly to accommodate MooseX::Types, which
342     # uses an object which overloads stringification as a type name.
343     my $name = ref $_[0] && !blessed $_[0] ? undef : shift;
344
345     my %p = map { %{$_} } @_;
346
347     # subtype Str => where { ... };
348     if ( !exists $p{as} ) {
349         $p{as} = $name;
350         $name = undef;
351     }
352
353     return _create_type_constraint(
354         $name, $p{as}, $p{where}, $p{message},
355         $p{optimize_as}
356     );
357 }
358
359 sub class_type {
360     register_type_constraint(
361         create_class_type_constraint(
362             $_[0],
363             ( defined( $_[1] ) ? $_[1] : () ),
364         )
365     );
366 }
367
368 sub role_type ($;$) {
369     register_type_constraint(
370         create_role_type_constraint(
371             $_[0],
372             ( defined( $_[1] ) ? $_[1] : () ),
373         )
374     );
375 }
376
377 sub maybe_type {
378     my ($type_parameter) = @_;
379
380     register_type_constraint(
381         $REGISTRY->get_type_constraint('Maybe')->parameterize($type_parameter)
382     );
383 }
384
385 sub duck_type {
386     my ( $type_name, @methods ) = @_;
387     if ( ref $type_name eq 'ARRAY' && !@methods ) {
388         @methods   = @$type_name;
389         $type_name = undef;
390     }
391     if ( @methods == 1 && ref $methods[0] eq 'ARRAY' ) {
392         @methods = @{ $methods[0] };
393     }
394
395     register_type_constraint(
396         create_duck_type_constraint(
397             $type_name,
398             \@methods,
399         )
400     );
401 }
402
403 sub coerce {
404     my ( $type_name, @coercion_map ) = @_;
405     _install_type_coercions( $type_name, \@coercion_map );
406 }
407
408 # The trick of returning @_ lets us avoid having to specify a
409 # prototype. Perl will parse this:
410 #
411 # subtype 'Foo'
412 #     => as 'Str'
413 #     => where { ... }
414 #
415 # as this:
416 #
417 # subtype( 'Foo', as( 'Str', where { ... } ) );
418 #
419 # If as() returns all it's extra arguments, this just works, and
420 # preserves backwards compatibility.
421 sub as { { as => shift }, @_ }
422 sub where (&)       { { where       => $_[0] } }
423 sub message (&)     { { message     => $_[0] } }
424 sub optimize_as (&) { { optimize_as => $_[0] } }
425
426 sub from    {@_}
427 sub via (&) { $_[0] }
428
429 sub enum {
430     my ( $type_name, @values ) = @_;
431
432     # NOTE:
433     # if only an array-ref is passed then
434     # you get an anon-enum
435     # - SL
436     if ( ref $type_name eq 'ARRAY' ) {
437         @values == 0
438             || __PACKAGE__->_throw_error("enum called with an array reference and additional arguments. Did you mean to parenthesize the enum call's parameters?");
439
440         @values    = @$type_name;
441         $type_name = undef;
442     }
443     if ( @values == 1 && ref $values[0] eq 'ARRAY' ) {
444         @values = @{ $values[0] };
445     }
446
447     register_type_constraint(
448         create_enum_type_constraint(
449             $type_name,
450             \@values,
451         )
452     );
453 }
454
455 sub create_enum_type_constraint {
456     my ( $type_name, $values ) = @_;
457
458     Moose::Meta::TypeConstraint::Enum->new(
459         name => $type_name || '__ANON__',
460         values => $values,
461     );
462 }
463
464 sub create_duck_type_constraint {
465     my ( $type_name, $methods ) = @_;
466
467     Moose::Meta::TypeConstraint::DuckType->new(
468         name => $type_name || '__ANON__',
469         methods => $methods,
470     );
471 }
472
473 sub match_on_type {
474     my ($to_match, @cases) = @_;
475     my $default;
476     if (@cases % 2 != 0) {
477         $default = pop @cases;
478         (ref $default eq 'CODE')
479             || __PACKAGE__->_throw_error("Default case must be a CODE ref, not $default");
480     }
481     while (@cases) {
482         my ($type, $action) = splice @cases, 0, 2;
483
484         unless (blessed $type && $type->isa('Moose::Meta::TypeConstraint')) {
485             $type = find_or_parse_type_constraint($type)
486                  || __PACKAGE__->_throw_error("Cannot find or parse the type '$type'")
487         }
488
489         (ref $action eq 'CODE')
490             || __PACKAGE__->_throw_error("Match action must be a CODE ref, not $action");
491
492         if ($type->check($to_match)) {
493             local $_ = $to_match;
494             return $action->($to_match);
495         }
496     }
497     (defined $default)
498         || __PACKAGE__->_throw_error("No cases matched for $to_match");
499     {
500         local $_ = $to_match;
501         return $default->($to_match);
502     }
503 }
504
505
506 ## --------------------------------------------------------
507 ## desugaring functions ...
508 ## --------------------------------------------------------
509
510 sub _create_type_constraint ($$$;$$) {
511     my $name      = shift;
512     my $parent    = shift;
513     my $check     = shift;
514     my $message   = shift;
515     my $optimized = shift;
516
517     my $pkg_defined_in = scalar( caller(1) );
518
519     if ( defined $name ) {
520         my $type = $REGISTRY->get_type_constraint($name);
521
522         ( $type->_package_defined_in eq $pkg_defined_in )
523             || _confess(
524                   "The type constraint '$name' has already been created in "
525                 . $type->_package_defined_in
526                 . " and cannot be created again in "
527                 . $pkg_defined_in )
528             if defined $type;
529
530         $name =~ /^[\w:\.]+$/
531             or die qq{$name contains invalid characters for a type name.}
532             . qq{ Names can contain alphanumeric character, ":", and "."\n};
533     }
534
535     my %opts = (
536         name               => $name,
537         package_defined_in => $pkg_defined_in,
538
539         ( $check     ? ( constraint => $check )     : () ),
540         ( $message   ? ( message    => $message )   : () ),
541         ( $optimized ? ( optimized  => $optimized ) : () ),
542     );
543
544     my $constraint;
545     if (
546         defined $parent
547         and $parent
548         = blessed $parent
549         ? $parent
550         : find_or_create_isa_type_constraint($parent)
551         ) {
552         $constraint = $parent->create_child_type(%opts);
553     }
554     else {
555         $constraint = Moose::Meta::TypeConstraint->new(%opts);
556     }
557
558     $REGISTRY->add_type_constraint($constraint)
559         if defined $name;
560
561     return $constraint;
562 }
563
564 sub _install_type_coercions ($$) {
565     my ( $type_name, $coercion_map ) = @_;
566     my $type = find_type_constraint($type_name);
567     ( defined $type )
568         || __PACKAGE__->_throw_error(
569         "Cannot find type '$type_name', perhaps you forgot to load it");
570     if ( $type->has_coercion ) {
571         $type->coercion->add_type_coercions(@$coercion_map);
572     }
573     else {
574         my $type_coercion = Moose::Meta::TypeCoercion->new(
575             type_coercion_map => $coercion_map,
576             type_constraint   => $type
577         );
578         $type->coercion($type_coercion);
579     }
580 }
581
582 ## --------------------------------------------------------
583 ## type notation parsing ...
584 ## --------------------------------------------------------
585
586 {
587
588     # All I have to say is mugwump++ cause I know
589     # do not even have enough regexp-fu to be able
590     # to have written this (I can only barely
591     # understand it as it is)
592     # - SL
593
594     use re "eval";
595
596     my $valid_chars = qr{[\w:\.]};
597     my $type_atom   = qr{ (?>$valid_chars+) }x;
598     my $ws          = qr{ (?>\s*) }x;
599     my $op_union    = qr{ $ws \| $ws }x;
600
601     my ($type, $type_capture_parts, $type_with_parameter, $union, $any);
602     if (Class::MOP::IS_RUNNING_ON_5_10) {
603         my $type_pattern
604             = q{  (?&type_atom)  (?: \[ (?&ws)  (?&any)  (?&ws) \] )? };
605         my $type_capture_parts_pattern
606             = q{ ((?&type_atom)) (?: \[ (?&ws) ((?&any)) (?&ws) \] )? };
607         my $type_with_parameter_pattern
608             = q{  (?&type_atom)      \[ (?&ws)  (?&any)  (?&ws) \]    };
609         my $union_pattern
610             = q{ (?&type) (?> (?: (?&op_union) (?&type) )+ ) };
611         my $any_pattern
612             = q{ (?&type) | (?&union) };
613
614         my $defines = qr{(?(DEFINE)
615             (?<valid_chars>         $valid_chars)
616             (?<type_atom>           $type_atom)
617             (?<ws>                  $ws)
618             (?<op_union>            $op_union)
619             (?<type>                $type_pattern)
620             (?<type_capture_parts>  $type_capture_parts_pattern)
621             (?<type_with_parameter> $type_with_parameter_pattern)
622             (?<union>               $union_pattern)
623             (?<any>                 $any_pattern)
624         )}x;
625
626         $type                = qr{ $type_pattern                $defines }x;
627         $type_capture_parts  = qr{ $type_capture_parts_pattern  $defines }x;
628         $type_with_parameter = qr{ $type_with_parameter_pattern $defines }x;
629         $union               = qr{ $union_pattern               $defines }x;
630         $any                 = qr{ $any_pattern                 $defines }x;
631     }
632     else {
633         $type
634             = qr{  $type_atom  (?: \[ $ws  (??{$any})  $ws \] )? }x;
635         $type_capture_parts
636             = qr{ ($type_atom) (?: \[ $ws ((??{$any})) $ws \] )? }x;
637         $type_with_parameter
638             = qr{  $type_atom      \[ $ws  (??{$any})  $ws \]    }x;
639         $union
640             = qr{ $type (?> (?: $op_union $type )+ ) }x;
641         $any
642             = qr{ $type | $union }x;
643     }
644
645
646     sub _parse_parameterized_type_constraint {
647         { no warnings 'void'; $any; }  # force capture of interpolated lexical
648         $_[0] =~ m{ $type_capture_parts }x;
649         return ( $1, $2 );
650     }
651
652     sub _detect_parameterized_type_constraint {
653         { no warnings 'void'; $any; }  # force capture of interpolated lexical
654         $_[0] =~ m{ ^ $type_with_parameter $ }x;
655     }
656
657     sub _parse_type_constraint_union {
658         { no warnings 'void'; $any; }  # force capture of interpolated lexical
659         my $given = shift;
660         my @rv;
661         while ( $given =~ m{ \G (?: $op_union )? ($type) }gcx ) {
662             push @rv => $1;
663         }
664         ( pos($given) eq length($given) )
665             || __PACKAGE__->_throw_error( "'$given' didn't parse (parse-pos="
666                 . pos($given)
667                 . " and str-length="
668                 . length($given)
669                 . ")" );
670         @rv;
671     }
672
673     sub _detect_type_constraint_union {
674         { no warnings 'void'; $any; }  # force capture of interpolated lexical
675         $_[0] =~ m{^ $type $op_union $type ( $op_union .* )? $}x;
676     }
677 }
678
679 ## --------------------------------------------------------
680 # define some basic built-in types
681 ## --------------------------------------------------------
682
683 # By making these classes immutable before creating all the types we
684 # below, we avoid repeatedly calling the slow MOP-based accessors.
685 $_->make_immutable(
686     inline_constructor => 1,
687     constructor_name   => "_new",
688
689     # these are Class::MOP accessors, so they need inlining
690     inline_accessors => 1
691     ) for grep { $_->is_mutable }
692     map { Class::MOP::class_of($_) }
693     qw(
694     Moose::Meta::TypeConstraint
695     Moose::Meta::TypeConstraint::Union
696     Moose::Meta::TypeConstraint::Parameterized
697     Moose::Meta::TypeConstraint::Parameterizable
698     Moose::Meta::TypeConstraint::Class
699     Moose::Meta::TypeConstraint::Role
700     Moose::Meta::TypeConstraint::Enum
701     Moose::Meta::TypeConstraint::DuckType
702     Moose::Meta::TypeConstraint::Registry
703 );
704
705 type 'Any'  => where {1};    # meta-type including all
706 subtype 'Item' => as 'Any';  # base-type
707
708 subtype 'Undef'   => as 'Item' => where { !defined($_) };
709 subtype 'Defined' => as 'Item' => where { defined($_) };
710
711 subtype 'Bool' => as 'Item' =>
712     where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' };
713
714 subtype 'Value' => as 'Defined' => where { !ref($_) } =>
715     optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Value;
716
717 subtype 'Ref' => as 'Defined' => where { ref($_) } =>
718     optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Ref;
719
720 subtype 'Str' => as 'Value' => where { ref(\$_) eq 'SCALAR' } =>
721     optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Str;
722
723 subtype 'Num' => as 'Str' =>
724     where { Scalar::Util::looks_like_number($_) } =>
725     optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Num;
726
727 subtype 'Int' => as 'Num' => where { "$_" =~ /^-?[0-9]+$/ } =>
728     optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Int;
729
730 subtype 'CodeRef' => as 'Ref' => where { ref($_) eq 'CODE' } =>
731     optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::CodeRef;
732 subtype 'RegexpRef' => as 'Ref' => where { ref($_) eq 'Regexp' } =>
733     optimize_as
734     \&Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef;
735 subtype 'GlobRef' => as 'Ref' => where { ref($_) eq 'GLOB' } =>
736     optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::GlobRef;
737
738 # NOTE:
739 # scalar filehandles are GLOB refs,
740 # but a GLOB ref is not always a filehandle
741 subtype 'FileHandle' => as 'GlobRef' => where {
742     Scalar::Util::openhandle($_) || ( blessed($_) && $_->isa("IO::Handle") );
743 } => optimize_as
744     \&Moose::Util::TypeConstraints::OptimizedConstraints::FileHandle;
745
746 # NOTE:
747 # blessed(qr/.../) returns true,.. how odd
748 subtype 'Object' => as 'Ref' =>
749     where { blessed($_) && blessed($_) ne 'Regexp' } =>
750     optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Object;
751
752 # This type is deprecated.
753 subtype 'Role' => as 'Object' => where { $_->can('does') } =>
754     optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Role;
755
756 my $_class_name_checker = sub { };
757
758 subtype 'ClassName' => as 'Str' =>
759     where { Class::MOP::is_class_loaded($_) } => optimize_as
760     \&Moose::Util::TypeConstraints::OptimizedConstraints::ClassName;
761
762 subtype 'RoleName' => as 'ClassName' => where {
763     (Class::MOP::class_of($_) || return)->isa('Moose::Meta::Role');
764 } => optimize_as
765     \&Moose::Util::TypeConstraints::OptimizedConstraints::RoleName;
766
767 ## --------------------------------------------------------
768 # parameterizable types ...
769
770 $REGISTRY->add_type_constraint(
771     Moose::Meta::TypeConstraint::Parameterizable->new(
772         name               => 'ScalarRef',
773         package_defined_in => __PACKAGE__,
774         parent             => find_type_constraint('Ref'),
775         constraint         => sub { ref($_) eq 'SCALAR' || ref($_) eq 'REF' },
776         optimized =>
777             \&Moose::Util::TypeConstraints::OptimizedConstraints::ScalarRef,
778         constraint_generator => sub {
779             my $type_parameter = shift;
780             my $check          = $type_parameter->_compiled_type_constraint;
781             return sub {
782                 return $check->(${ $_ });
783             };
784         }
785     )
786 );
787
788 $REGISTRY->add_type_constraint(
789     Moose::Meta::TypeConstraint::Parameterizable->new(
790         name               => 'ArrayRef',
791         package_defined_in => __PACKAGE__,
792         parent             => find_type_constraint('Ref'),
793         constraint         => sub { ref($_) eq 'ARRAY' },
794         optimized =>
795             \&Moose::Util::TypeConstraints::OptimizedConstraints::ArrayRef,
796         constraint_generator => sub {
797             my $type_parameter = shift;
798             my $check          = $type_parameter->_compiled_type_constraint;
799             return sub {
800                 foreach my $x (@$_) {
801                     ( $check->($x) ) || return;
802                 }
803                 1;
804                 }
805         }
806     )
807 );
808
809 $REGISTRY->add_type_constraint(
810     Moose::Meta::TypeConstraint::Parameterizable->new(
811         name               => 'HashRef',
812         package_defined_in => __PACKAGE__,
813         parent             => find_type_constraint('Ref'),
814         constraint         => sub { ref($_) eq 'HASH' },
815         optimized =>
816             \&Moose::Util::TypeConstraints::OptimizedConstraints::HashRef,
817         constraint_generator => sub {
818             my $type_parameter = shift;
819             my $check          = $type_parameter->_compiled_type_constraint;
820             return sub {
821                 foreach my $x ( values %$_ ) {
822                     ( $check->($x) ) || return;
823                 }
824                 1;
825                 }
826         }
827     )
828 );
829
830 $REGISTRY->add_type_constraint(
831     Moose::Meta::TypeConstraint::Parameterizable->new(
832         name                 => 'Maybe',
833         package_defined_in   => __PACKAGE__,
834         parent               => find_type_constraint('Item'),
835         constraint           => sub {1},
836         constraint_generator => sub {
837             my $type_parameter = shift;
838             my $check          = $type_parameter->_compiled_type_constraint;
839             return sub {
840                 return 1 if not( defined($_) ) || $check->($_);
841                 return;
842                 }
843         }
844     )
845 );
846
847 my @PARAMETERIZABLE_TYPES
848     = map { $REGISTRY->get_type_constraint($_) } qw[ScalarRef ArrayRef HashRef Maybe];
849
850 sub get_all_parameterizable_types {@PARAMETERIZABLE_TYPES}
851
852 sub add_parameterizable_type {
853     my $type = shift;
854     ( blessed $type
855             && $type->isa('Moose::Meta::TypeConstraint::Parameterizable') )
856         || __PACKAGE__->_throw_error(
857         "Type must be a Moose::Meta::TypeConstraint::Parameterizable not $type"
858         );
859     push @PARAMETERIZABLE_TYPES => $type;
860 }
861
862 ## --------------------------------------------------------
863 # end of built-in types ...
864 ## --------------------------------------------------------
865
866 {
867     my @BUILTINS = list_all_type_constraints();
868     sub list_all_builtin_type_constraints {@BUILTINS}
869 }
870
871 sub _throw_error {
872     shift;
873     require Moose;
874     unshift @_, 'Moose';
875     goto &Moose::throw_error;
876 }
877
878 1;
879
880 # ABSTRACT: Type constraint system for Moose
881
882 __END__
883
884 =pod
885
886 =head1 SYNOPSIS
887
888   use Moose::Util::TypeConstraints;
889
890   subtype 'Natural'
891       => as 'Int'
892       => where { $_ > 0 };
893
894   subtype 'NaturalLessThanTen'
895       => as 'Natural'
896       => where { $_ < 10 }
897       => message { "This number ($_) is not less than ten!" };
898
899   coerce 'Num'
900       => from 'Str'
901         => via { 0+$_ };
902
903   enum 'RGBColors' => qw(red green blue);
904
905   no Moose::Util::TypeConstraints;
906
907 =head1 DESCRIPTION
908
909 This module provides Moose with the ability to create custom type
910 constraints to be used in attribute definition.
911
912 =head2 Important Caveat
913
914 This is B<NOT> a type system for Perl 5. These are type constraints,
915 and they are not used by Moose unless you tell it to. No type
916 inference is performed, expressions are not typed, etc. etc. etc.
917
918 A type constraint is at heart a small "check if a value is valid"
919 function. A constraint can be associated with an attribute. This
920 simplifies parameter validation, and makes your code clearer to read,
921 because you can refer to constraints by name.
922
923 =head2 Slightly Less Important Caveat
924
925 It is B<always> a good idea to quote your type names.
926
927 This prevents Perl from trying to execute the call as an indirect
928 object call. This can be an issue when you have a subtype with the
929 same name as a valid class.
930
931 For instance:
932
933   subtype DateTime => as Object => where { $_->isa('DateTime') };
934
935 will I<just work>, while this:
936
937   use DateTime;
938   subtype DateTime => as Object => where { $_->isa('DateTime') };
939
940 will fail silently and cause many headaches. The simple way to solve
941 this, as well as future proof your subtypes from classes which have
942 yet to have been created, is to quote the type name:
943
944   use DateTime;
945   subtype 'DateTime' => as 'Object' => where { $_->isa('DateTime') };
946
947 =head2 Default Type Constraints
948
949 This module also provides a simple hierarchy for Perl 5 types, here is
950 that hierarchy represented visually.
951
952   Any
953   Item
954       Bool
955       Maybe[`a]
956       Undef
957       Defined
958           Value
959               Str
960                   Num
961                       Int
962                   ClassName
963                   RoleName
964           Ref
965               ScalarRef[`a]
966               ArrayRef[`a]
967               HashRef[`a]
968               CodeRef
969               RegexpRef
970               GlobRef
971                   FileHandle
972               Object
973
974 B<NOTE:> Any type followed by a type parameter C<[`a]> can be
975 parameterized, this means you can say:
976
977   ArrayRef[Int]    # an array of integers
978   HashRef[CodeRef] # a hash of str to CODE ref mappings
979   ScalarRef[Int]   # a reference to an integer
980   Maybe[Str]       # value may be a string, may be undefined
981
982 If Moose finds a name in brackets that it does not recognize as an
983 existing type, it assumes that this is a class name, for example
984 C<ArrayRef[DateTime]>.
985
986 B<NOTE:> Unless you parameterize a type, then it is invalid to include
987 the square brackets. I.e. C<ArrayRef[]> will be treated as a new type
988 name, I<not> as a parameterization of C<ArrayRef>.
989
990 B<NOTE:> The C<Undef> type constraint for the most part works
991 correctly now, but edge cases may still exist, please use it
992 sparingly.
993
994 B<NOTE:> The C<ClassName> type constraint does a complex package
995 existence check. This means that your class B<must> be loaded for this
996 type constraint to pass.
997
998 B<NOTE:> The C<RoleName> constraint checks a string is a I<package
999 name> which is a role, like C<'MyApp::Role::Comparable'>.
1000
1001 =head2 Type Constraint Naming
1002
1003 Type name declared via this module can only contain alphanumeric
1004 characters, colons (:), and periods (.).
1005
1006 Since the types created by this module are global, it is suggested
1007 that you namespace your types just as you would namespace your
1008 modules. So instead of creating a I<Color> type for your
1009 B<My::Graphics> module, you would call the type
1010 I<My::Graphics::Types::Color> instead.
1011
1012 =head2 Use with Other Constraint Modules
1013
1014 This module can play nicely with other constraint modules with some
1015 slight tweaking. The C<where> clause in types is expected to be a
1016 C<CODE> reference which checks it's first argument and returns a
1017 boolean. Since most constraint modules work in a similar way, it
1018 should be simple to adapt them to work with Moose.
1019
1020 For instance, this is how you could use it with
1021 L<Declare::Constraints::Simple> to declare a completely new type.
1022
1023   type 'HashOfArrayOfObjects',
1024       {
1025       where => IsHashRef(
1026           -keys   => HasLength,
1027           -values => IsArrayRef(IsObject)
1028       )
1029   };
1030
1031 For more examples see the F<t/200_examples/004_example_w_DCS.t> test
1032 file.
1033
1034 Here is an example of using L<Test::Deep> and it's non-test
1035 related C<eq_deeply> function.
1036
1037   type 'ArrayOfHashOfBarsAndRandomNumbers'
1038       => where {
1039           eq_deeply($_,
1040               array_each(subhashof({
1041                   bar           => isa('Bar'),
1042                   random_number => ignore()
1043               })))
1044         };
1045
1046 For a complete example see the
1047 F<t/200_examples/005_example_w_TestDeep.t> test file.
1048
1049 =head1 FUNCTIONS
1050
1051 =head2 Type Constraint Constructors
1052
1053 The following functions are used to create type constraints.  They
1054 will also register the type constraints your create in a global
1055 registry that is used to look types up by name.
1056
1057 See the L</SYNOPSIS> for an example of how to use these.
1058
1059 =over 4
1060
1061 =item B<< subtype 'Name' => as 'Parent' => where { } ... >>
1062
1063 This creates a named subtype.
1064
1065 If you provide a parent that Moose does not recognize, it will
1066 automatically create a new class type constraint for this name.
1067
1068 When creating a named type, the C<subtype> function should either be
1069 called with the sugar helpers (C<where>, C<message>, etc), or with a
1070 name and a hashref of parameters:
1071
1072  subtype( 'Foo', { where => ..., message => ... } );
1073
1074 The valid hashref keys are C<as> (the parent), C<where>, C<message>,
1075 and C<optimize_as>.
1076
1077 =item B<< subtype as 'Parent' => where { } ... >>
1078
1079 This creates an unnamed subtype and will return the type
1080 constraint meta-object, which will be an instance of
1081 L<Moose::Meta::TypeConstraint>.
1082
1083 When creating an anonymous type, the C<subtype> function should either
1084 be called with the sugar helpers (C<where>, C<message>, etc), or with
1085 just a hashref of parameters:
1086
1087  subtype( { where => ..., message => ... } );
1088
1089 =item B<class_type ($class, ?$options)>
1090
1091 Creates a new subtype of C<Object> with the name C<$class> and the
1092 metaclass L<Moose::Meta::TypeConstraint::Class>.
1093
1094 =item B<role_type ($role, ?$options)>
1095
1096 Creates a C<Role> type constraint with the name C<$role> and the
1097 metaclass L<Moose::Meta::TypeConstraint::Role>.
1098
1099 =item B<maybe_type ($type)>
1100
1101 Creates a type constraint for either C<undef> or something of the
1102 given type.
1103
1104 =item B<duck_type ($name, \@methods)>
1105
1106 This will create a subtype of Object and test to make sure the value
1107 C<can()> do the methods in C<\@methods>.
1108
1109 This is intended as an easy way to accept non-Moose objects that
1110 provide a certain interface. If you're using Moose classes, we
1111 recommend that you use a C<requires>-only Role instead.
1112
1113 =item B<duck_type (\@methods)>
1114
1115 If passed an ARRAY reference as the only parameter instead of the
1116 C<$name>, C<\@methods> pair, this will create an unnamed duck type.
1117 This can be used in an attribute definition like so:
1118
1119   has 'cache' => (
1120       is  => 'ro',
1121       isa => duck_type( [qw( get_set )] ),
1122   );
1123
1124 =item B<enum ($name, \@values)>
1125
1126 This will create a basic subtype for a given set of strings.
1127 The resulting constraint will be a subtype of C<Str> and
1128 will match any of the items in C<\@values>. It is case sensitive.
1129 See the L</SYNOPSIS> for a simple example.
1130
1131 B<NOTE:> This is not a true proper enum type, it is simply
1132 a convenient constraint builder.
1133
1134 =item B<enum (\@values)>
1135
1136 If passed an ARRAY reference as the only parameter instead of the
1137 C<$name>, C<\@values> pair, this will create an unnamed enum. This
1138 can then be used in an attribute definition like so:
1139
1140   has 'sort_order' => (
1141       is  => 'ro',
1142       isa => enum([qw[ ascending descending ]]),
1143   );
1144
1145 =item B<as 'Parent'>
1146
1147 This is just sugar for the type constraint construction syntax.
1148
1149 It takes a single argument, which is the name of a parent type.
1150
1151 =item B<where { ... }>
1152
1153 This is just sugar for the type constraint construction syntax.
1154
1155 It takes a subroutine reference as an argument. When the type
1156 constraint is tested, the reference is run with the value to be tested
1157 in C<$_>. This reference should return true or false to indicate
1158 whether or not the constraint check passed.
1159
1160 =item B<message { ... }>
1161
1162 This is just sugar for the type constraint construction syntax.
1163
1164 It takes a subroutine reference as an argument. When the type
1165 constraint fails, then the code block is run with the value provided
1166 in C<$_>. This reference should return a string, which will be used in
1167 the text of the exception thrown.
1168
1169 =item B<optimize_as { ... }>
1170
1171 This can be used to define a "hand optimized" version of your
1172 type constraint which can be used to avoid traversing a subtype
1173 constraint hierarchy.
1174
1175 B<NOTE:> You should only use this if you know what you are doing,
1176 all the built in types use this, so your subtypes (assuming they
1177 are shallow) will not likely need to use this.
1178
1179 =item B<< type 'Name' => where { } ... >>
1180
1181 This creates a base type, which has no parent.
1182
1183 The C<type> function should either be called with the sugar helpers
1184 (C<where>, C<message>, etc), or with a name and a hashref of
1185 parameters:
1186
1187   type( 'Foo', { where => ..., message => ... } );
1188
1189 The valid hashref keys are C<where>, C<message>, and C<optimize_as>.
1190
1191 =back
1192
1193 =head2 Type Constraint Utilities
1194
1195 =over 4
1196
1197 =item B<< match_on_type $value => ( $type => \&action, ... ?\&default ) >>
1198
1199 This is a utility function for doing simple type based dispatching similar to
1200 match/case in OCaml and case/of in Haskell. It is not as featureful as those
1201 languages, nor does not it support any kind of automatic destructuring
1202 bind. Here is a simple Perl pretty printer dispatching over the core Moose
1203 types.
1204
1205   sub ppprint {
1206       my $x = shift;
1207       match_on_type $x => (
1208           HashRef => sub {
1209               my $hash = shift;
1210               '{ '
1211                   . (
1212                   join ", " => map { $_ . ' => ' . ppprint( $hash->{$_} ) }
1213                       sort keys %$hash
1214                   ) . ' }';
1215           },
1216           ArrayRef => sub {
1217               my $array = shift;
1218               '[ ' . ( join ", " => map { ppprint($_) } @$array ) . ' ]';
1219           },
1220           CodeRef   => sub {'sub { ... }'},
1221           RegexpRef => sub { 'qr/' . $_ . '/' },
1222           GlobRef   => sub { '*' . B::svref_2object($_)->NAME },
1223           Object    => sub { $_->can('to_string') ? $_->to_string : $_ },
1224           ScalarRef => sub { '\\' . ppprint( ${$_} ) },
1225           Num       => sub {$_},
1226           Str       => sub { '"' . $_ . '"' },
1227           Undef     => sub {'undef'},
1228           => sub { die "I don't know what $_ is" }
1229       );
1230   }
1231
1232 Or a simple JSON serializer:
1233
1234   sub to_json {
1235       my $x = shift;
1236       match_on_type $x => (
1237           HashRef => sub {
1238               my $hash = shift;
1239               '{ '
1240                   . (
1241                   join ", " =>
1242                       map { '"' . $_ . '" : ' . to_json( $hash->{$_} ) }
1243                       sort keys %$hash
1244                   ) . ' }';
1245           },
1246           ArrayRef => sub {
1247               my $array = shift;
1248               '[ ' . ( join ", " => map { to_json($_) } @$array ) . ' ]';
1249           },
1250           Num   => sub {$_},
1251           Str   => sub { '"' . $_ . '"' },
1252           Undef => sub {'null'},
1253           => sub { die "$_ is not acceptable json type" }
1254       );
1255   }
1256
1257 The matcher is done by mapping a C<$type> to an C<\&action>. The C<$type> can
1258 be either a string type or a L<Moose::Meta::TypeConstraint> object, and
1259 C<\&action> is a subroutine reference. This function will dispatch on the
1260 first match for C<$value>. It is possible to have a catch-all by providing an
1261 additional subroutine reference as the final argument to C<match_on_type>.
1262
1263 =back
1264
1265 =head2 Type Coercion Constructors
1266
1267 You can define coercions for type constraints, which allow you to
1268 automatically transform values to something valid for the type
1269 constraint. If you ask your accessor to coerce, then Moose will run
1270 the type-coercion code first, followed by the type constraint
1271 check. This feature should be used carefully as it is very powerful
1272 and could easily take off a limb if you are not careful.
1273
1274 See the L</SYNOPSIS> for an example of how to use these.
1275
1276 =over 4
1277
1278 =item B<< coerce 'Name' => from 'OtherName' => via { ... }  >>
1279
1280 This defines a coercion from one type to another. The C<Name> argument
1281 is the type you are coercing I<to>.
1282
1283 To define multiple coercions, supply more sets of from/via pairs:
1284
1285   coerce 'Name' =>
1286     from 'OtherName' => via { ... },
1287     from 'ThirdName' => via { ... };
1288
1289 =item B<from 'OtherName'>
1290
1291 This is just sugar for the type coercion construction syntax.
1292
1293 It takes a single type name (or type object), which is the type being
1294 coerced I<from>.
1295
1296 =item B<via { ... }>
1297
1298 This is just sugar for the type coercion construction syntax.
1299
1300 It takes a subroutine reference. This reference will be called with
1301 the value to be coerced in C<$_>. It is expected to return a new value
1302 of the proper type for the coercion.
1303
1304 =back
1305
1306 =head2 Creating and Finding Type Constraints
1307
1308 These are additional functions for creating and finding type
1309 constraints. Most of these functions are not available for
1310 importing. The ones that are importable as specified.
1311
1312 =over 4
1313
1314 =item B<find_type_constraint($type_name)>
1315
1316 This function can be used to locate the L<Moose::Meta::TypeConstraint>
1317 object for a named type.
1318
1319 This function is importable.
1320
1321 =item B<register_type_constraint($type_object)>
1322
1323 This function will register a L<Moose::Meta::TypeConstraint> with the
1324 global type registry.
1325
1326 This function is importable.
1327
1328 =item B<normalize_type_constraint_name($type_constraint_name)>
1329
1330 This method takes a type constraint name and returns the normalized
1331 form. This removes any whitespace in the string.
1332
1333 =item B<create_type_constraint_union($pipe_separated_types | @type_constraint_names)>
1334
1335 This can take a union type specification like C<'Int|ArrayRef[Int]'>,
1336 or a list of names. It returns a new
1337 L<Moose::Meta::TypeConstraint::Union> object.
1338
1339 =item B<create_parameterized_type_constraint($type_name)>
1340
1341 Given a C<$type_name> in the form of C<'BaseType[ContainerType]'>,
1342 this will create a new L<Moose::Meta::TypeConstraint::Parameterized>
1343 object. The C<BaseType> must exist already exist as a parameterizable
1344 type.
1345
1346 =item B<create_class_type_constraint($class, $options)>
1347
1348 Given a class name this function will create a new
1349 L<Moose::Meta::TypeConstraint::Class> object for that class name.
1350
1351 The C<$options> is a hash reference that will be passed to the
1352 L<Moose::Meta::TypeConstraint::Class> constructor (as a hash).
1353
1354 =item B<create_role_type_constraint($role, $options)>
1355
1356 Given a role name this function will create a new
1357 L<Moose::Meta::TypeConstraint::Role> object for that role name.
1358
1359 The C<$options> is a hash reference that will be passed to the
1360 L<Moose::Meta::TypeConstraint::Role> constructor (as a hash).
1361
1362 =item B<create_enum_type_constraint($name, $values)>
1363
1364 Given a enum name this function will create a new
1365 L<Moose::Meta::TypeConstraint::Enum> object for that enum name.
1366
1367 =item B<create_duck_type_constraint($name, $methods)>
1368
1369 Given a duck type name this function will create a new
1370 L<Moose::Meta::TypeConstraint::DuckType> object for that enum name.
1371
1372 =item B<find_or_parse_type_constraint($type_name)>
1373
1374 Given a type name, this first attempts to find a matching constraint
1375 in the global registry.
1376
1377 If the type name is a union or parameterized type, it will create a
1378 new object of the appropriate, but if given a "regular" type that does
1379 not yet exist, it simply returns false.
1380
1381 When given a union or parameterized type, the member or base type must
1382 already exist.
1383
1384 If it creates a new union or parameterized type, it will add it to the
1385 global registry.
1386
1387 =item B<find_or_create_isa_type_constraint($type_name)>
1388
1389 =item B<find_or_create_does_type_constraint($type_name)>
1390
1391 These functions will first call C<find_or_parse_type_constraint>. If
1392 that function does not return a type, a new anonymous type object will
1393 be created.
1394
1395 The C<isa> variant will use C<create_class_type_constraint> and the
1396 C<does> variant will use C<create_role_type_constraint>.
1397
1398 =item B<get_type_constraint_registry>
1399
1400 Returns the L<Moose::Meta::TypeConstraint::Registry> object which
1401 keeps track of all type constraints.
1402
1403 =item B<list_all_type_constraints>
1404
1405 This will return a list of type constraint names in the global
1406 registry. You can then fetch the actual type object using
1407 C<find_type_constraint($type_name)>.
1408
1409 =item B<list_all_builtin_type_constraints>
1410
1411 This will return a list of builtin type constraints, meaning those
1412 which are defined in this module. See the L<Default Type Constraints>
1413 section for a complete list.
1414
1415 =item B<export_type_constraints_as_functions>
1416
1417 This will export all the current type constraints as functions into
1418 the caller's namespace (C<Int()>, C<Str()>, etc). Right now, this is
1419 mostly used for testing, but it might prove useful to others.
1420
1421 =item B<get_all_parameterizable_types>
1422
1423 This returns all the parameterizable types that have been registered,
1424 as a list of type objects.
1425
1426 =item B<add_parameterizable_type($type)>
1427
1428 Adds C<$type> to the list of parameterizable types
1429
1430 =back
1431
1432 =head1 BUGS
1433
1434 See L<Moose/BUGS> for details on reporting bugs.
1435
1436 =cut