rollback some stuff to reset my brain a bit
[gitmo/MooseX-Types-Structured.git] / lib / MooseX / Meta / TypeConstraint / Structured / Positional.pm
CommitLineData
9a491c80 1package MooseX::Meta::TypeConstraint::Structured::Positional;
2
3use Moose;
4use Moose::Meta::TypeConstraint ();
9a491c80 5
6extends 'Moose::Meta::TypeConstraint';
740eb6a9 7with 'MooseX::Meta::TypeConstraint::Role::Structured';
9a491c80 8
9=head1 NAME
10
11MooseX::Meta::TypeConstraint::Structured::Positional - Structured Type Constraints
12
309c8a6c 13=head1 SYNOPSIS
14
15The follow is example usage:
16
17 use Moose::Util::TypeConstraints;
18 use MooseX::Meta::TypeConstraint::Structured::Positional;
19
20 my @required = ('Str', 'Int');
21 my @optional = ('Object');
22
23 my $tc = MooseX::Meta::TypeConstraint::Structured::Positional->new(
24 name => 'Dict',
25 parent => find_type_constraint('ArrayRef'),
26 signature => [map {
27 find_type_constraint($_);
28 } @required],
29 optional_signature => [map {
30 find_type_constraint($_);
31 } @optional],
32 );
33
9a491c80 34=head1 DESCRIPTION
35
9a491c80 36Positionally structured Constraints expect the internal constraints to be in
309c8a6c 37'positioned' or ArrayRef style order. This allows you to add type constraints
38to the internal values of the Arrayref.
9a491c80 39
9a491c80 40=head1 ATTRIBUTES
41
42This class defines the following attributes.
43
44=head2 signature
45
46This is a signature of internal contraints for the contents of the outer
47contraint container.
48
49=cut
50
24dd1d2e 51has '+signature' => (isa=>'ArrayRef[Moose::Meta::TypeConstraint]');
9a491c80 52
53=head2 optional_signature
54
55This is a signature of internal contraints for the contents of the outer
56contraint container. These are optional constraints.
57
58=cut
59
24dd1d2e 60has '+optional_signature' => (isa=>'ArrayRef[Moose::Meta::TypeConstraint]');
9a491c80 61
62=head1 METHODS
63
64This class defines the following methods.
65
66=head2 _normalize_args
67
68Get arguments into a known state or die trying. Ideally we try to make this
69into a HashRef so we can match it up with the L</signature> HashRef.
70
71=cut
72
73sub _normalize_args {
74 my ($self, $args) = @_;
75 if(defined $args) {
76 if(ref $args eq 'ARRAY') {
77 @$args
78 } else {
79 confess 'Signature must be an ArrayRef type';
80 }
81 } else {
82 confess 'Signature cannot be empty';
83 }
84}
85
86=head2 constraint
87
88The constraint is basically validating the L</signature> against the incoming
89
90=cut
91
92sub constraint {
93 my $self = shift;
94 return sub {
95 my @args = $self->_normalize_args(shift);
96 my @signature = @{$self->signature};
78f55946 97 my @optional_signature = @{$self->optional_signature}
98 if $self->has_optional_signature;
9a491c80 99
100 ## First make sure all the required type constraints match
101 while( my $type_constraint = shift @signature) {
102 if(my $error = $type_constraint->validate(shift @args)) {
103 confess $error;
104 }
105 }
106
107 ## Now test the option type constraints.
108 while( my $arg = shift @args) {
99b27cbd 109 if(my $optional_type_constraint = shift @optional_signature) {
110 if(my $error = $optional_type_constraint->validate($arg)) {
111 confess $error;
112 }
113 } else {
114 confess "Too Many arguments for the available type constraints";
115 }
9a491c80 116 }
117
118 ## If we got this far we passed!
119 return 1;
120 };
121}
122
123=head2 signature_equals
124
125Check that the signature equals another signature.
126
127=cut
128
129sub signature_equals {
130 my ($self, $compared_type_constraint) = @_;
131
132 foreach my $idx (0..$#{$self->signature}) {
133 my $this = $self->signature->[$idx];
134 my $that = $compared_type_constraint->signature->[$idx];
135 return unless $this->equals($that);
136 }
137
138 if($self->has_optional_signature) {
139 foreach my $idx (0..$#{$self->optional_signature}) {
140 my $this = $self->optional_signature->[$idx];
141 my $that = $compared_type_constraint->optional_signature->[$idx];
142 return unless $this->equals($that);
143 }
144 }
145
146 return 1;
147}
148
9a491c80 149=head1 AUTHOR
150
151John James Napiorkowski <jjnapiork@cpan.org>
152
153=head1 LICENSE
154
155You may distribute this code under the same terms as Perl itself.
156
157=cut
158
159no Moose; 1;