Failed Conditions
Pull Request — master (#551)
by Jáchym
10:59
created

AmpPromiseAdapter::then()   A

Complexity

Conditions 5
Paths 1

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 5.0909

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 13
c 1
b 0
f 0
dl 0
loc 20
ccs 11
cts 13
cp 0.8462
rs 9.5222
cc 5
nc 1
nop 3
crap 5.0909
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GraphQL\Executor\Promise\Adapter;
6
7
use Amp\Deferred;
8
use Amp\Failure;
9
use Amp\Promise as AmpPromise;
10
use Amp\Success;
11
use GraphQL\Executor\Promise\Promise;
12
use GraphQL\Executor\Promise\PromiseAdapter;
13
use Throwable;
14
use function Amp\Promise\all;
15
use function array_replace;
16
17
class AmpPromiseAdapter implements PromiseAdapter
18
{
19
    /**
20
     * @inheritdoc
21
     */
22 1
    public function isThenable($value) : bool
23
    {
24 1
        return $value instanceof AmpPromise;
25
    }
26
27
    /**
28
     * @inheritdoc
29
     */
30 2
    public function convertThenable($thenable) : Promise
31
    {
32 2
        return new Promise($thenable, $this);
33
    }
34
35
    /**
36
     * @inheritdoc
37
     */
38 6
    public function then(Promise $promise, ?callable $onFulfilled = null, ?callable $onRejected = null) : Promise
39
    {
40 6
        $deferred = new Deferred();
41
        $onResolve = static function (?Throwable $reason, $value) use ($onFulfilled, $onRejected, $deferred) : void {
42 6
            if ($reason === null && $onFulfilled !== null) {
43 5
                self::resolveWithCallable($deferred, $onFulfilled, $value);
44 1
            } elseif ($reason === null) {
45
                $deferred->resolve($value);
46 1
            } elseif ($onRejected !== null) {
47 1
                self::resolveWithCallable($deferred, $onRejected, $reason);
48
            } else {
49
                $deferred->fail($reason);
50
            }
51 6
        };
52
53
        /** @var AmpPromise $adoptedPromise */
54 6
        $adoptedPromise = $promise->adoptedPromise;
55 6
        $adoptedPromise->onResolve($onResolve);
56
57 6
        return new Promise($deferred->promise(), $this);
58
    }
59
60
    /**
61
     * @inheritdoc
62
     */
63 1
    public function create(callable $resolver) : Promise
64
    {
65 1
        $deferred = new Deferred();
66
67 1
        $resolver(
68
            static function ($value) use ($deferred) : void {
69 1
                $deferred->resolve($value);
70 1
            },
71
            static function (Throwable $exception) use ($deferred) : void {
72
                $deferred->fail($exception);
73 1
            }
74
        );
75
76 1
        return new Promise($deferred->promise(), $this);
77
    }
78
79
    /**
80
     * @inheritdoc
81
     */
82 1
    public function createFulfilled($value = null) : Promise
83
    {
84 1
        $promise = new Success($value);
85
86 1
        return new Promise($promise, $this);
87
    }
88
89
    /**
90
     * @inheritdoc
91
     */
92 1
    public function createRejected($reason) : Promise
93
    {
94 1
        $promise = new Failure($reason);
95
96 1
        return new Promise($promise, $this);
97
    }
98
99
    /**
100
     * @inheritdoc
101
     */
102 2
    public function all(array $promisesOrValues) : Promise
103
    {
104
        /** @var AmpPromise[] $promises */
105 2
        $promises = [];
106 2
        foreach ($promisesOrValues as $key => $item) {
107 2
            if ($item instanceof Promise) {
108
                $promises[$key] = $item->adoptedPromise;
109 2
            } elseif ($item instanceof AmpPromise) {
110 2
                $promises[$key] = $item;
111
            }
112
        }
113
114 2
        $deferred = new Deferred();
115
116
        $onResolve = static function (?Throwable $reason, ?array $values) use ($promisesOrValues, $deferred) : void {
117 2
            if ($reason) {
118
                $deferred->fail($reason);
119
120
                return;
121
            }
122
123 2
            $deferred->resolve(array_replace($promisesOrValues, $values));
124 2
        };
125
126 2
        all($promises)->onResolve($onResolve);
127
128 2
        return new Promise($deferred->promise(), $this);
129
    }
130
131 6
    private static function resolveWithCallable(Deferred $deferred, callable $callback, $argument) : void
132
    {
133
        try {
134 6
            $result = $callback($argument);
135
        } catch (Throwable $exception) {
136
            $deferred->fail($exception);
137
138
            return;
139
        }
140
141 6
        if ($result instanceof Promise) {
142
            $result = $result->adoptedPromise;
143
        }
144
145 6
        $deferred->resolve($result);
146 6
    }
147
}
148