1 package MooseX::Meta::TypeConstraint::Structured;
3 use 5.8.8; ## Minimum tested Perl Version
5 use Moose::Util::TypeConstraints;
7 extends 'Moose::Meta::TypeConstraint';
9 our $AUTHORITY = 'cpan:JJNAPIORK';
13 MooseX::Meta::TypeConstraint::Structured - Structured Type Constraints
21 our $VERSION = '0.01';
25 Structured type constraints let you assign an internal pattern of type
26 constraints to a 'container' constraint. The goal is to make it easier to
27 declare constraints like "ArrayRef[Int, Int, Str]" where the constraint is an
28 ArrayRef of three elements and the internal constraint on the three is Int, Int
31 To accomplish this, we add an attribute to the base L<Moose::Meta::TypeConstraint>
32 to hold a L</signature>, which is a reference to a pattern of type constraints.
33 We then override L</constraint> to check our incoming value to the attribute
34 against this signature pattern.
38 The following subtypes and coercions are defined in this class.
40 =head2 MooseX::Meta::TypeConstraint::Structured::Signature
42 This is a type constraint to normalize the incoming L</signature>. We want
43 everything as a HashRef in the end.
47 subtype 'MooseX::Meta::TypeConstraint::Structured::Signature',
51 foreach my $key (keys %signature) {
52 $signature{$key}->isa('Moose::Meta::TypeConstraint');
56 coerce 'MooseX::Meta::TypeConstraint::Structured::Signature',
57 from 'ArrayRef[Object]',
60 my %hashed_signature = map { $_ => $signature[$_] } 0..$#signature;
66 This class defines the following attributes.
70 This is a signature of internal contraints for the contents of the outer
77 isa=>'MooseX::Meta::TypeConstraint::Structured::Signature',
84 This class defines the following methods.
86 =head2 _normalize_args
88 Get arguments into a known state or die trying. Ideally we try to make this
89 into a HashRef so we can match it up with the L</signature> HashRef.
94 my ($self, $args) = @_;
96 if(ref $args eq 'ARRAY') {
97 return map { $_ => $args->[$_] } (0..$#$args);
98 } elsif (ref $args eq 'HASH') {
101 confess 'Signature must be a reference';
104 confess 'Signature cannot be empty';
110 The constraint is basically validating the L</signature> against the incoming
117 my %args = $self->_normalize_args(shift);
118 foreach my $idx (keys %{$self->signature}) {
119 my $type_constraint = $self->signature->{$idx};
120 if(my $error = $type_constraint->validate($args{$idx})) {
129 modifier to make sure equals descends into the L</signature>
133 around 'equals' => sub {
134 my ($equals, $self, $compared_type_constraint) = @_;
136 ## Make sure we are comparing typeconstraints of the same base class
137 return unless $compared_type_constraint->isa(__PACKAGE__);
139 ## Make sure the base equals is also good
140 return unless $self->$equals($compared_type_constraint);
142 ## Make sure the signatures match
143 return unless $self->signature_equals($compared_type_constraint);
145 ## If we get this far, the two are equal
149 =head2 signature_equals
151 Check that the signature equals another signature.
155 sub signature_equals {
156 my ($self, $compared_type_constraint) = @_;
158 foreach my $idx (keys %{$self->signature}) {
159 my $this = $self->signature->{$idx};
160 my $that = $compared_type_constraint->signature->{$idx};
161 return unless $this->equals($that);
169 John James Napiorkowski <jjnapiork@cpan.org>
173 You may distribute this code under the same terms as Perl itself.