File Coverage

blib/lib/MooseX/Types/Base.pm
Criterion Covered Total %
statement 99 99 100.0
branch 20 26 76.9
condition 9 11 81.8
subroutine 24 24 100.0
pod 11 11 100.0
total 163 171 95.3


line stmt bran cond sub pod time code
1             package MooseX::Types::Base;
2             # ABSTRACT: Type library base class
3              
4             our $VERSION = '0.46';
5              
6 17     17   79 use Moose;
  17         36  
  17         121  
7              
8 17     17   107643 use Carp::Clan qw( ^MooseX::Types );
  17         39  
  17         143  
9 17     17   12996 use MooseX::Types::Util qw( filter_tags );
  17         41  
  17         876  
10 17     17   87 use Sub::Exporter qw( build_exporter );
  17         30  
  17         148  
11 17     17   3257 use Moose::Util::TypeConstraints qw( find_type_constraint );
  17         33  
  17         192  
12              
13 17     17   5921 use namespace::autoclean;
  17         31  
  17         68  
14              
15             #pod =head1 DESCRIPTION
16             #pod
17             #pod You normally won't need to interact with this class by yourself. It is
18             #pod merely a collection of functionality that type libraries need to
19             #pod interact with moose and the rest of the L<MooseX::Types> module.
20             #pod
21             #pod =cut
22              
23             my $UndefMsg = q{Unable to find type '%s' in library '%s'};
24              
25             #pod =head1 METHODS
26             #pod
27             #pod =cut
28              
29             #pod =head2 import
30             #pod
31             #pod Provides the import mechanism for your library. See
32             #pod L<MooseX::Types/"LIBRARY USAGE"> for syntax details on this.
33             #pod
34             #pod =cut
35              
36             sub import {
37 56     56   33255 my ($class, @args) = @_;
38              
39             # filter or create options hash for S:E
40 56 100 66     482 my $options = (@args and (ref($args[0]) eq 'HASH')) ? $args[0] : undef;
41              
42             # preserve additional options, to ensure types are installed into the type library's namespace
43 56 100       97 my %ex_spec = %{ $options || {} };
  56         345  
44 56         183 delete @ex_spec{ qw(-wrapper -into -full) };
45              
46 56 100       158 unless ($options) {
47 31         106 $options = {foo => 23};
48 31         91 unshift @args, $options;
49             }
50              
51             # all types known to us
52 56         289 my @types = $class->type_names;
53              
54             # determine the wrapper, -into is supported for compatibility reasons
55 56   100     379 my $wrapper = $options->{ -wrapper } || 'MooseX::Types';
56              
57             $args[0]->{into} = $options->{ -into }
58 56 100       252 if exists $options->{ -into };
59              
60 56         91 my %ex_util;
61              
62             TYPE:
63 56         176 for my $type_short (@types) {
64              
65             # find type name and object, create undefined message
66 613 50       23474 my $type_full = $class->get_type($type_short)
67             or croak "No fully qualified type name stored for '$type_short'";
68 613         1668 my $type_cons = find_type_constraint($type_full);
69 613         55877 my $undef_msg = sprintf($UndefMsg, $type_short, $class);
70              
71             # the type itself
72 613         2747 push @{ $ex_spec{exports} },
73             $type_short,
74             sub {
75 156     156   12975 bless $wrapper->type_export_generator($type_short, $type_full),
76             'MooseX::Types::EXPORTED_TYPE_CONSTRAINT';
77 613         756 };
78              
79             # the check helper
80 613         2751 push @{ $ex_spec{exports} },
81             "is_${type_short}",
82 613     156   831 sub { $wrapper->check_export_generator($type_short, $type_full, $undef_msg) };
  156         3813  
83              
84             # only export coercion helper if full (for libraries) or coercion is defined
85             next TYPE
86             unless $options->{ -full }
87 613 100 100     3317 or ($type_cons and $type_cons->has_coercion);
      66        
88 74         367 push @{ $ex_spec{exports} },
89             "to_${type_short}",
90 74     69   897 sub { $wrapper->coercion_export_generator($type_short, $type_full, $undef_msg) };
  69         1472  
91 74         275 $ex_util{ $type_short }{to}++; # shortcut to remember this exists
92             }
93              
94             # create S:E exporter and increase export level unless specified explicitly
95 56         1710 my $exporter = build_exporter \%ex_spec;
96             $options->{into_level}++
97 56 100       38076 unless $options->{into};
98              
99             # remember requested symbols to determine what helpers to auto-export
100             my %was_requested =
101 132         293 map { ($_ => 1) }
102 56         111 grep { not ref }
  190         386  
103             @args;
104              
105             # determine which additional symbols (helpers) to export along
106 56         106 my %add;
107             EXPORT:
108 56         124 for my $type (grep { exists $was_requested{ $_ } } @types) {
  613         1036  
109             $add{ "is_$type" }++
110 128 50       421 unless $was_requested{ "is_$type" };
111             next EXPORT
112 128 100       344 unless exists $ex_util{ $type }{to};
113             $add{ "to_$type" }++
114 67 50       252 unless $was_requested{ "to_$type" };
115             }
116              
117             # and on to the real exporter
118 56         208 my @new_args = (@args, keys %add);
119 56         200 return $class->$exporter(@new_args);
120             }
121              
122             #pod =head2 get_type
123             #pod
124             #pod This returns a type from the library's store by its name.
125             #pod
126             #pod =cut
127              
128             sub get_type {
129 613     613 1 1319 my ($class, $type) = @_;
130              
131             # useful message if the type couldn't be found
132 613 50       1293 croak "Unknown type '$type' in library '$class'"
133             unless $class->has_type($type);
134              
135             # return real name of the type
136 613         1616 return $class->type_storage->{ $type };
137             }
138              
139             #pod =head2 type_names
140             #pod
141             #pod Returns a list of all known types by their name.
142             #pod
143             #pod =cut
144              
145             sub type_names {
146 59     59 1 122 my ($class) = @_;
147              
148             # return short names of all stored types
149 59         90 return keys %{ $class->type_storage };
  59         185  
150             }
151              
152             #pod =head2 add_type
153             #pod
154             #pod Adds a new type to the library.
155             #pod
156             #pod =cut
157              
158             sub add_type {
159 56     56 1 108 my ($class, $type) = @_;
160              
161             # store type with library prefix as real name
162 56         264 $class->type_storage->{ $type } = "${class}::${type}";
163             }
164              
165             #pod =head2 has_type
166             #pod
167             #pod Returns true or false depending on if this library knows a type by that
168             #pod name.
169             #pod
170             #pod =cut
171              
172             sub has_type {
173 613     613 1 808 my ($class, $type) = @_;
174              
175             # check if we stored a type under that name
176 613         1543 return ! ! $class->type_storage->{ $type };
177             }
178              
179             #pod =head2 type_storage
180             #pod
181             #pod Returns the library's type storage hash reference. You shouldn't use this
182             #pod method directly unless you know what you are doing. It is not an internal
183             #pod method because overriding it makes virtual libraries very easy.
184             #pod
185             #pod =cut
186              
187             sub type_storage {
188 308     308 1 468 my ($class) = @_;
189              
190             # return a reference to the storage in ourself
191 17     17   13879 { no strict 'refs';
  17         54  
  17         1301  
  308         400  
192 308         355 return \%{ $class . '::__MOOSEX_TYPELIBRARY_STORAGE' };
  308         1726  
193             }
194             }
195              
196             #pod =head2 registered_class_types
197             #pod
198             #pod Returns the class types registered within this library. Don't use directly.
199             #pod
200             #pod =cut
201              
202             sub registered_class_types {
203 6     6 1 10 my ($class) = @_;
204              
205             {
206 17     17   80 no strict 'refs';
  17         43  
  17         2649  
  6         9  
207 6         8 return \%{ $class . '::__MOOSEX_TYPELIBRARY_CLASS_TYPES' };
  6         114  
208             }
209             }
210              
211             #pod =head2 register_class_type
212             #pod
213             #pod Register a C<class_type> for use in this library by class name.
214             #pod
215             #pod =cut
216              
217             sub register_class_type {
218 2     2 1 3844 my ($class, $type) = @_;
219              
220 2 50       15 croak "Not a class_type"
221             unless $type->isa('Moose::Meta::TypeConstraint::Class');
222              
223 2         15 $class->registered_class_types->{$type->class} = $type;
224             }
225              
226             #pod =head2 get_registered_class_type
227             #pod
228             #pod Get a C<class_type> registered in this library by name.
229             #pod
230             #pod =cut
231              
232             sub get_registered_class_type {
233 4     4 1 8 my ($class, $name) = @_;
234              
235 4         18 $class->registered_class_types->{$name};
236             }
237              
238             #pod =head2 registered_role_types
239             #pod
240             #pod Returns the role types registered within this library. Don't use directly.
241             #pod
242             #pod =cut
243              
244             sub registered_role_types {
245 3     3 1 6 my ($class) = @_;
246              
247             {
248 17     17   101 no strict 'refs';
  17         32  
  17         2506  
  3         5  
249 3         5 return \%{ $class . '::__MOOSEX_TYPELIBRARY_ROLE_TYPES' };
  3         281  
250             }
251             }
252              
253             #pod =head2 register_role_type
254             #pod
255             #pod Register a C<role_type> for use in this library by role name.
256             #pod
257             #pod =cut
258              
259             sub register_role_type {
260 1     1 1 1964 my ($class, $type) = @_;
261              
262 1 50       6 croak "Not a role_type"
263             unless $type->isa('Moose::Meta::TypeConstraint::Role');
264              
265 1         6 $class->registered_role_types->{$type->role} = $type;
266             }
267              
268             #pod =head2 get_registered_role_type
269             #pod
270             #pod Get a C<role_type> registered in this library by role name.
271             #pod
272             #pod =cut
273              
274             sub get_registered_role_type {
275 2     2 1 5 my ($class, $name) = @_;
276              
277 2         8 $class->registered_role_types->{$name};
278             }
279              
280             #pod =head1 SEE ALSO
281             #pod
282             #pod L<MooseX::Types::Moose>
283             #pod
284             #pod =cut
285              
286             1;
287              
288             __END__
289              
290             =pod
291              
292             =encoding UTF-8
293              
294             =head1 NAME
295              
296             MooseX::Types::Base - Type library base class
297              
298             =head1 VERSION
299              
300             version 0.46
301              
302             =head1 DESCRIPTION
303              
304             You normally won't need to interact with this class by yourself. It is
305             merely a collection of functionality that type libraries need to
306             interact with moose and the rest of the L<MooseX::Types> module.
307              
308             =head1 METHODS
309              
310             =head2 import
311              
312             Provides the import mechanism for your library. See
313             L<MooseX::Types/"LIBRARY USAGE"> for syntax details on this.
314              
315             =head2 get_type
316              
317             This returns a type from the library's store by its name.
318              
319             =head2 type_names
320              
321             Returns a list of all known types by their name.
322              
323             =head2 add_type
324              
325             Adds a new type to the library.
326              
327             =head2 has_type
328              
329             Returns true or false depending on if this library knows a type by that
330             name.
331              
332             =head2 type_storage
333              
334             Returns the library's type storage hash reference. You shouldn't use this
335             method directly unless you know what you are doing. It is not an internal
336             method because overriding it makes virtual libraries very easy.
337              
338             =head2 registered_class_types
339              
340             Returns the class types registered within this library. Don't use directly.
341              
342             =head2 register_class_type
343              
344             Register a C<class_type> for use in this library by class name.
345              
346             =head2 get_registered_class_type
347              
348             Get a C<class_type> registered in this library by name.
349              
350             =head2 registered_role_types
351              
352             Returns the role types registered within this library. Don't use directly.
353              
354             =head2 register_role_type
355              
356             Register a C<role_type> for use in this library by role name.
357              
358             =head2 get_registered_role_type
359              
360             Get a C<role_type> registered in this library by role name.
361              
362             =head1 SEE ALSO
363              
364             L<MooseX::Types::Moose>
365              
366             =head1 AUTHOR
367              
368             Robert "phaylon" Sedlacek <rs@474.at>
369              
370             =head1 COPYRIGHT AND LICENSE
371              
372             This software is copyright (c) 2007 by Robert "phaylon" Sedlacek.
373              
374             This is free software; you can redistribute it and/or modify it under
375             the same terms as the Perl 5 programming language system itself.
376              
377             =cut