1 package MooseX::Meta::TypeConstraint::Structured::Named;
4 use Moose::Meta::TypeConstraint ();
5 use Moose::Util::TypeConstraints;
7 extends 'Moose::Meta::TypeConstraint';
8 with 'MooseX::Meta::TypeConstraint::Role::Structured';
12 MooseX::Meta::TypeConstraint::Structured::Named - Structured Type Constraints
20 our $VERSION = '0.01';
24 Structured type constraints let you assign an internal pattern of type
25 constraints to a 'container' constraint. The goal is to make it easier to
26 declare constraints like "ArrayRef[Int, Int, Str]" where the constraint is an
27 ArrayRef of three elements and the internal constraint on the three is Int, Int
30 To accomplish this, we add an attribute to the base L<Moose::Meta::TypeConstraint>
31 to hold a L</signature>, which is a reference to a pattern of type constraints.
32 We then override L</constraint> to check our incoming value to the attribute
33 against this signature pattern.
35 Named structured Constraints expect the internal constraints to be in keys or
36 fields similar to what we expect in a HashRef.
40 The following types are defined in this class.
42 =head2 Moose::Meta::TypeConstraint
44 Used to make sure we can properly validate incoming signatures.
48 class_type 'Moose::Meta::TypeConstraint';
52 This class defines the following attributes.
56 This is a signature of internal contraints for the contents of the outer
61 has '+signature' => (isa=>'HashRef[Moose::Meta::TypeConstraint]');
63 =head2 optional_signature
65 This is a signature of internal contraints for the contents of the outer
66 contraint container. These are optional constraints.
70 has '+optional_signature' => (isa=>'HashRef[Moose::Meta::TypeConstraint]');
74 This class defines the following methods.
76 =head2 _normalize_args
78 Get arguments into a known state or die trying. Ideally we try to make this
79 into a HashRef so we can match it up with the L</signature> HashRef.
84 my ($self, $args) = @_;
86 if(ref $args eq 'HASH') {
89 confess 'Signature must be an HashRef type';
92 confess 'Signature cannot be empty';
98 The constraint is basically validating the L</signature> against the incoming
105 my %args = $self->_normalize_args(shift);
106 my @signature = keys %{$self->signature};
107 my @ptional_signature = keys %{$self->optional_signature}
108 if $self->has_optional_signature;
110 ## First make sure all the required type constraints match
111 while( my $type_constraint_key = shift @signature) {
112 my $type_constraint = $self->signature->{$type_constraint_key};
113 if(my $error = $type_constraint->validate($args{$type_constraint_key})) {
116 delete $args{$type_constraint_key};
119 ## Now test the option type constraints.
120 while( my $arg_key = keys %args) {
121 my $optional_type_constraint = $self->signature->{$arg_key};
122 if(my $error = $optional_type_constraint->validate($args{$arg_key})) {
127 ## If we got this far we passed!
132 =head2 signature_equals
134 Check that the signature equals another signature.
138 sub signature_equals {
139 my ($self, $compared_type_constraint) = @_;
141 foreach my $idx (keys %{$self->signature}) {
142 my $this = $self->signature->{$idx};
143 my $that = $compared_type_constraint->signature->{$idx};
144 return unless $this->equals($that);
147 if($self->has_optional_signature) {
148 foreach my $idx (keys %{$self->optional_signature}) {
149 my $this = $self->optional_signature->{$idx};
150 my $that = $compared_type_constraint->optional_signature->{$idx};
151 return unless $this->equals($that);
160 modifier to make sure equals descends into the L</signature>
164 around 'equals' => sub {
165 my ($equals, $self, $compared_type_constraint) = @_;
167 ## Make sure we are comparing typeconstraints of the same base class
168 return unless $compared_type_constraint->isa(__PACKAGE__);
170 ## Make sure the base equals is also good
171 return unless $self->$equals($compared_type_constraint);
173 ## Make sure the signatures match
174 return unless $self->signature_equals($compared_type_constraint);
176 ## If we get this far, the two are equal
182 John James Napiorkowski <jjnapiork@cpan.org>
186 You may distribute this code under the same terms as Perl itself.