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