File Coverage

blib/lib/MooseX/Types/Base.pm
Criterion Covered Total %
statement 98 98 100.0
branch 20 26 76.9
condition 9 11 81.8
subroutine 23 23 100.0
pod 11 11 100.0
total 161 169 95.2


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