use Moose;
use Moose::Meta::TypeConstraint ();
-use Moose::Util::TypeConstraints;
extends 'Moose::Meta::TypeConstraint';
with 'MooseX::Meta::TypeConstraint::Role::Structured';
MooseX::Meta::TypeConstraint::Structured::Named - Structured Type Constraints
-=head1 VERSION
+=head1 SYNOPSIS
-0.01
+The follow is example usage:
-=cut
-
-our $VERSION = '0.01';
+ use Moose::Util::TypeConstraints;
+ use MooseX::Meta::TypeConstraint::Structured::Named;
+
+ my %required = (key1='Str', key2=>'Int');
+ my %optional = (key3=>'Object');
+
+ my $tc = MooseX::Meta::TypeConstraint::Structured::Named->new(
+ name => 'Dict',
+ parent => find_type_constraint('HashRef'),
+ package_defined_in => __PACKAGE__,
+ signature => {map {
+ $_ => find_type_constraint($required{$_});
+ } keys %required},
+ optional_signature => {map {
+ $_ => find_type_constraint($optional{$_});
+ } keys %optional},
+ );
=head1 DESCRIPTION
-Structured type constraints let you assign an internal pattern of type
-constraints to a 'container' constraint. The goal is to make it easier to
-declare constraints like "ArrayRef[Int, Int, Str]" where the constraint is an
-ArrayRef of three elements and the internal constraint on the three is Int, Int
-and Str.
-
-To accomplish this, we add an attribute to the base L<Moose::Meta::TypeConstraint>
-to hold a L</signature>, which is a reference to a pattern of type constraints.
-We then override L</constraint> to check our incoming value to the attribute
-against this signature pattern.
-
Named structured Constraints expect the internal constraints to be in keys or
-fields similar to what we expect in a HashRef.
-
-=head1 TYPES
-
-The following types are defined in this class.
-
-=head2 Moose::Meta::TypeConstraint
-
-Used to make sure we can properly validate incoming signatures.
-
-=cut
-
-class_type 'Moose::Meta::TypeConstraint';
+fields similar to what we expect in a HashRef. Basically, this allows you to
+easily add type constraint checks against values in the wrapping HashRef
+identified by the key name.
=head1 ATTRIBUTES
my $self = shift;
return sub {
my %args = $self->_normalize_args(shift);
- my @signature = keys %{$self->signature};
- my @ptional_signature = keys %{$self->optional_signature}
- if $self->has_optional_signature;
+ my @optional_signature;
+
+ if($signature[-1]->isa('MooseX::Meta::TypeConstraint::Structured::Optional')) {
+ my $optional = pop @signature;
+ @optional_signature = @{$optional->signature};
+ }
## First make sure all the required type constraints match
- while( my $type_constraint_key = shift @signature) {
- my $type_constraint = $self->signature->{$type_constraint_key};
- if(my $error = $type_constraint->validate($args{$type_constraint_key})) {
+ foreach my $sig_key (keys %{$self->signature}) {
+ my $type_constraint = $self->signature->{$sig_key};
+ if(my $error = $type_constraint->validate($args{$sig_key})) {
confess $error;
+ } else {
+ delete $args{$sig_key};
}
- delete $args{$type_constraint_key};
}
## Now test the option type constraints.
- while( my $arg_key = keys %args) {
- my $optional_type_constraint = $self->signature->{$arg_key};
+ foreach my $arg_key (keys %args) {
+ my $optional_type_constraint = $self->optional_signature->{$arg_key};
if(my $error = $optional_type_constraint->validate($args{$arg_key})) {
confess $error;
}
return 1;
}
-=head2 equals
-
-modifier to make sure equals descends into the L</signature>
-=cut
-
-around 'equals' => sub {
- my ($equals, $self, $compared_type_constraint) = @_;
-
- ## Make sure we are comparing typeconstraints of the same base class
- return unless $compared_type_constraint->isa(__PACKAGE__);
-
- ## Make sure the base equals is also good
- return unless $self->$equals($compared_type_constraint);
-
- ## Make sure the signatures match
- return unless $self->signature_equals($compared_type_constraint);
-
- ## If we get this far, the two are equal
- return 1;
-};
=head1 AUTHOR