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