File Coverage

blib/lib/Promises.pm
Criterion Covered Total %
statement 44 54 81.4
branch 11 18 61.1
condition 3 5 60.0
subroutine 14 16 87.5
pod 5 5 100.0
total 77 98 78.5


line stmt bran cond sub pod time code
1             package Promises;
2             our $AUTHORITY = 'cpan:YANICK';
3             $Promises::VERSION = '1.04';
4             # ABSTRACT: An implementation of Promises in Perl
5              
6 11     11   501886 use strict;
  11         97  
  11         333  
7 11     11   52 use warnings;
  11         19  
  11         291  
8              
9 11     11   4819 use Promises::Deferred;
  11         23  
  11         802  
10             our $Backend = 'Promises::Deferred';
11              
12             our $WARN_ON_UNHANDLED_REJECT = 0;
13              
14 11         1881 use Sub::Exporter -setup => {
15              
16             collectors => [
17             'backend' => \'_set_backend',
18             'warn_on_unhandled_reject' => \'_set_warn_on_unhandled_reject',
19             ],
20             exports => [qw[
21             deferred resolved rejected
22             collect collect_hash
23             ]]
24 11     11   5750 };
  11         126988  
25              
26             sub _set_warn_on_unhandled_reject {
27 2     2   315 my( undef, $arg ) = @_;
28              
29 2 50       10 if( $WARN_ON_UNHANDLED_REJECT = $arg->[0] ) {
30             # only brings the big guns if asked for
31              
32             *Promises::Deferred::DESTROY = sub {
33              
34 12 50   12   28 return unless $WARN_ON_UNHANDLED_REJECT;
35              
36 12         18 my $self = shift;
37              
38             return unless
39 12 100 100     27 $self->is_rejected and not $self->{_reject_was_handled};
40              
41 4         1268 require Data::Dumper;
42              
43 4         13648 my $dump =
44             Data::Dumper->new([$self->result])->Terse(1)->Dump;
45              
46 4         251 chomp $dump;
47 4         33 $dump =~ s/\n\s*/ /g;
48              
49             warn "Promise's rejection ", $dump,
50             " was not handled",
51 4 100       26 ($self->{_caller} ? ( ' at ', join ' line ', @{$self->{_caller}} ) : ()) , "\n";
  3         26  
52 2         17 };
53             }
54             }
55              
56             sub _set_backend {
57 0     0   0 my ( undef, $arg ) = @_;
58 0 0       0 my $backend = $arg->[0] or return;
59              
60 0 0       0 unless ( $backend =~ s/^\+// ) {
61 0         0 $backend = 'Promises::Deferred::' . $backend;
62             }
63 0         0 require Module::Runtime;
64 0   0     0 $Backend = Module::Runtime::use_module($backend) || return;
65 0         0 return 1;
66              
67             }
68              
69             sub deferred(;&) {
70 29     29 1 2584 my $promise = $Backend->new;
71              
72 29 50       71 if ( my $code = shift ) {
73 0         0 $promise->resolve;
74             return $promise->then(sub{
75 0     0   0 $code->($promise);
76 0         0 });
77             }
78              
79 29         75 return $promise;
80             }
81              
82 14     14 1 171 sub resolved { deferred->resolve(@_) }
83 1     1 1 14 sub rejected { deferred->reject(@_) }
84              
85             sub collect_hash {
86             collect(@_)->then( sub {
87             map {
88 3     3   4 my @values = @$_;
  14         19  
89 14 100       20 die "'collect_hash' promise returned more than one value: [@{[ join ', ', @values ]} ]\n"
  1         9  
90             if @values > 1;
91              
92 13 100       25 @values == 1 ? $values[0] : undef;
93             } @_ })
94 3     3 1 8 }
95              
96             sub collect {
97 8     8 1 24 my @promises = @_;
98              
99 8         18 my $all_done = resolved();
100              
101 8         16 for my $p ( @promises ) {
102 26         33 my @results;
103             $all_done = $all_done->then( sub {
104 26     26   35 @results = @_;
105 26         61 return $p;
106 26     26   87 } )->then(sub{ ( @results, [ @_ ] ) } );
  26         62  
107             }
108              
109 8         50 return $all_done;
110             }
111              
112             1;
113              
114             __END__