Add predicates to the informational Mouse::Attribute attributes
[gitmo/Mouse.git] / lib / Mouse / Attribute.pm
index 22e86e0..da448b5 100644 (file)
@@ -26,26 +26,53 @@ sub weak_ref        { $_[0]->{weak_ref}        }
 sub init_arg        { $_[0]->{init_arg}        }
 sub type_constraint { $_[0]->{type_constraint} }
 
+sub has_name            { exists $_[0]->{name}            }
+sub has_class           { exists $_[0]->{class}           }
+sub has_default         { exists $_[0]->{default}         }
+sub has_predicate       { exists $_[0]->{predicate}       }
+sub has_clearer         { exists $_[0]->{clearer}         }
+sub has_handles         { exists $_[0]->{handles}         }
+sub has_weak_ref        { exists $_[0]->{weak_ref}        }
+sub has_init_arg        { exists $_[0]->{init_arg}        }
+sub has_type_constraint { exists $_[0]->{type_constraint} }
+
 sub generate_accessor {
     my $attribute = shift;
 
-    my $key     = $attribute->{init_arg};
-    my $default = $attribute->{default};
-    my $trigger = $attribute->{trigger};
+    my $name       = $attribute->{name};
+    my $key        = $attribute->{init_arg};
+    my $default    = $attribute->{default};
+    my $trigger    = $attribute->{trigger};
+    my $type       = $attribute->{type_constraint};
+
+    my $constraint = sub {
+        return unless $type;
+
+        my $checker = Mouse::TypeRegistry->optimized_constraints->{$type};
+        return $checker if $checker;
+
+        confess "Unable to parse type constraint '$type'";
+    }->();
 
     my $accessor = 'sub {
         my $self = shift;';
 
     if ($attribute->{is} eq 'rw') {
         $accessor .= 'if (@_) {
-            $self->{$key} = $_[0];';
+            local $_ = $_[0];';
+
+        if ($constraint) {
+            $accessor .= 'Carp::confess("Attribute ($name) does not pass the type constraint because: Validation failed for \'$type\' failed with value $_") unless $constraint->();'
+        }
+
+        $accessor .= '$self->{$key} = $_;';
 
         if ($attribute->{weak_ref}) {
             $accessor .= 'Scalar::Util::weaken($self->{$key});';
         }
 
         if ($trigger) {
-            $accessor .= '$trigger->($self, $_[0], $attribute);';
+            $accessor .= '$trigger->($self, $_, $attribute);';
         }
 
         $accessor .= '}';