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