Completed
Push — master ( a6feea...7247a2 )
by Stéphane
06:46
created

ReactPromiseAdapter::setLoop()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1
Metric Value
dl 0
loc 5
rs 9.4286
ccs 3
cts 3
cp 1
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 React\Promise\PromiseInterface as ReactPromise;
7
use Http\Client\Exception;
8
use Http\Promise\Promise;
9
use Psr\Http\Message\ResponseInterface;
10
11
/**
12
 * React promise adapter implementation
13
 * @author Stéphane Hulard <[email protected]>
14
 */
15
class ReactPromiseAdapter implements Promise
16
{
17
    /**
18
     * Promise status
19
     * @var string
20
     */
21
    private $state = Promise::PENDING;
22
23
    /**
24
     * Adapted React promise
25
     * @var ReactPromise
26
     */
27
    private $promise;
28
29
    /**
30
     * PSR7 received response
31
     * @var ResponseInterface
32
     */
33
    private $response;
34
35
    /**
36
     * Execution error
37
     * @var Exception
38
     */
39
    private $exception;
40
41
    /**
42
     * React Event Loop used for synchronous processing
43
     * @var LoopInterface
44
     */
45
    private $loop;
46
47
    /**
48
     * Initialize the promise
49
     * @param ReactPromise $promise
50
     */
51 108
    public function __construct(ReactPromise $promise)
52
    {
53 108
        $promise->then(
54
            function (ResponseInterface $response) {
55 105
                $this->state = Promise::FULFILLED;
56 105
                $this->response = $response;
57 108
            },
58
            function (Exception $error) {
59 3
                $this->state = Promise::REJECTED;
60 3
                $this->exception = $error;
61 3
            }
62 108
        );
63 108
        $this->promise = $promise;
64 108
    }
65
66
    /**
67
     * Allow to apply callable when the promise resolve
68
     * @param  callable|null $onFulfilled
69
     * @param  callable|null $onRejected
70
     * @return ReactPromiseAdapter
71
     */
72 55
    public function then(callable $onFulfilled = null, callable $onRejected = null)
73
    {
74
        $this->promise->then(function () use ($onFulfilled) {
75 53
            if (null !== $onFulfilled) {
76 53
                call_user_func($onFulfilled, $this->response);
77 53
            }
78 55
        }, function () use ($onRejected) {
79 2
            if (null !== $onRejected) {
80 2
                call_user_func($onRejected, $this->exception);
81
            }
82 55
        });
83 55
        return $this;
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89 108
    public function getState()
90
    {
91 108
        return $this->state;
92
    }
93
94
    /**
95
     * Set EventLoop used for synchronous processing
96
     * @param LoopInterface $loop
97
     * @return ReactPromiseAdapter
98
     */
99 108
    public function setLoop(LoopInterface $loop)
100
    {
101 108
        $this->loop = $loop;
102 108
        return $this;
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108 108
    public function wait($unwrap = true)
109
    {
110 108
        if (null === $this->loop) {
111
            throw new \LogicException("You must set the loop before wait!");
112
        }
113 108
        while (Promise::PENDING === $this->getState()) {
114 108
            $this->loop->tick();
115 108
        }
116
117 108
        if ($unwrap) {
118 105
            if (Promise::REJECTED == $this->getState()) {
119 1
                throw $this->exception;
120
            }
121
122 104
            return $this->response;
123
        }
124 3
    }
125
}
126