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