File Coverage

blib/lib/Catalyst/Plugin/MapComponentDependencies/Utils.pm
Criterion Covered Total %
statement 37 58 63.7
branch 9 12 75.0
condition 4 11 36.3
subroutine 18 27 66.6
pod 5 16 31.2
total 73 124 58.8


line stmt bran cond sub pod time code
1             package Catalyst::Plugin::MapComponentDependencies::Utils;
2              
3 4     4   1598105 use Scalar::Util 'blessed';
  4         5  
  4         266  
4 4     4   18 use Exporter 'import';
  4         6  
  4         88  
5 4     4   2055 use Data::Visitor::Callback;
  4         189156  
  4         2946  
6              
7             our @EXPORT_OK = (qw/FromModel FromView FromController FromComponent FromCode ConfigLoaderSubstitutions/);
8             our %EXPORT_TAGS = (All => \@EXPORT_OK, ALL => \@EXPORT_OK);
9              
10 33     33 0 107 sub model_ns { __PACKAGE__ .'::MODEL' }
11 31     31 0 66 sub view_ns { __PACKAGE__ .'::VIEW' }
12 31     31 0 56 sub controller_ns { __PACKAGE__ .'::CONTROLLER' }
13 31     31 0 52 sub component_ns { __PACKAGE__ .'::COMPONENT' }
14 32     32 0 78 sub code_ns { __PACKAGE__ .'::CODE' }
15              
16             sub _is {
17 156     156   169 my ($possible, $target_ns) = @_;
18 156 100 100     998 return (defined($possible) and
19             blessed($possible) and
20             $possible->isa($target_ns)) ?
21             $$possible : 0;
22             }
23              
24 32     32 0 78 sub is_model($) { return _is(shift, model_ns) }
25 31     31 0 52 sub is_view($) { return _is(shift, view_ns) }
26 31     31 0 62 sub is_controller($) { return _is(shift, controller_ns) }
27 31     31 0 65 sub is_component($) { return _is(shift, component_ns) }
28 31     31 0 59 sub is_code($) { return _is(shift, code_ns) }
29              
30 1     1 1 34705 sub FromModel($) { my $v = shift; return bless \$v, model_ns }
  1         7  
31 0     0 1 0 sub FromView($) { my $v = shift; return bless \$v, view_ns }
  0         0  
32 0     0 1 0 sub FromController($) { my $v = shift; return bless \$v, controller_ns }
  0         0  
33 0     0 0 0 sub FromComponent($) { my $v = shift; return bless \$v, component_ns }
  0         0  
34 1     1 1 3 sub FromCode(&) { my $v = shift; return bless \$v, code_ns }
  1         5  
35              
36             sub _expand_config {
37 12     12   23 my ($app_or_ctx, $component_name, $config) = @_;
38             my $visitor_cb = sub {
39 32     32   10540 my ( $visitor, $data ) = @_;
40              
41 32 100 50     71 if(my $m = is_model $data ) { return $_ = $app_or_ctx->model($m) || die "$m is not a Model" }
  1         15  
42 31 50 0     67 if(my $v = is_view $data ) { return $_ = $app_or_ctx->view($v) || die "$v is not a View" }
  0         0  
43 31 50 0     63 if(my $c = is_controller $data ) { return $_ = $app_or_ctx->controller($c) || die "$c is not a Controller" }
  0         0  
44 31 50 0     64 if(my $c = is_component $data ) { return $_ = $app_or_ctx->component($c) || die "$c is not a Component" }
  0         0  
45 31 100       55 if(my $c = is_code $data ) { return $_ = $c->($app_or_ctx, $component_name, $config) }
  1         9  
46              
47 30         90 return $data;
48 12         112 };
49              
50 12         481 Data::Visitor::Callback->new(visit => $visitor_cb)
51             ->visit($config);
52             }
53              
54             sub ConfigLoaderSubstitutions {
55             return (
56 0     0     FromModel => sub { my $c = shift; FromModel(@_) },
  0            
57 0     0     FromView => sub { my $c = shift; FromView(@_) },
  0            
58 0     0     FromController => sub { my $c = shift; FromController(@_) },
  0            
59 0     0     FromComponent => sub { my $c = shift; FromComponent(@_) },
  0            
60             FromCode => sub {
61 0     0     my $c = shift;
62 0           FromCode { eval shift };
  0            
63             },
64 0     0 1   );
65             }
66              
67             1;
68              
69             =head1 NAME
70              
71             Catalyst::Plugin::MapComponentDependencies::Utils - Utilities to integrate dependencies
72              
73             =head1 SYNOPSIS
74              
75             package MyApp;
76              
77             use Moose;
78             use Catalyst 'MapComponentDependencies;
79             use Catalyst::Plugin::MapComponentDependencies::Utils ':All';
80              
81             MyApp->config(
82             'Model::Bar' => { key => 'value' },
83             'Model::Foo' => {
84             bar => FromModel 'Bar',
85             baz => FromCode {
86             my ($app_or_ctx, $component_name) = @_;
87             return ...;
88             },
89             another_param => 'value',
90             },
91             );
92              
93             MyApp->setup;
94              
95             =head1 DESCRIPTION
96              
97             Utility functions to streamline integration of dynamic dependencies into your
98             global L<Catalyst> configuration.
99              
100             L<Catalyst::Plugin::MapComponentDependencies> offers a simple way to specify
101             configuration values for you components to be the value of other components
102             and to do so in a way that respects if your component does ACCEPT_CONTEXT.
103             We do this by providing a new namespace key in your configuration. However
104             you may prefer a 'flatter' configuration. These utility methods allow you to
105             'tag' a value in your configuration. This leads to a more simple configuration
106             setup, but it has the downside in that you must either use a Perl configuration
107             (as in the SYNOPSIS example) or if you are using L<Catalyst::Plugin::ConfigLoader>
108             you can install additional configuration substitutions like so:
109              
110             use Catalyst::Plugin::MapComponentDependencies::Utils ':All';
111              
112             __PACKAGE__->config->{ 'Plugin::ConfigLoader' }
113             ->{ substitutions } = { ConfigLoaderSubstitutions };
114              
115             See L<Catalyst::Plugin::MapComponentDependencies> for other options to declare
116             your component dependencies if this approach does not appeal.
117              
118             =head1 EXPORTS
119              
120             This package exports the following functions
121              
122             =head2 FromModel
123              
124             Creates a dependency to the named model.
125              
126             =head2 FromView
127              
128             Creates a dependency to the named model.
129              
130             =head2 FromController
131              
132             Creates a dependency to the named controller.
133              
134             =head2 FromCode
135              
136             An anonymouse coderef that must return the expected dependency.
137              
138             =head2 ConfigLoaderSubstitutions
139              
140             Returns a Hash suitable for use as additional substitutions in
141             L<Catalyst::Plugin::ConfigLoader>.
142              
143             =head1 SEE ALSO
144              
145             L<Catalyst>, L<Catalyst::Plugin::MapComponentDependencies>,
146             L<Catalyst::Plugin::ConfigLoader>.
147              
148             =head1 AUTHOR
149            
150             John Napiorkowski L<email:jjnapiork@cpan.org>
151            
152             =head1 COPYRIGHT & LICENSE
153            
154             Copyright 2015, John Napiorkowski L<email:jjnapiork@cpan.org>
155            
156             This library is free software; you can redistribute it and/or modify it under
157             the same terms as Perl itself.
158              
159             =cut