finished extended type examples
[gitmo/MooseX-Dependent.git] / lib / MooseX / Dependent / Meta / TypeConstraint / Dependent.pm
index 9cfc50f..b05a3e2 100644 (file)
@@ -36,6 +36,7 @@ has 'parent_type_constraint' => (
     required=>1,
 );
 
+
 =head2 constraining_value_type_constraint
 
 This is a type constraint which defines what kind of value is allowed to be the
@@ -63,79 +64,10 @@ has 'constraining_value' => (
     predicate=>'has_constraining_value',
 );
 
-=head2 constraint_generator
-
-A subref or closure that contains the way we validate incoming values against
-a set of type constraints.
-
-
-has 'constraint_generator' => (
-    is=>'ro',
-    isa=>'CodeRef',
-    predicate=>'has_constraint_generator',
-    required=>1,
-);
-
 =head1 METHODS
 
 This class defines the following methods.
 
-=head2 validate
-
-We intercept validate in order to custom process the message.
-
-override 'validate' => sub {
-    my ($self, @args) = @_;
-    my $compiled_type_constraint = $self->_compiled_type_constraint;
-    my $message = bless {message=>undef}, 'MooseX::Types::Dependent::Message';
-    my $result = $compiled_type_constraint->(@args, $message);
-
-    if($result) {
-        return $result;
-    } else {
-        my $args = Devel::PartialDump::dump(@args);
-        if(my $message = $message->{message}) {
-            return $self->get_message("$args, Internal Validation Error is: $message");
-        } else {
-            return $self->get_message($args);
-        }
-    }
-};
-
-=head2 generate_constraint_for ($type_constraints)
-
-Given some type constraints, use them to generate validation rules for an ref
-of values (to be passed at check time)
-
-
-sub generate_constraint_for {
-    my ($self, $callback) = @_;
-    return sub {   
-        my $dependent_pair = shift @_;
-        my ($dependent, $constraining) = @$dependent_pair;
-        
-        ## First need to test the bits
-        unless($self->check_dependent($dependent)) {
-            $_[0]->{message} = $self->get_message_dependent($dependent)
-             if $_[0];
-            return;
-        }
-    
-        unless($self->check_constraining($constraining)) {
-            $_[0]->{message} = $self->get_message_constraining($constraining)
-             if $_[0];
-            return;
-        }
-    
-        my $constraint_generator = $self->constraint_generator;
-        return $constraint_generator->(
-            $dependent,
-            $callback,
-            $constraining,
-        );
-    };
-}
-
 =head2 parameterize (@args)
 
 Given a ref of type constraints, create a structured type.
@@ -145,28 +77,48 @@ Given a ref of type constraints, create a structured type.
 sub parameterize {
     my $self = shift @_;
     my $class = ref $self;
-    
+
+    Moose->throw_error("$self already has a constraining value.") if
+     $self->has_constraining_value;
+         
     if(blessed $_[0] && $_[0]->isa('Moose::Meta::TypeConstraint')) {
         my $arg1 = shift @_;
-        my $arg2 = shift @_ || $self->constraining_value_type_constraint;
-        
-        Moose->throw_error("$arg2 is not a type constraint")
-         unless $arg2->isa('Moose::Meta::TypeConstraint');
          
-        Moose->throw_error('Too Many Args!  Two are allowed.') if @_;
-        
-        return $class->new(
-            name => $self->_generate_subtype_name($arg1, $arg2),
-            parent => $self,
-            constraint => $self->constraint,
-            parent_type_constraint=>$arg1,
-            constraining_value_type_constraint => $arg2,
-        );
-
+        if(blessed $_[0] && $_[0]->isa('Moose::Meta::TypeConstraint')) {
+            my $arg2 = shift @_ || $self->constraining_value_type_constraint;
+            
+            ## TODO fix this crap!
+            Moose->throw_error("$arg2 is not a type constraint")
+             unless $arg2->isa('Moose::Meta::TypeConstraint');
+             
+            Moose->throw_error("$arg1 is not a type of: ".$self->parent_type_constraint->name)
+             unless $arg1->is_a_type_of($self->parent_type_constraint);
+
+            Moose->throw_error("$arg2 is not a type of: ".$self->constraining_value_type_constraint->name)
+             unless $arg2->is_a_type_of($self->constraining_value_type_constraint);
+             
+            Moose->throw_error('Too Many Args!  Two are allowed.') if @_;
+            
+            return $class->new(
+                name => $self->_generate_subtype_name($arg1, $arg2),
+                parent => $self,
+                constraint => $self->constraint,
+                parent_type_constraint=>$arg1,
+                constraining_value_type_constraint => $arg2,
+            );
+        } else {
+            Moose->throw_error("$arg1 is not a type of: ".$self->constraining_value_type_constraint->name)
+             unless $arg1->is_a_type_of($self->constraining_value_type_constraint);
+             
+            return $class->new(
+                name => $self->_generate_subtype_name($self->parent_type_constraint, $arg1),
+                parent => $self,
+                constraint => $self->constraint,
+                parent_type_constraint=>$self->parent_type_constraint,
+                constraining_value_type_constraint => $arg1,
+            );
+        }
     } else {
-        Moose->throw_error("$self already has a constraining value.") if
-         $self->has_constraining_value;
-        
         my $args;
         ## Jump through some hoops to let them do tc[key=>10] and tc[{key=>10}]
         if(@_) {
@@ -283,21 +235,34 @@ sub is_a_type_of {
 
 around 'check' => sub {
     my ($check, $self, @args) = @_;
-    return $self->parent_type_constraint->check(@args) && $self->$check(@args)
+    return (
+        $self->parent_type_constraint->check(@args) &&
+        $self->$check(@args)
+    );
 };
 
 around 'validate' => sub {
     my ($validate, $self, @args) = @_;
-    return $self->parent_type_constraint->validate(@args) || $self->$validate(@args);
+    return (
+        $self->parent_type_constraint->validate(@args) ||
+        $self->$validate(@args)
+    );
 };
 
 around '_compiled_type_constraint' => sub {
     my ($method, $self, @args) = @_;
     my $coderef = $self->$method(@args);
-    my @extra_args = $self->has_constraining_value ? $self->constraining_value : ();
+    my $constraining;
+    if($self->has_constraining_value) {
+        $constraining = $self->constraining_value;
+    } 
+    
     return sub {
         my @local_args = @_;
-        $coderef->(@local_args, @extra_args);
+        if(my $err = $self->constraining_value_type_constraint->validate($constraining)) {
+            Moose->throw_error($err);
+        }
+        $coderef->(@local_args, $constraining);
     };
 };