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