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