Test Failed
Push — master ( 33bfdc...47f867 )
by Kirill
02:32
created

Deferred   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 0

Importance

Changes 0
Metric Value
dl 0
loc 110
rs 10
c 0
b 0
f 0
wmc 11
lcom 2
cbo 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 2
A getOffset() 0 4 1
A definedIn() 0 6 1
A getContext() 0 4 1
A then() 0 6 1
A __invoke() 0 4 1
A invoke() 0 12 2
A response() 0 10 2
1
<?php
2
/**
3
 * This file is part of Railt package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace Railt\SDL\Frontend\Deferred;
11
12
use Railt\SDL\Frontend\Context\ContextInterface;
13
14
/**
15
 * Class Deferred
16
 */
17
class Deferred implements DeferredInterface
18
{
19
    /**
20
     * @var \Closure[]
21
     */
22
    private $then = [];
23
24
    /**
25
     * @var ContextInterface
26
     */
27
    private $ctx;
28
29
    /**
30
     * @var int
31
     */
32
    private $offset = 0;
33
34
    /**
35
     * Deferred constructor.
36
     * @param ContextInterface $ctx
37
     * @param \Closure $then
38
     */
39
    public function __construct(ContextInterface $ctx, \Closure $then = null)
40
    {
41
        $this->ctx = $ctx;
42
43
        if ($then) {
44
            $this->then($then);
45
        }
46
    }
47
48
    /**
49
     * @return int
50
     */
51
    public function getOffset(): int
52
    {
53
        return $this->offset;
54
    }
55
56
    /**
57
     * @param int $offset
58
     * @return DeferredInterface
59
     */
60
    public function definedIn(int $offset): DeferredInterface
61
    {
62
        $this->offset = $offset;
63
64
        return $this;
65
    }
66
67
    /**
68
     * @return ContextInterface
69
     */
70
    public function getContext(): ContextInterface
71
    {
72
        return $this->ctx;
73
    }
74
75
    /**
76
     * @param \Closure $then
77
     * @return Deferred|$this
78
     */
79
    public function then(\Closure $then): DeferredInterface
80
    {
81
        $this->then[] = $then;
82
83
        return $this;
84
    }
85
86
    /**
87
     * @param mixed $value
88
     * @return \Generator|mixed|null
89
     */
90
    public function __invoke($value)
91
    {
92
        return $this->invoke($value);
93
    }
94
95
    /**
96
     * @param array $args
97
     * @return \Generator|mixed
98
     */
99
    public function invoke(...$args): \Generator
100
    {
101
        $result = $args[0] ?? null;
102
103
        foreach ($this->then as $callback) {
104
            yield from $output = $this->response($callback($this->ctx, ...$args));
105
106
            $args[0] = $result = $output->getReturn();
107
        }
108
109
        return $result;
110
    }
111
112
    /**
113
     * @param mixed $result
114
     * @return \Generator
115
     */
116
    private function response($result): \Generator
117
    {
118
        if ($result instanceof \Generator) {
119
            yield from $result;
120
121
            return $result->getReturn();
122
        }
123
124
        return $result;
125
    }
126
}
127