File Coverage

lib/Context/Singleton/Frame/DB.pm
Criterion Covered Total %
statement 71 72 98.6
branch 8 10 80.0
condition 10 15 66.6
subroutine 18 19 94.7
pod 0 7 0.0
total 107 123 86.9


line stmt bran cond sub pod time code
1              
2 3     3   22 use strict;
  3         6  
  3         88  
3 3     3   15 use warnings;
  3         5  
  3         76  
4 3     3   16 use feature 'state';
  3         6  
  3         312  
5              
6             package Context::Singleton::Frame::DB;
7              
8             our $VERSION = v1.0.4;
9              
10 3     3   1587 use Class::Load;
  3         51764  
  3         143  
11 3     3   1563 use Module::Pluggable::Object;
  3         24239  
  3         123  
12 3     3   509 use Ref::Util;
  3         1620  
  3         205  
13              
14 3     3   1493 use Context::Singleton::Frame::Builder::Value;
  3         10  
  3         105  
15 3     3   1323 use Context::Singleton::Frame::Builder::Hash;
  3         10  
  3         91  
16 3     3   1308 use Context::Singleton::Frame::Builder::Array;
  3         8  
  3         2310  
17              
18             sub new {
19 37     37 0 79 my ($class) = @_;
20              
21 37         130 my $self = bless {
22             cache => {},
23             plugin => {},
24             }, $class;
25              
26 37         124 $self->contrive ('Class::Load', (
27             value => 'Class::Load',
28             ));
29              
30             $self->contrive ('class_loader', (
31             dep => [ 'Class::Load' ],
32 0     0   0 as => sub { $_[0]->can ('load_class') },
33 37         224 ));
34              
35 37         144 return $self;
36             }
37              
38             sub instance {
39 73     73 0 11954 state $instance = __PACKAGE__->new;
40 73         265 return $instance;
41             }
42              
43             sub _contrive_class_loader {
44 1     1   4 my ($self, $name) = @_;
45              
46 1 50       4 return if exists $self->{cache}{$name};
47              
48 1         105 $self->contrive ($name, (
49             dep => [ 'class_loader' ],
50             as => eval "sub { \$_[0]->(q[$name]) && q[$name] }",
51             ));
52              
53 1         3 return;
54             }
55              
56             sub _guess_builder_class {
57 318     318   541 my ($self, $def) = @_;
58              
59 318 100       693 return 'Context::Singleton::Frame::Builder::Value' if exists $def->{value};
60 244 50       504 return 'Context::Singleton::Frame::Builder::Hash' if Ref::Util::is_hashref ($def->{dep});
61 244         444 return 'Context::Singleton::Frame::Builder::Array'
62             }
63              
64             sub contrive {
65 318     318 0 896 my ($self, $name, %def) = @_;
66              
67 318 100       690 if ($def{class}) {
68 1         4 $self->_contrive_class_loader ($def{class});
69 1   50     6 $def{builder} //= 'new';
70             }
71              
72 318 100 66     1157 if ($def{class} // $def{deduce}) {
73 1   33     6 $def{this} = $def{class} // $def{deduce};
74 1         2 delete $def{class};
75 1         2 delete $def{deduce};
76             }
77              
78 318         638 my $builder_class = $self->_guess_builder_class (\%def);
79 318         1232 my $builder = $builder_class->new (%def);
80              
81 318         568 push @{ $self->{cache}{ $name } }, $builder;
  318         980  
82              
83 318         935 return;
84             }
85              
86             sub trigger {
87 34     34 0 86 my ($self, $name, $code) = @_;
88              
89 34         54 push @{ $self->{trigger}{ $name } }, $code;
  34         121  
90              
91 34         90 return;
92             }
93              
94             sub find_builder_for {
95 95     95 0 246 my ($self, $name) = @_;
96              
97 95   100     161 return @{ $self->{cache}{ $name } // [] };
  95         464  
98             }
99              
100             sub find_trigger_for {
101 30     30 0 62 my ($self, $name) = @_;
102              
103 30   100     40 return @{ $self->{trigger}{ $name } // [] };
  30         181  
104             }
105              
106             sub load_rules {
107 6     6 0 21 my ($self, @packages) = @_;
108              
109 6         12 for my $package (@packages) {
110 6   66     24 $self->{plugins}{ $package } //= do {
111 5         40 Module::Pluggable::Object->new (
112             require => 1,
113             search_path => [ $package ],
114             )->plugins;
115 5         8321 1;
116             };
117             }
118              
119 6         2562 return;
120             }
121              
122             1;