bump version to 0.66
[gitmo/Moose.git] / lib / Moose / Meta / TypeConstraint / Union.pm
index 1337b0e..ed3cd59 100644 (file)
@@ -7,7 +7,8 @@ use metaclass;
 
 use Moose::Meta::TypeCoercion::Union;
 
-our $VERSION   = '0.06';
+our $VERSION   = '0.66';
+$VERSION = eval $VERSION;
 our $AUTHORITY = 'cpan:STEVAN';
 
 use base 'Moose::Meta::TypeConstraint';
@@ -20,7 +21,8 @@ __PACKAGE__->meta->add_attribute('type_constraints' => (
 sub new { 
     my ($class, %options) = @_;
     my $self = $class->SUPER::new(
-        name     => (join ' | ' => map { $_->name } @{$options{type_constraints}}),
+        name     => (join '|' => sort {$a cmp $b}
+                     map { $_->name } @{$options{type_constraints}}),
         parent   => undef,
         message  => undef,
         hand_optimized_type_constraint => undef,
@@ -40,6 +42,36 @@ sub new {
     return $self;
 }
 
+sub equals {
+    my ( $self, $type_or_name ) = @_;
+
+    my $other = Moose::Util::TypeConstraints::find_type_constraint($type_or_name);
+
+    return unless $other->isa(__PACKAGE__);
+
+    my @self_constraints  = @{ $self->type_constraints };
+    my @other_constraints = @{ $other->type_constraints };
+
+    return unless @self_constraints == @other_constraints;
+
+    # FIXME presort type constraints for efficiency?
+    constraint: foreach my $constraint ( @self_constraints ) {
+        for ( my $i = 0; $i < @other_constraints; $i++ ) {
+            if ( $constraint->equals($other_constraints[$i]) ) {
+                splice @other_constraints, $i, 1;
+                next constraint;
+            }
+        }
+    }
+
+    return @other_constraints == 0;
+}
+
+sub parents {
+    my $self = shift;
+    $self->type_constraints;
+}
+
 sub validate {
     my ($self, $value) = @_;
     my $message;
@@ -68,29 +100,27 @@ sub is_subtype_of {
     return 0;
 }
 
-sub includes_type {
-    my ($self, $type) = @_;
-
-    my $has_type = sub {
-        my $subtype = shift;
-
-        for my $type (@{ $self->type_constraints }) {
-            return 1 if $subtype->is_a_type_of($type);
-        }
-
-        return 0;
-    };
-
-    if ($type->isa('Moose::Meta::TypeConstraint::Union')) {
-        for my $t (@{ $type->type_constraints }) {
-            return 0 unless $has_type->($t);
-        }
-    }
-    else {
-        return 0 unless $has_type->($type);
+sub create_child_type {
+    my ( $self, %opts ) = @_;
+
+    my $constraint
+        = Moose::Meta::TypeConstraint->new( %opts, parent => $self );
+
+    # if we have a type constraint union, and no
+    # type check, this means we are just aliasing
+    # the union constraint, which means we need to
+    # handle this differently.
+    # - SL
+    if ( not( defined $opts{constraint} )
+        && $self->has_coercion ) {
+        $constraint->coercion(
+            Moose::Meta::TypeCoercion::Union->new(
+                type_constraint => $self,
+            )
+        );
     }
 
-    return 1;
+    return $constraint;
 }
 
 1;
@@ -106,7 +136,7 @@ Moose::Meta::TypeConstraint::Union - A union of Moose type constraints
 =head1 DESCRIPTION
 
 This metaclass represents a union of Moose type constraints. More 
-details to be explained later (possibly in a Cookbook::Recipe).
+details to be explained later (possibly in a Cookbook recipe).
 
 This actually used to be part of Moose::Meta::TypeConstraint, but it 
 is now better off in it's own file. 
@@ -126,10 +156,14 @@ but it does provide the same API
 
 =item B<type_constraints>
 
+=item B<parents>
+
 =item B<constraint>
 
 =item B<includes_type>
 
+=item B<equals>
+
 =back
 
 =head2 Overriden methods 
@@ -171,6 +205,8 @@ anyway. They are here for completeness.
 
 =item B<has_hand_optimized_type_constraint>
 
+=item B<create_child_type>
+
 =back
 
 =head1 BUGS
@@ -185,7 +221,7 @@ Stevan Little E<lt>stevan@iinteractive.comE<gt>
 
 =head1 COPYRIGHT AND LICENSE
 
-Copyright 2006-2008 by Infinity Interactive, Inc.
+Copyright 2006-2009 by Infinity Interactive, Inc.
 
 L<http://www.iinteractive.com>