tests pass now
[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
8our $VERSION = '0.03';
9
10__PACKAGE__->meta->add_attribute('type_constraints' => (
11 accessor => 'type_constraints',
12 default => sub { [] }
13));
14
15sub new {
16 my $class = shift;
17 my $self = $class->meta->new_object(@_);
18 return $self;
19}
20
21sub name { join ' | ' => map { $_->name } @{$_[0]->type_constraints} }
22
23# NOTE:
24# this should probably never be used
25# but we include it here for completeness
26sub constraint {
27 my $self = shift;
28 sub { $self->check($_[0]) };
29}
30
31# conform to the TypeConstraint API
32sub parent { undef }
33sub message { undef }
34sub has_message { 0 }
35
36# FIXME:
37# not sure what this should actually do here
38sub coercion { undef }
39
40# this should probably be memoized
41sub has_coercion {
42 my $self = shift;
43 foreach my $type (@{$self->type_constraints}) {
44 return 1 if $type->has_coercion
45 }
46 return 0;
47}
48
49# NOTE:
50# this feels too simple, and may not always DWIM
51# correctly, especially in the presence of
52# close subtype relationships, however it should
53# work for a fair percentage of the use cases
54sub coerce {
55 my $self = shift;
56 my $value = shift;
57 foreach my $type (@{$self->type_constraints}) {
58 if ($type->has_coercion) {
59 my $temp = $type->coerce($value);
60 return $temp if $self->check($temp);
61 }
62 }
63 return undef;
64}
65
66sub _compiled_type_constraint {
67 my $self = shift;
68 return sub {
69 my $value = shift;
70 foreach my $type (@{$self->type_constraints}) {
71 return 1 if $type->check($value);
72 }
73 return undef;
74 }
75}
76
77sub check {
78 my $self = shift;
79 my $value = shift;
80 $self->_compiled_type_constraint->($value);
81}
82
83sub validate {
84 my $self = shift;
85 my $value = shift;
86 my $message;
87 foreach my $type (@{$self->type_constraints}) {
88 my $err = $type->validate($value);
89 return unless defined $err;
90 $message .= ($message ? ' and ' : '') . $err
91 if defined $err;
92 }
93 return ($message . ' in (' . $self->name . ')') ;
94}
95
96sub is_a_type_of {
97 my ($self, $type_name) = @_;
98 foreach my $type (@{$self->type_constraints}) {
99 return 1 if $type->is_a_type_of($type_name);
100 }
101 return 0;
102}
103
104sub is_subtype_of {
105 my ($self, $type_name) = @_;
106 foreach my $type (@{$self->type_constraints}) {
107 return 1 if $type->is_subtype_of($type_name);
108 }
109 return 0;
110}
111
1121;
113
114__END__
115
116=pod
117
39b3bc94 118=head1 NAME
119
120=head1 SYNOPOSIS
121
122=head1 DESCRIPTION
123
124=head1 METHODS
125
126=over 4
127
128=item B<check>
129
130=item B<coerce>
131
132=item B<coercion>
133
134=item B<constraint>
135
136=item B<has_coercion>
137
138=item B<has_message>
139
140=item B<is_a_type_of>
141
142=item B<is_subtype_of>
143
144=item B<message>
145
146=item B<meta>
147
148=item B<name>
149
150=item B<new>
151
152=item B<parent>
153
154=item B<type_constraints>
155
156=item B<validate>
157
158=back
159
160=head1 BUGS
161
162All complex software has bugs lurking in it, and this module is no
163exception. If you find a bug please either email me, or add the bug
164to cpan-RT.
165
166=head1 AUTHOR
167
168Stevan Little E<lt>stevan@iinteractive.comE<gt>
169
170Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
171
172=head1 COPYRIGHT AND LICENSE
173
174Copyright 2006 by Infinity Interactive, Inc.
175
176L<http://www.iinteractive.com>
177
178This library is free software; you can redistribute it and/or modify
179it under the same terms as Perl itself.
180
8ee73eeb 181=cut