Make formatting more like the rest of the code
[gitmo/MooseX-Types.git] / lib / MooseX / Types / Combine.pm
1 package MooseX::Types::Combine;
2
3 # ABSTRACT: Combine type libraries for exporting
4
5 use strict;
6 use warnings;
7 use Class::MOP ();
8
9 =head1 SYNOPSIS
10
11     package CombinedTypeLib;
12
13     use base 'MooseX::Types::Combine';
14
15     __PACKAGE__->provide_types_from(qw/TypeLib1 TypeLib2/);
16
17     package UserClass;
18
19     use CombinedTypeLib qw/Type1 Type2 ... /;
20
21 =head1 DESCRIPTION
22
23 Allows you to export types from multiple type libraries. 
24
25 Libraries on the right side of the type libs passed to L</provide_types_from>
26 take precedence over those on the left in case of conflicts.
27
28 =cut
29
30 sub import {
31     my ($class, @types) = @_;
32     my $caller = caller;
33
34     my %types = $class->_provided_types;
35
36     if ( grep { $_ eq ':all' } @types ) {
37         $_->import( { -into => $caller }, q{:all} )
38             for $class->provide_types_from;
39         return;
40     }
41
42     my %from;
43     for my $type (@types) {
44         unless ($types{$type}) {
45             my @type_libs = $class->provide_types_from;
46
47             die
48                 "$caller asked for a type ($type) which is not found in any of the"
49                 . " type libraries (@type_libs) combined by $class\n";
50         }
51
52         push @{ $from{ $types{$type} } }, $type;
53     }
54
55     $_->import({ -into => $caller }, @{ $from{ $_ } })
56         for keys %from;
57 }
58
59 =head1 CLASS METHODS
60
61 =head2 provide_types_from
62
63 Sets or returns a list of type libraries to re-export from.
64
65 =cut
66
67 sub provide_types_from {
68     my ($class, @libs) = @_;
69
70     my $store =
71      do { no strict 'refs'; \@{ "${class}::__MOOSEX_TYPELIBRARY_LIBRARIES" } };
72
73     if (@libs) {
74         $class->_check_type_lib($_) for @libs;
75         @$store = @libs;
76
77         my %types = map {
78             my $lib = $_;
79             map +( $_ => $lib ), $lib->type_names
80         } @libs;
81
82         $class->_provided_types(%types);
83     }
84
85     @$store;
86 }
87
88 sub _check_type_lib {
89     my ($class, $lib) = @_;
90
91     Class::MOP::load_class($lib);
92
93     die "Cannot use $lib in a combined type library, it does not provide any types"
94         unless $lib->can('type_names');
95 }
96
97 sub _provided_types {
98     my ($class, %types) = @_;
99
100     my $types =
101      do { no strict 'refs'; \%{ "${class}::__MOOSEX_TYPELIBRARY_TYPES" } };
102
103     %$types = %types
104         if keys %types;
105
106     %$types;
107 }
108
109 =head1 SEE ALSO
110
111 L<MooseX::Types>
112
113 =head1 LICENSE
114
115 This program is free software; you can redistribute it and/or modify
116 it under the same terms as perl itself.
117
118 =cut
119
120 1;