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