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