changelog
[gitmo/Moose.git] / lib / Moose / Meta / TypeConstraint / Union.pm
CommitLineData
8ee73eeb 1
2package Moose::Meta::TypeConstraint::Union;
3
4use strict;
5use warnings;
6use metaclass;
7
3726f905 8use Moose::Meta::TypeCoercion::Union;
9
a94188ac 10our $VERSION = '0.56';
d44714be 11our $AUTHORITY = 'cpan:STEVAN';
8ee73eeb 12
d67145ed 13use base 'Moose::Meta::TypeConstraint';
14
8ee73eeb 15__PACKAGE__->meta->add_attribute('type_constraints' => (
16 accessor => 'type_constraints',
17 default => sub { [] }
18));
19
20sub new {
3726f905 21 my ($class, %options) = @_;
22 my $self = $class->SUPER::new(
23 name => (join ' | ' => map { $_->name } @{$options{type_constraints}}),
24 parent => undef,
25 message => undef,
26 hand_optimized_type_constraint => undef,
27 compiled_type_constraint => sub {
28 my $value = shift;
29 foreach my $type (@{$options{type_constraints}}) {
30 return 1 if $type->check($value);
31 }
32 return undef;
33 },
34 %options
35 );
36 $self->_set_constraint(sub { $self->check($_[0]) });
37 $self->coercion(Moose::Meta::TypeCoercion::Union->new(
38 type_constraint => $self
39 ));
8ee73eeb 40 return $self;
41}
42
dabed765 43sub equals {
44 my ( $self, $type_or_name ) = @_;
45
46 my $other = Moose::Util::TypeConstraints::find_type_constraint($type_or_name);
47
48 return unless $other->isa(__PACKAGE__);
49
50 my @self_constraints = @{ $self->type_constraints };
51 my @other_constraints = @{ $other->type_constraints };
52
53 return unless @self_constraints == @other_constraints;
54
55 # FIXME presort type constraints for efficiency?
56 constraint: foreach my $constraint ( @self_constraints ) {
57 for ( my $i = 0; $i < @other_constraints; $i++ ) {
58 if ( $constraint->equals($other_constraints[$i]) ) {
59 splice @other_constraints, $i, 1;
60 next constraint;
61 }
62 }
63 }
64
65 return @other_constraints == 0;
66}
67
68sub parents {
69 my $self = shift;
70 $self->type_constraints;
71}
72
8ee73eeb 73sub validate {
3726f905 74 my ($self, $value) = @_;
8ee73eeb 75 my $message;
76 foreach my $type (@{$self->type_constraints}) {
77 my $err = $type->validate($value);
78 return unless defined $err;
79 $message .= ($message ? ' and ' : '') . $err
80 if defined $err;
81 }
82 return ($message . ' in (' . $self->name . ')') ;
83}
84
85sub is_a_type_of {
86 my ($self, $type_name) = @_;
87 foreach my $type (@{$self->type_constraints}) {
88 return 1 if $type->is_a_type_of($type_name);
89 }
90 return 0;
91}
92
93sub is_subtype_of {
94 my ($self, $type_name) = @_;
95 foreach my $type (@{$self->type_constraints}) {
96 return 1 if $type->is_subtype_of($type_name);
97 }
98 return 0;
99}
100
1011;
102
103__END__
104
105=pod
106
39b3bc94 107=head1 NAME
108
ecb59493 109Moose::Meta::TypeConstraint::Union - A union of Moose type constraints
39b3bc94 110
111=head1 DESCRIPTION
112
ecb59493 113This metaclass represents a union of Moose type constraints. More
5cfe3805 114details to be explained later (possibly in a Cookbook recipe).
ecb59493 115
116This actually used to be part of Moose::Meta::TypeConstraint, but it
117is now better off in it's own file.
118
39b3bc94 119=head1 METHODS
120
ecb59493 121This class is not a subclass of Moose::Meta::TypeConstraint,
122but it does provide the same API
123
39b3bc94 124=over 4
125
ecb59493 126=item B<meta>
39b3bc94 127
ecb59493 128=item B<new>
39b3bc94 129
ecb59493 130=item B<name>
131
132=item B<type_constraints>
39b3bc94 133
dabed765 134=item B<parents>
135
39b3bc94 136=item B<constraint>
137
1b58cb9f 138=item B<includes_type>
139
dabed765 140=item B<equals>
141
ecb59493 142=back
39b3bc94 143
ecb59493 144=head2 Overriden methods
145
146=over 4
147
148=item B<check>
149
150=item B<coerce>
151
152=item B<validate>
39b3bc94 153
154=item B<is_a_type_of>
155
156=item B<is_subtype_of>
157
ecb59493 158=back
39b3bc94 159
ecb59493 160=head2 Empty or Stub methods
39b3bc94 161
ecb59493 162These methods tend to not be very relevant in
163the context of a union. Either that or they are
164just difficult to specify and not very useful
165anyway. They are here for completeness.
39b3bc94 166
ecb59493 167=over 4
39b3bc94 168
169=item B<parent>
170
ecb59493 171=item B<coercion>
39b3bc94 172
ecb59493 173=item B<has_coercion>
174
175=item B<message>
176
177=item B<has_message>
39b3bc94 178
0eec94be 179=item B<hand_optimized_type_constraint>
180
181=item B<has_hand_optimized_type_constraint>
182
39b3bc94 183=back
184
185=head1 BUGS
186
187All complex software has bugs lurking in it, and this module is no
188exception. If you find a bug please either email me, or add the bug
189to cpan-RT.
190
191=head1 AUTHOR
192
193Stevan Little E<lt>stevan@iinteractive.comE<gt>
194
39b3bc94 195=head1 COPYRIGHT AND LICENSE
196
778db3ac 197Copyright 2006-2008 by Infinity Interactive, Inc.
39b3bc94 198
199L<http://www.iinteractive.com>
200
201This library is free software; you can redistribute it and/or modify
202it under the same terms as Perl itself.
203
8ee73eeb 204=cut