File Coverage

blib/lib/MooseX/Types/Base.pm
Criterion Covered Total %
statement 95 95 100.0
branch 20 26 76.9
condition 10 11 90.9
subroutine 22 22 100.0
pod 11 11 100.0
total 158 165 95.7


line stmt bran cond sub pod time code
1             package MooseX::Types::Base;
2             # ABSTRACT: Type library base class
3              
4             our $VERSION = '0.51';
5              
6 18     18   172 use Carp::Clan qw( ^MooseX::Types );
  18         39  
  18         135  
7 18     18   1904 use Sub::Exporter qw( build_exporter );
  18         33  
  18         213  
8 18     18   6061 use Moose::Util::TypeConstraints qw( find_type_constraint );
  18         60  
  18         192  
9              
10 18     18   8791 use namespace::autoclean;
  18         38  
  18         116  
11              
12             #pod =head1 DESCRIPTION
13             #pod
14             #pod You normally won't need to interact with this class by yourself. It is
15             #pod merely a collection of functionality that type libraries need to
16             #pod interact with moose and the rest of the L<MooseX::Types> module.
17             #pod
18             #pod =cut
19              
20             my $UndefMsg = q{Unable to find type '%s' in library '%s'};
21              
22             #pod =head1 METHODS
23             #pod
24             #pod =cut
25              
26             #pod =head2 import
27             #pod
28             #pod Provides the import mechanism for your library. See
29             #pod L<MooseX::Types/"LIBRARY USAGE"> for syntax details on this.
30             #pod
31             #pod =cut
32              
33             sub import {
34 62     62   174080 my ($class, @args) = @_;
35              
36             # filter or create options hash for S:E
37 62 100 66     434 my $options = (@args and (ref($args[0]) eq 'HASH')) ? $args[0] : undef;
38              
39             # preserve additional options, to ensure types are installed into the type library's namespace
40 62 100       103 my %ex_spec = %{ $options || {} };
  62         323  
41 62         219 delete @ex_spec{ qw(-wrapper -into -full) };
42              
43 62 100       159 unless ($options) {
44 33         63 $options = {};
45 33         87 unshift @args, $options;
46             }
47              
48             # all types known to us
49 62         295 my @types = $class->type_names;
50              
51             # determine the wrapper, -into is supported for compatibility reasons
52 62   100     280 my $wrapper = $options->{ -wrapper } || 'MooseX::Types';
53              
54             $args[0]->{into} = $options->{ -into }
55 62 100       240 if exists $options->{ -into };
56              
57 62         110 my %ex_util;
58              
59             TYPE:
60 62         193 for my $type_short (@types) {
61              
62             # find type name and object, create undefined message
63 667 50       29432 my $type_full = $class->get_type($type_short)
64             or croak "No fully qualified type name stored for '$type_short'";
65 667         1721 my $type_cons = find_type_constraint($type_full);
66 667         71280 my $undef_msg = sprintf($UndefMsg, $type_short, $class);
67              
68             # the type itself
69 667         3481 push @{ $ex_spec{exports} },
70             $type_short,
71             sub {
72 168     168   17007 bless $wrapper->type_export_generator($type_short, $type_full),
73             'MooseX::Types::EXPORTED_TYPE_CONSTRAINT';
74 667         999 };
75              
76             # the check helper
77 667         1415 my $check_name = "is_${type_short}";
78 667         2819 push @{ $ex_spec{exports} },
79             $check_name,
80 667     168   894 sub { $wrapper->check_export_generator($type_short, $type_full, $undef_msg) };
  168         5349  
81              
82             # only export coercion helper if full (for libraries) or coercion is defined
83             next TYPE
84             unless $options->{ -full }
85 667 100 100     3192 or ($type_cons and $type_cons->has_coercion);
      100        
86              
87 82         1141 my $coercion_name = "to_${type_short}";
88 82         345 push @{ $ex_spec{exports} },
89             $coercion_name,
90 82     75   130 sub { $wrapper->coercion_export_generator($type_short, $type_full, $undef_msg) };
  75         1962  
91 82         367 $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 62         2243 my $exporter = build_exporter \%ex_spec;
96             $options->{into_level}++
97 62 100       43972 unless $options->{into};
98              
99             # remember requested symbols to determine what helpers to auto-export
100             my %was_requested =
101 144         373 map { ($_ => 1) }
102 62         176 grep { not ref }
  208         413  
103             @args;
104              
105             # determine which additional symbols (helpers) to export along
106 62         127 my %add;
107             EXPORT:
108 62         158 for my $type (grep { exists $was_requested{ $_ } } @types) {
  667         1103  
109             $add{ "is_$type" }++
110 140 50       477 unless $was_requested{ "is_$type" };
111             next EXPORT
112 140 100       422 unless exists $ex_util{ $type }{to};
113             $add{ "to_$type" }++
114 73 50       358 unless $was_requested{ "to_$type" };
115             }
116              
117             # and on to the real exporter
118 62         251 my @new_args = (@args, keys %add);
119 62         208 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 667     667 1 1407 my ($class, $type) = @_;
130              
131             # useful message if the type couldn't be found
132 667 50       1423 croak "Unknown type '$type' in library '$class'"
133             unless $class->has_type($type);
134              
135             # return real name of the type
136 667         1391 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 67     67 1 547484 my ($class) = @_;
147              
148             # return short names of all stored types
149 67         103 return keys %{ $class->type_storage };
  67         204  
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 62     62 1 129 my ($class, $type) = @_;
160              
161             # store type with library prefix as real name
162 62         184 $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 667     667 1 1100 my ($class, $type) = @_;
174              
175             # check if we stored a type under that name
176 667         1537 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 344     344 1 538 my ($class) = @_;
189              
190             # return a reference to the storage in ourself
191 18     18   19387 { no strict 'refs';
  18         44  
  18         1910  
  344         468  
192 344         493 return \%{ $class . '::__MOOSEX_TYPELIBRARY_STORAGE' };
  344         1594  
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 13 my ($class) = @_;
204              
205             {
206 18     18   107 no strict 'refs';
  18         44  
  18         3613  
  6         10  
207 6         11 return \%{ $class . '::__MOOSEX_TYPELIBRARY_CLASS_TYPES' };
  6         157  
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 5106 my ($class, $type) = @_;
219              
220 2 50       14 croak "Not a class_type"
221             unless $type->isa('Moose::Meta::TypeConstraint::Class');
222              
223 2         14 $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 12 my ($class, $name) = @_;
234              
235 4         17 $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 9 my ($class) = @_;
246              
247             {
248 18     18   121 no strict 'refs';
  18         34  
  18         3106  
  3         6  
249 3         4 return \%{ $class . '::__MOOSEX_TYPELIBRARY_ROLE_TYPES' };
  3         269  
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 3287 my ($class, $type) = @_;
261              
262 1 50       7 croak "Not a role_type"
263             unless $type->isa('Moose::Meta::TypeConstraint::Role');
264              
265 1         58 $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 6 my ($class, $name) = @_;
276              
277 2         10 $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.51
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 SUPPORT
367              
368             Bugs may be submitted through L<the RT bug tracker|https://rt.cpan.org/Public/Dist/Display.html?Name=MooseX-Types>
369             (or L<bug-MooseX-Types@rt.cpan.org|mailto:bug-MooseX-Types@rt.cpan.org>).
370              
371             There is also a mailing list available for users of this distribution, at
372             L<http://lists.perl.org/list/moose.html>.
373              
374             There is also an irc channel available for users of this distribution, at
375             L<C<#moose> on C<irc.perl.org>|irc://irc.perl.org/#moose>.
376              
377             =head1 AUTHOR
378              
379             Robert "phaylon" Sedlacek <rs@474.at>
380              
381             =head1 COPYRIGHT AND LICENCE
382              
383             This software is copyright (c) 2007 by Robert "phaylon" Sedlacek.
384              
385             This is free software; you can redistribute it and/or modify it under
386             the same terms as the Perl 5 programming language system itself.
387              
388             =cut