Completed
Push — master ( f895fe...230702 )
by Stéphane
15s queued 11s
created

Promise::getState()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Http\Adapter\React;
4
5
use Http\Adapter\React\Exception\UnexpectedValueException;
6
use Http\Client\Exception as HttplugException;
7
use Http\Promise\Promise as HttpPromise;
8
use Psr\Http\Message\RequestInterface;
9
use Psr\Http\Message\ResponseInterface;
10
use React\EventLoop\LoopInterface;
11
use React\Promise\PromiseInterface;
12
use RuntimeException;
13
14
/**
15
 * React promise adapter implementation.
16
 *
17
 * @author Stéphane Hulard <[email protected]>
18
 *
19
 * @internal
20
 */
21
final class Promise implements HttpPromise
22
{
23
    /**
24
     * Promise status.
25
     *
26
     * @var string
27
     */
28
    private $state = HttpPromise::PENDING;
29
30
    /**
31
     * PSR7 received response.
32
     *
33
     * @var ResponseInterface
34
     */
35
    private $response;
36
37
    /**
38
     * Execution error.
39
     *
40
     * @var Exception
41
     */
42
    private $exception;
43
44
    /**
45
     * HTTP Request.
46
     *
47
     * @var RequestInterface
48
     */
49
    private $request;
50
51
    /**
52
     * Adapted ReactPHP promise.
53
     *
54
     * @var PromiseInterface
55
     */
56
    private $promise;
57
58
    /**
59
     * ReactPHP LoopInterface.
60
     *
61
     * @var LoopInterface
62
     */
63
    private $loop;
64
65 110
    public function __construct(PromiseInterface $promise, LoopInterface $loop, RequestInterface $request)
66
    {
67 110
        $this->state = self::PENDING;
68
69 110
        $this->request = $request;
70 110
        $this->loop = $loop;
71 110
        $this->promise = $promise->then(
72
            function (?ResponseInterface $response): ResponseInterface {
73 102
                $this->response = $response;
74 102
                $this->state = self::FULFILLED;
75
76 102
                return $response;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $response could return the type null which is incompatible with the type-hinted return Psr\Http\Message\ResponseInterface. Consider adding an additional type-check to rule them out.
Loading history...
77 110
            },
78
            /**
79
             * @param mixed $reason
80
             */
81
            function ($reason): void {
82 8
                $this->state = self::REJECTED;
83
84 8
                if ($reason instanceof HttplugException) {
85 4
                    $this->exception = $reason;
0 ignored issues
show
Documentation Bug introduced by
It seems like $reason of type Http\Client\Exception is incompatible with the declared type Http\Adapter\React\Exception of property $exception.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
86 6
                } elseif ($reason instanceof RuntimeException) {
87 4
                    $this->exception = new HttplugException\NetworkException($reason->getMessage(), $this->request, $reason);
88 2
                } elseif ($reason instanceof \Throwable) {
89 1
                    $this->exception = new HttplugException\TransferException('Invalid exception returned from ReactPHP', 0, $reason);
90
                } else {
91 1
                    $this->exception = new UnexpectedValueException('Reason returned from ReactPHP must be an Exception');
92
                }
93
94 8
                throw $this->exception;
95 110
            });
96 110
    }
97
98 54
    public function then(?callable $onFulfilled = null, ?callable $onRejected = null)
99
    {
100 54
        return new self($this->promise->then($onFulfilled, $onRejected), $this->loop, $this->request);
101
    }
102
103
    /**
104
     * {@inheritdoc}
105
     */
106 110
    public function getState()
107
    {
108 110
        return $this->state;
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114 110
    public function wait($unwrap = true)
115
    {
116 110
        $loop = $this->loop;
117 110
        while (HttpPromise::PENDING === $this->getState()) {
118
            $loop->futureTick(function () use ($loop) {
119 104
                $loop->stop();
120 104
            });
121 104
            $loop->run();
122
        }
123
124 110
        if ($unwrap) {
125 107
            if (HttpPromise::REJECTED == $this->getState()) {
126 6
                throw $this->exception;
127
            }
128
129 101
            return $this->response;
130
        }
131 3
    }
132
}
133