Commit | Line | Data |
9a491c80 |
1 | package MooseX::Meta::TypeConstraint::Role::Structured; |
2 | |
3 | use Moose::Role; |
b5f77bd3 |
4 | use Moose::Util::TypeConstraints; |
5 | requires qw(_normalize_args signature_equals); |
9a491c80 |
6 | |
7 | =head1 NAME |
8 | |
9 | MooseX::Meta::TypeConstraint::Role::Structured - Structured Type Constraints |
10 | |
9a491c80 |
11 | =head1 DESCRIPTION |
12 | |
6479ca33 |
13 | This Role defines the interface and basic behavior of Structured Type Constraints. |
9a491c80 |
14 | |
309c8a6c |
15 | Structured type constraints let you assign an internal pattern of type |
16 | constraints to a 'container' constraint. The goal is to make it easier to |
17 | declare constraints like "ArrayRef[Int, Int, Str]" where the constraint is an |
18 | ArrayRef of three elements and the internal constraint on the three is Int, Int |
19 | and Str. |
20 | |
21 | To accomplish this, we add an attribute to the base L<Moose::Meta::TypeConstraint> |
22 | to hold a L</signature>, which is a reference to a pattern of type constraints. |
23 | We then override L</constraint> to check our incoming value to the attribute |
24 | against this signature pattern. Additionally we allow L</optional_signature> to |
25 | hold any optional type constraints. The overall goal is to support something |
26 | like: |
27 | |
28 | has 'attr' => (isa=>'Tuple[Int, Str, Optional[Int, Int]]'); |
29 | |
30 | These classes define how the underlying support for this works. |
31 | |
b5f77bd3 |
32 | =head1 TYPES |
33 | |
34 | The following types are defined in this class. |
35 | |
36 | =head2 Moose::Meta::TypeConstraint |
37 | |
38 | Used to make sure we can properly validate incoming signatures. |
39 | |
40 | =cut |
41 | |
42 | class_type 'Moose::Meta::TypeConstraint'; |
43 | |
9a491c80 |
44 | =head1 ATTRIBUTES |
45 | |
46 | This class defines the following attributes. |
47 | |
48 | =head2 signature |
49 | |
50 | This is a signature of internal contraints for the contents of the outer |
51 | contraint container. |
52 | |
53 | =cut |
54 | |
55 | has 'signature' => ( |
56 | is=>'ro', |
bc5c0758 |
57 | isa=>'Ref', |
9a491c80 |
58 | required=>1, |
59 | ); |
60 | |
24dd1d2e |
61 | =head2 optional_signature |
62 | |
63 | This is a signature of internal contraints for the contents of the outer |
64 | contraint container. These are optional constraints. |
65 | |
66 | =cut |
67 | |
68 | has 'optional_signature' => ( |
69 | is=>'ro', |
70 | isa=>'Ref', |
71 | predicate=>'has_optional_signature', |
72 | ); |
73 | |
9a491c80 |
74 | =head1 METHODS |
75 | |
76 | This class defines the following methods. |
77 | |
9a491c80 |
78 | =head2 equals |
79 | |
80 | modifier to make sure equals descends into the L</signature> |
81 | |
82 | =cut |
83 | |
b5f77bd3 |
84 | around 'equals' => sub { |
85 | my ($equals, $self, $compared_type_constraint) = @_; |
86 | |
87 | ## Make sure we are comparing typeconstraints of the same base class |
88 | return unless $compared_type_constraint->isa(__PACKAGE__); |
89 | |
90 | ## Make sure the base equals is also good |
91 | return unless $self->$equals($compared_type_constraint); |
92 | |
93 | ## Make sure the signatures match |
94 | return unless $self->signature_equals($compared_type_constraint); |
95 | |
96 | ## If we get this far, the two are equal |
97 | return 1; |
98 | }; |
99 | |
9a491c80 |
100 | =head1 AUTHOR |
101 | |
102 | John James Napiorkowski <jjnapiork@cpan.org> |
103 | |
104 | =head1 LICENSE |
105 | |
106 | You may distribute this code under the same terms as Perl itself. |
107 | |
108 | =cut |
109 | |
bc5c0758 |
110 | 1; |