Completed
Pull Request — master (#23)
by Joel
05:03
created

Promise::setLoop()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Http\Adapter\React;
4
5
use React\EventLoop\LoopInterface;
6
use Http\Client\Exception;
7
use Http\Promise\Promise as HttpPromise;
8
use Psr\Http\Message\ResponseInterface;
9
10
/**
11
 * React promise adapter implementation.
12
 *
13
 * @author Stéphane Hulard <[email protected]>
14
 *
15
 * @internal
16
 */
17
class Promise implements HttpPromise
18
{
19
    /**
20
     * Promise status.
21
     *
22
     * @var string
23
     */
24
    private $state = HttpPromise::PENDING;
25
26
    /**
27
     * PSR7 received response.
28
     *
29
     * @var ResponseInterface
30
     */
31
    private $response;
32
33
    /**
34
     * Execution error.
35
     *
36
     * @var Exception
37
     */
38
    private $exception;
39
40
    /**
41
     * @var callable|null
42
     */
43
    private $onFulfilled;
44
45
    /**
46
     * @var callable|null
47
     */
48
    private $onRejected;
49
50
    /**
51
     * React Event Loop used for synchronous processing.
52
     *
53
     * @var LoopInterface
54
     */
55
    private $loop;
56
57 109
    public function __construct(LoopInterface $loop)
58
    {
59 109
        $this->loop = $loop;
60 109
    }
61
62
    /**
63
     * Allow to apply callable when the promise resolve.
64
     *
65
     * @param callable|null $onFulfilled
66
     * @param callable|null $onRejected
67
     *
68
     * @return Promise
69
     */
70 56
    public function then(callable $onFulfilled = null, callable $onRejected = null)
71
    {
72 56
        $newPromise = new Promise($this->loop);
73
74
        $onFulfilled = $onFulfilled !== null ? $onFulfilled : function (ResponseInterface $response) {
75 1
            return $response;
76 56
        };
77
78
        $onRejected = $onRejected !== null ? $onRejected : function (Exception $exception) {
79 1
            throw $exception;
80 56
        };
81
82
        $this->onFulfilled = function(ResponseInterface $response) use ($onFulfilled, $newPromise) {
83
            try {
84 54
                $newPromise->resolve($onFulfilled($response));
85 54
            } catch (Exception $exception) {
86
                $newPromise->reject($exception);
87
            }
88 54
        };
89
90 2
        $this->onRejected = function(Exception $exception) use ($onRejected, $newPromise) {
0 ignored issues
show
Unused Code introduced by
The parameter $exception is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
91
            try {
92 2
                $newPromise->resolve($onRejected($exception));
93 2
            } catch (Exception $exception) {
94 2
                $newPromise->reject($exception);
95
            }
96 2
        };
97
98 56
        return $newPromise;
99
    }
100
101
    /**
102
     * Resolve this promise
103
     *
104
     * @param ResponseInterface $response
105
     *
106
     * @internal
107
     */
108 106 View Code Duplication
    public function resolve(ResponseInterface $response)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
109
    {
110 106
        if ($this->state !== HttpPromise::PENDING) {
111
            throw new \RuntimeException('Promise is already resolved');
112
        }
113
114 106
        $this->state = HttpPromise::FULFILLED;
115 106
        $this->response = $response;
116 106
        $onFulfilled = $this->onFulfilled;
117
118 106
        if (null !== $onFulfilled) {
119 54
            $onFulfilled($response);
120 54
        }
121 106
    }
122
123
    /**
124
     * Reject this promise
125
     *
126
     * @param Exception $exception
127
     *
128
     * @internal
129
     */
130 3 View Code Duplication
    public function reject(Exception $exception)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
131
    {
132 3
        if ($this->state !== HttpPromise::PENDING) {
133
            throw new \RuntimeException('Promise is already resolved');
134
        }
135
136 3
        $this->state = HttpPromise::REJECTED;
137 3
        $this->exception = $exception;
138 3
        $onRejected = $this->onRejected;
139
140 3
        if (null !== $onRejected) {
141 2
            $onRejected($exception);
142 2
        }
143 3
    }
144
145
    /**
146
     * {@inheritdoc}
147
     */
148 109
    public function getState()
149
    {
150 109
        return $this->state;
151
    }
152
153
    /**
154
     * {@inheritdoc}
155
     */
156 109
    public function wait($unwrap = true)
157
    {
158 109
        while (HttpPromise::PENDING === $this->getState()) {
159 108
            $this->loop->tick();
160 108
        }
161
162 109
        if ($unwrap) {
163 106
            if (HttpPromise::REJECTED == $this->getState()) {
164 1
                throw $this->exception;
165
            }
166
167 105
            return $this->response;
168
        }
169 3
    }
170
}
171