e4ae3dc2bbadfbd66b9324d70abbd2896a4796fb
[gitmo/MooseX-Types-Path-Class.git] / lib / MooseX / Types / Path / Class.pm
1 package MooseX::Types::Path::Class;
2
3 use warnings FATAL => 'all';
4 use strict;
5
6 our $VERSION = '0.06';
7 $VERSION = eval $VERSION;
8 our $AUTHORITY = 'cpan:THEPLER';
9
10 use Path::Class ();
11 # TODO: export dir() and file() from Path::Class? (maybe)
12
13 use MooseX::Types
14     -declare => [qw( Dir File ExistingDir ExistingFile NonExistingDir NonExistingFile )];
15
16 use MooseX::Types::Moose qw(Str ArrayRef);
17
18 class_type('Path::Class::Dir');
19 class_type('Path::Class::File');
20
21 subtype Dir, as 'Path::Class::Dir';
22 subtype File, as 'Path::Class::File';
23
24 subtype ExistingFile, as File, where { -e $_->stringify },
25     message { "File '$_' must exist." };
26
27 subtype NonExistingFile, as File, where { !-e $_->stringify },
28     message { "File '$_' must not exist." };
29
30 subtype ExistingDir, as Dir,
31     where { -e $_->stringify && -d $_->stringify },
32     message { "Directory '$_' must exist" };
33
34 subtype NonExistingDir, as Dir,
35     where { !-e $_->stringify },
36     message { "Directory '$_' not must exist" };
37
38 for my $type ( 'Path::Class::Dir', Dir, ExistingDir, NonExistingDir ) {
39     coerce $type,
40         from Str,      via { Path::Class::Dir->new("$_") },
41         from ArrayRef, via { Path::Class::Dir->new(@$_) };
42 }
43
44 for my $type ( 'Path::Class::File', File, ExistingFile, NonExistingFile ) {
45     coerce $type,
46         from Str,      via { Path::Class::File->new("$_") },
47         from ArrayRef, via { Path::Class::File->new(@$_) };
48 }
49
50 # optionally add Getopt option type
51 eval { require MooseX::Getopt; };
52 if ( !$@ ) {
53     MooseX::Getopt::OptionTypeMap->add_option_type_to_map( $_, '=s', )
54         for (
55             'Path::Class::Dir', 'Path::Class::File',
56             Dir,                 File,
57             ExistingDir,         ExistingFile,
58             NonExistingFile,     NonExistingDir,
59         );
60 }
61
62 1;
63 __END__
64
65
66 =head1 NAME
67
68 MooseX::Types::Path::Class - A Path::Class type library for Moose
69
70
71 =head1 SYNOPSIS
72
73   package MyClass;
74   use Moose;
75   use MooseX::Types::Path::Class;
76   with 'MooseX::Getopt';  # optional
77
78   has 'dir' => (
79       is       => 'ro',
80       isa      => 'Path::Class::Dir',
81       required => 1,
82       coerce   => 1,
83   );
84
85   has 'file' => (
86       is       => 'ro',
87       isa      => 'Path::Class::File',
88       required => 1,
89       coerce   => 1,
90   );
91
92   # these attributes are coerced to the
93   # appropriate Path::Class objects
94   MyClass->new( dir => '/some/directory/', file => '/some/file' );
95
96
97 =head1 DESCRIPTION
98
99 MooseX::Types::Path::Class creates common L<Moose> types,
100 coercions and option specifications useful for dealing
101 with L<Path::Class> objects as L<Moose> attributes.
102
103 Coercions (see L<Moose::Util::TypeConstraints>) are made
104 from both 'Str' and 'ArrayRef' to both L<Path::Class::Dir> and
105 L<Path::Class::File> objects.  If you have L<MooseX::Getopt> installed,
106 the Getopt option type ("=s") will be added for both
107 L<Path::Class::Dir> and L<Path::Class::File>.
108
109
110 =head1 EXPORTS
111
112 None of these are exported by default.  They are provided via
113 L<MooseX::Types>.
114
115 =over
116
117 =item Dir, File
118
119 These exports can be used instead of the full class names.  Example:
120
121   package MyClass;
122   use Moose;
123   use MooseX::Types::Path::Class qw(Dir File);
124
125   has 'dir' => (
126       is       => 'ro',
127       isa      => Dir,
128       required => 1,
129       coerce   => 1,
130   );
131
132   has 'file' => (
133       is       => 'ro',
134       isa      => File,
135       required => 1,
136       coerce   => 1,
137   );
138
139 Note that there are no quotes around Dir or File.
140
141 =item ExistingDir, ExistingFile
142
143 Like File and Dir, but the files or directories must exist on disk
144 when the type is checked, and the object on disk must be a file (for
145 ExistingFile) or directory (for ExistingDir).
146
147 At no point will this library attempt to coerce a path into existence
148 by creating directories or files.  The coercions for ExistingDir and ExistingFile
149 simply coerce 'Str' and 'ArrayRef' to L<Path::Class> objects.
150
151 These types do rely on I/O.  The case could be made that this makes them not
152 suitable to be called "types".  Consider a file that gets removed after the
153 ExistingFile type is checked.  This can be a source of difficult to find bugs
154 (you've been warned).  Often, you're going to check (either explicitly or implicitly)
155 whether a path exists at the point where you're actually going to use it
156 anyway.  In such cases you may be better off using the Dir or File type and then
157 later (say, in some method) check for existence yourself instead of using these types
158 constraints that you can't really trust to remain true indefinitely.
159
160
161 =item NonExistingDir, NonExistingFile
162
163 Like File and Dir, but the path must not exist on disk
164 when the type is checked.
165
166 At no point will this library attempt to coerce a path into non-existence
167 by removing directories or files.  The coercions for NonExistingDir and NonExistingFile
168 simply coerce 'Str' and 'ArrayRef' to L<Path::Class> objects.
169
170 The same caveats regarding I/O for the Existing* types above apply here as well.
171
172 =item is_$type($value)
173
174 Returns true or false based on whether $value passes the constraint for $type.
175
176 =item to_$type($value)
177
178 Attempts to coerce $value to the given $type.  Returns the coerced value
179 or false if the coercion failed.
180
181 =back
182
183
184 =head1 DEPENDENCIES
185
186 L<Moose>, L<MooseX::Types>, L<Path::Class>
187
188
189 =head1 BUGS AND LIMITATIONS
190
191 If you find a bug please either email the author, or add
192 the bug to cpan-RT L<http://rt.cpan.org>.
193
194
195 =head1 AUTHOR
196
197 Todd Hepler  C<< <thepler@employees.org> >>
198
199
200 =head1 LICENCE AND COPYRIGHT
201
202 Copyright (c) 2007-2009, Todd Hepler C<< <thepler@employees.org> >>.
203
204 This module is free software; you can redistribute it and/or
205 modify it under the same terms as Perl itself. See L<perlartistic>.
206
207