more tests for the mixed string and perl type constraints in union type constraints...
[gitmo/MooseX-Types.git] / lib / MooseX / Types / TypeDecorator.pm
CommitLineData
4c2125a4 1package MooseX::Types::TypeDecorator;
2
a706b0f2 3use strict;
4use warnings;
4c2125a4 5
c1260541 6
bb5b7b28 7use Carp::Clan qw( ^MooseX::Types );
475bbd1d 8use Moose::Util::TypeConstraints ();
bb5b7b28 9use Moose::Meta::TypeConstraint::Union;
371efa05 10use Scalar::Util qw(blessed);
bb5b7b28 11
4c2125a4 12use overload(
13 '""' => sub {
c1260541 14 my $self = shift @_;
15 if(blessed $self) {
16 return $self->__type_constraint->name;
17 } else {
18 return "$self";
19 }
4c2125a4 20 },
cf1a8bfa 21 '|' => sub {
686e5888 22
23 ## It's kind of ugly that we need to know about Union Types, but this
24 ## is needed for syntax compatibility. Maybe someday we'll all just do
25 ## Or[Str,Str,Int]
442e42ba 26
0d07f026 27 my @args = @_[0,1]; ## arg 3 is special, see the overload docs.
28 my @tc = grep {blessed $_} map {
29 blessed $_ ? $_ :
30 Moose::Util::TypeConstraints::find_or_parse_type_constraint($_)
31 || croak "$_ is not a type constraint"
32 } @args;
33
34 ( scalar @tc == scalar @args)
35 || croak "one of your type constraints is bad. Passed: ". join(', ', @args) ." Got: ". join(', ', @tc);
36
37 ( scalar @tc >= 2 )
38 || croak "You must pass in at least 2 type names to make a union";
442e42ba 39
bb5b7b28 40 my $union = Moose::Meta::TypeConstraint::Union->new(type_constraints=>\@tc);
41 return Moose::Util::TypeConstraints::register_type_constraint($union);
cf1a8bfa 42 },
1d9a68a6 43 fallback => 1,
44
4c2125a4 45);
46
47=head1 NAME
48
49MooseX::Types::TypeDecorator - More flexible access to a Type Constraint
50
51=head1 DESCRIPTION
52
53This is a decorator object that contains an underlying type constraint. We use
54this to control access to the type constraint and to add some features.
55
a706b0f2 56=head1 METHODS
4c2125a4 57
a706b0f2 58This class defines the following methods.
4c2125a4 59
a706b0f2 60=head2 new
4c2125a4 61
a706b0f2 62Old school instantiation
4c2125a4 63
64=cut
65
a706b0f2 66sub new {
475bbd1d 67 my $class = shift @_;
68 if(my $arg = shift @_) {
371efa05 69 if(blessed $arg && $arg->isa('Moose::Meta::TypeConstraint')) {
475bbd1d 70 return bless {'__type_constraint'=>$arg}, $class;
e7d06577 71 } elsif(
72 blessed $arg &&
73 $arg->isa('MooseX::Types::UndefinedType')
74 ) {
475bbd1d 75 ## stub in case we'll need to handle these types differently
76 return bless {'__type_constraint'=>$arg}, $class;
371efa05 77 } elsif(blessed $arg) {
78 croak "Argument must be ->isa('Moose::Meta::TypeConstraint') or ->isa('MooseX::Types::UndefinedType'), not ". blessed $arg;
475bbd1d 79 } else {
d8f30dd4 80 croak "Argument cannot be '$arg'";
475bbd1d 81 }
bb5b7b28 82 } else {
e7d06577 83 croak "This method [new] requires a single argument.";
bb5b7b28 84 }
a706b0f2 85}
4c2125a4 86
5a9b6d38 87=head2 __type_constraint ($type_constraint)
4c2125a4 88
e088dd03 89Set/Get the type_constraint.
4c2125a4 90
91=cut
92
475bbd1d 93sub __type_constraint {
c1260541 94 my $self = shift @_;
371efa05 95 if(blessed $self) {
96 if(defined(my $tc = shift @_)) {
97 $self->{__type_constraint} = $tc;
98 }
99 return $self->{__type_constraint};
100 } else {
101 croak 'cannot call __type_constraint as a class method';
a706b0f2 102 }
a706b0f2 103}
4c2125a4 104
bb5b7b28 105=head2 isa
106
107handle $self->isa since AUTOLOAD can't.
108
109=cut
110
111sub isa {
371efa05 112 my ($self, $target) = @_;
bb5b7b28 113 if(defined $target) {
c1260541 114 if(blessed $self) {
115 return $self->__type_constraint->isa($target);
116 } else {
117 return;
118 }
bb5b7b28 119 } else {
120 return;
121 }
122}
123
124=head2 can
125
126handle $self->can since AUTOLOAD can't.
127
128=cut
129
130sub can {
131 my ($self, $target) = @_;
132 if(defined $target) {
c1260541 133 if(blessed $self) {
134 return $self->__type_constraint->can($target);
135 } else {
136 return;
137 }
bb5b7b28 138 } else {
139 return;
140 }
141}
142
c1260541 143=head2 meta
144
145have meta examine the underlying type constraints
146
147=cut
148
149sub meta {
150 my $self = shift @_;
151 if(blessed $self) {
152 return $self->__type_constraint->meta;
153 }
154}
155
156
a706b0f2 157=head2 DESTROY
4c2125a4 158
a706b0f2 159We might need it later
4c2125a4 160
a706b0f2 161=cut
4c2125a4 162
a706b0f2 163sub DESTROY {
164 return;
165}
4c2125a4 166
a706b0f2 167=head2 AUTOLOAD
4c2125a4 168
a706b0f2 169Delegate to the decorator targe
4c2125a4 170
a706b0f2 171=cut
4c2125a4 172
e088dd03 173sub AUTOLOAD {
077ac262 174
475bbd1d 175 my ($self, @args) = @_;
a706b0f2 176 my ($method) = (our $AUTOLOAD =~ /([^:]+)$/);
077ac262 177
178 ## We delegate with this method in an attempt to support a value of
179 ## __type_constraint which is also AUTOLOADing, in particular the class
180 ## MooseX::Types::UndefinedType which AUTOLOADs during autovivication.
181
182 my $return;
183
184 eval {
185 $return = $self->__type_constraint->$method(@args);
186 }; if($@) {
187 croak $@;
475bbd1d 188 } else {
077ac262 189 return $return;
475bbd1d 190 }
a706b0f2 191}
4c2125a4 192
193=head1 AUTHOR AND COPYRIGHT
194
195John Napiorkowski (jnapiorkowski) <jjnapiork@cpan.org>
196
197=head1 LICENSE
198
199This program is free software; you can redistribute it and/or modify
200it under the same terms as perl itself.
201
202=cut
203
2041;