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