Whenever we inline a type constraint, we need to include its inline environment.
[gitmo/Moose.git] / lib / Moose / Meta / TypeConstraint / Enum.pm
CommitLineData
dabed765 1package Moose::Meta::TypeConstraint::Enum;
2
3use strict;
4use warnings;
5use metaclass;
6
964294c1 7use B;
4078709c 8use Moose::Util::TypeConstraints ();
9
dabed765 10use base 'Moose::Meta::TypeConstraint';
11
12__PACKAGE__->meta->add_attribute('values' => (
4078709c 13 accessor => 'values',
dabed765 14));
15
964294c1 16my $inliner = sub {
17 my $self = shift;
18 my $val = shift;
19
3975b592 20 return 'defined(' . $val . ') '
21 . '&& !ref(' . $val . ') '
9c44971f 22 . '&& $enums{' . $val . '}';
964294c1 23};
24
dabed765 25sub new {
26 my ( $class, %args ) = @_;
27
28 $args{parent} = Moose::Util::TypeConstraints::find_type_constraint('Str');
964294c1 29 $args{inlined} = $inliner;
dabed765 30
f6af1028 31 if ( scalar @{ $args{values} } < 2 ) {
32 require Moose;
33 Moose->throw_error("You must have at least two values to enumerate through");
34 }
35
36 for (@{ $args{values} }) {
37 if (!defined($_)) {
38 require Moose;
39 Moose->throw_error("Enum values must be strings, not undef");
40 }
41 elsif (ref($_)) {
42 require Moose;
43 Moose->throw_error("Enum values must be strings, not '$_'");
44 }
45 }
46
964294c1 47 my %values = map { $_ => 1 } @{ $args{values} };
48 $args{constraint} = sub { $values{ $_[0] } };
9c44971f 49 $args{inline_environment} = { '%enums' => \%values };
964294c1 50
1b8d1399 51 my $self = $class->_new(\%args);
dabed765 52
53 $self->compile_type_constraint()
54 unless $self->_has_compiled_type_constraint;
55
56 return $self;
57}
58
59sub equals {
60 my ( $self, $type_or_name ) = @_;
61
62 my $other = Moose::Util::TypeConstraints::find_type_constraint($type_or_name);
63
64 return unless $other->isa(__PACKAGE__);
65
66 my @self_values = sort @{ $self->values };
67 my @other_values = sort @{ $other->values };
68
69 return unless @self_values == @other_values;
70
71 while ( @self_values ) {
72 my $value = shift @self_values;
73 my $other_value = shift @other_values;
74
75 return unless $value eq $other_value;
76 }
77
78 return 1;
79}
80
81sub constraint {
82 my $self = shift;
83
84 my %values = map { $_ => undef } @{ $self->values };
85
86 return sub { exists $values{$_[0]} };
87}
88
2fb4885e 89sub create_child_type {
90 my ($self, @args) = @_;
39170e48 91 return Moose::Meta::TypeConstraint->new(@args, parent => $self);
2fb4885e 92}
93
4078709c 941;
dabed765 95
ad46f524 96# ABSTRACT: Type constraint for enumerated values.
97
dabed765 98__END__
99
100=pod
101
d7d8f2ee 102=head1 DESCRIPTION
103
104This class represents type constraints based on an enumerated list of
105acceptable values.
106
107=head1 INHERITANCE
108
109C<Moose::Meta::TypeConstraint::Enum> is a subclass of
110L<Moose::Meta::TypeConstraint>.
111
dabed765 112=head1 METHODS
113
114=over 4
115
d7d8f2ee 116=item B<< Moose::Meta::TypeConstraint::Enum->new(%options) >>
117
d36ebb14 118This creates a new enum type constraint based on the given
d7d8f2ee 119C<%options>.
120
121It takes the same options as its parent, with several
122exceptions. First, it requires an additional option, C<values>. This
123should be an array reference containing a list of valid string
124values. Second, it automatically sets the parent to the C<Str> type.
125
126Finally, it ignores any provided C<constraint> option. The constraint
53de29e5 127is generated automatically based on the provided C<values>.
dabed765 128
d7d8f2ee 129=item B<< $constraint->values >>
dabed765 130
d7d8f2ee 131Returns the array reference of acceptable values provided to the
132constructor.
dabed765 133
d7d8f2ee 134=item B<< $constraint->create_child_type >>
dabed765 135
d7d8f2ee 136This returns a new L<Moose::Meta::TypeConstraint> object with the type
137as its parent.
4078709c 138
d7d8f2ee 139Note that it does I<not> return a C<Moose::Meta::TypeConstraint::Enum>
140object!
2fb4885e 141
dabed765 142=back
143
4078709c 144=head1 BUGS
145
d4048ef3 146See L<Moose/BUGS> for details on reporting bugs.
4078709c 147
dabed765 148=cut
149
150