eea8d51dcfe7ecf12bc0f8f1beee6d281cebf203
[gitmo/MooseX-Types-Structured.git] / lib / MooseX / Meta / TypeConstraint / Structured.pm
1 package MooseX::Meta::TypeConstraint::Structured;
2
3 use Moose;
4 use Moose::Util::TypeConstraints ();
5 extends 'Moose::Meta::TypeConstraint';
6
7 =head1 NAME
8
9 MooseX::Meta::TypeConstraint::Structured - Structured type constraints.
10
11 =head1 DESCRIPTION
12
13 A structure is a set of L<Moose::Meta::TypeConstraint> that are 'aggregated' in
14 such a way as that they are all applied to an incoming list of arguments.  The
15 idea here is that a Type Constraint could be something like, "An Int followed by
16 an Int and then a Str" and that this could be done so with a declaration like:
17
18     Tuple[Int,Int,Str]; ## Example syntax
19     
20 So a structure is a list of Type constraints (the "Int,Int,Str" in the above
21 example) which are intended to function together.
22
23 =head1 ATTRIBUTES
24
25 This class defines the following attributes.
26
27 =head2 type_constraints
28
29 A list of L<Moose::Meta::TypeConstraint> objects.
30
31 =cut
32
33 has 'type_constraints' => (
34     is=>'ro',
35     isa=>'Ref',
36     predicate=>'has_type_constraints',
37 );
38
39 =head2 constraint_generator
40
41 A subref or closure that contains the way we validate incoming values against
42 a set of type constraints.
43
44 =cut
45
46 has 'constraint_generator' => (is=>'ro', isa=>'CodeRef');
47
48 =head1 METHODS
49
50 This class defines the following methods.
51
52 =head2 generate_constraint_for ($type_constraints)
53
54 Given some type constraints, use them to generate validation rules for an ref
55 of values (to be passed at check time)
56
57 =cut
58
59 sub generate_constraint_for {
60     my ($self, $type_constraints) = @_;
61     return sub {
62         my $constraint_generator = $self->constraint_generator;
63         return $constraint_generator->($type_constraints, @_);
64     };
65 }
66
67 =head2 parameterize (@type_constraints)
68
69 Given a ref of type constraints, create a structured type.
70
71 =cut
72
73 sub parameterize {
74     my ($self, @type_constraints) = @_;
75     my $name = $self->name .'['. join(',', map {"$_"} @type_constraints) .']';
76     return __PACKAGE__->new(
77         name => $name,
78         parent => $self,
79         type_constraints => \@type_constraints,
80         constraint_generator => $self->constraint_generator,
81     );
82 }
83
84 =head2 compile_type_constraint
85
86 hook into compile_type_constraint so we can set the correct validation rules.
87
88 =cut
89
90 around 'compile_type_constraint' => sub {
91     my ($compile_type_constraint, $self, @args) = @_;
92     
93     if($self->has_type_constraints) {
94         my $type_constraints = $self->type_constraints;
95         my $constraint = $self->generate_constraint_for($type_constraints);
96         $self->_set_constraint($constraint);        
97     }
98
99     return $self->$compile_type_constraint(@args);
100 };
101
102 =head1 SEE ALSO
103
104 The following modules or resources may be of interest.
105
106 L<Moose>, L<Moose::Meta::TypeConstraint>
107
108 =head1 AUTHOR
109
110 John Napiorkowski, C<< <jjnapiork@cpan.org> >>
111
112 =head1 COPYRIGHT & LICENSE
113
114 This program is free software; you can redistribute it and/or modify
115 it under the same terms as Perl itself.
116
117 =cut
118
119 1;