File Coverage

blib/lib/Type/Libraries.pm
Criterion Covered Total %
statement 36 36 100.0
branch 5 8 62.5
condition 1 3 33.3
subroutine 10 10 100.0
pod 1 1 100.0
total 53 58 91.3


line stmt bran cond sub pod time code
1 5     5   1601254 use 5.008;
  5         17  
  5         208  
2 5     5   29 use strict;
  5         9  
  5         164  
3 5     5   38 use warnings;
  5         7  
  5         314  
4              
5             package Type::Libraries;
6              
7             our $AUTHORITY = 'cpan:TOBYINK';
8             our $VERSION = '0.002';
9              
10 5     5   5096 use Type::Library ();
  5         120656  
  5         123  
11 5     5   5239 use Type::Utils ();
  5         25202  
  5         163  
12 5     5   3822 use Module::Runtime qw(module_notional_filename);
  5         5350  
  5         48  
13              
14             sub import
15             {
16 5     5   61 my ($me, $lib, @args) = @_;
17 5 100       37 return unless $lib;
18            
19 4 50       28 my $shim = $me->_make_class(ref $lib ? @$lib : $lib);
20            
21 4         69 my $import = $shim->can('import');
22 4         23 @_ = ($shim, @args);
23 4         30 goto $import;
24             }
25              
26             my $ident = 0;
27             my %cache;
28              
29             sub _make_class
30             {
31 4     4   11 my ($me, @lib) = @_;
32            
33 4   33     98 my $id = ( $cache{join '|', sort @lib} ||= ++$ident );
34 4         31 my $class = sprintf("%s::__SHIMS__::%04d", $me, $id);
35            
36 4 50       18 unless ($INC{module_notional_filename($class)})
37             {
38 4         178 $INC{module_notional_filename($class)} = __FILE__;
39 4         80 $me->setup_class($class, @lib);
40             }
41            
42 4         29 return $class;
43             }
44              
45             sub setup_class
46             {
47 4     4 1 10 my ($me, $class, @lib) = @_;
48            
49 4 50   4   350 eval qq{
  4         24  
  4         9  
  4         34  
50             package $class;
51             use Type::Library -base;
52             Type::Utils::extends( \@lib );
53             1;
54             } or die($@);
55             }
56              
57             1;
58              
59             __END__
60              
61             =pod
62              
63             =encoding utf-8
64              
65             =head1 NAME
66              
67             Type::Libraries - bundle up multiple type constraint libraries
68              
69             =head1 SYNOPSIS
70              
71             package Contact {
72             use Moo;
73             use MooX::late;
74            
75             use Type::Libraries [qw(
76             Types::Standard
77             MooseX::Types::Common::Numeric
78             MouseX::Types::URI
79             )], qw( ArrayRef NegativeInt PositiveInt Uri );
80            
81             has house_number => (
82             is => 'ro',
83             isa => PositiveInt->plus_coercions(NegativeInt, '-$_'),
84             coerce => 1,
85             );
86            
87             has websites => (
88             is => 'ro',
89             isa => ArrayRef[Uri],
90             coerce => 1,
91             );
92             }
93              
94             =head1 DESCRIPTION
95              
96             Type::Libraries allows you to import type constraints from multiple
97             type constraint libraries in a single C<use> statement.
98              
99             Whatsmore, it wraps type constraints using L<Type::Tiny> to ensure
100             that the imported type constraint keywords will work in L<Moose>-,
101             L<Moo>-, and L<Mouse>-based classes and roles. Yes, that's right: you
102             can use L<MooseX::Types> libraries in L<Moo>; L<MouseX::Types>
103             libraries in L<Moose> and so on.
104              
105             =head2 Using Type::Libraries in classes and roles
106              
107             The example in the L</SYNOPSIS> demonstrates how to use
108             L<Type::Libraries> in your class or role. (The example uses the
109             L<MooX::late> extension for L<Moo> to enable C<< coerce => 1 >> to
110             work. Without this extension, L<Moo> coercions need to be a coderef,
111             but it by no means necessary to use L<MooX::late> if you're using
112             Type::Libraries.)
113              
114             The basic syntax for importing types is:
115              
116             use Type::Libraries \@libraries, @types;
117              
118             For further information, see:
119              
120             =over
121              
122             =item *
123              
124             L<Type::Tiny::Manual::UsingWithMoose>
125              
126             =item *
127              
128             L<Type::Tiny::Manual::UsingWithMoo>
129              
130             =item *
131              
132             L<Type::Tiny::Manual::UsingWithMouse>
133              
134             =item *
135              
136             L<Type::Tiny::Manual::UsingWithOther>
137              
138             =back
139              
140             =head2 Using Type::Libraries to create a union type library
141              
142             You can also use Type::Libraries to create your own type constraint
143             library which is the union of several pre-existing one:
144              
145             package MyTypes {
146             use Type::Libraries;
147             Type::Libraries->setup_class(
148             __PACKAGE__, # me
149             qw(
150             Types::Standard
151             MooseX::Types::Common::Numeric
152             MouseX::Types::URI
153             ),
154             );
155             }
156              
157             Your union type library can then be imported from:
158              
159             use MyTypes qw( ArrayRef NegativeInt PositiveInt Uri );
160              
161             =begin trustme
162              
163             =item setup_class
164              
165             =end trustme
166              
167             =head1 BUGS
168              
169             Please report any bugs to
170             L<http://rt.cpan.org/Dist/Display.html?Queue=Type-Libraries>.
171              
172             =head1 SEE ALSO
173              
174             L<MooseX::Types::Combine> is similar, but only supports
175             L<MooseX::Types> libraries.
176              
177             =head1 AUTHOR
178              
179             Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
180              
181             =head1 COPYRIGHT AND LICENCE
182              
183             This software is copyright (c) 2013 by Toby Inkster.
184              
185             This is free software; you can redistribute it and/or modify it under
186             the same terms as the Perl 5 programming language system itself.
187              
188             =head1 DISCLAIMER OF WARRANTIES
189              
190             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
191             WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
192             MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
193