Completed
Pull Request — master (#3)
by Randy
01:20
created

EnsuranceTrait::hasThrowable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Dgame\Ensurance;
4
5
use Dgame\Ensurance\Exception\EnsuranceException;
6
use Throwable;
7
8
/**
9
 * Trait EnsuranceTrait
10
 * @package Dgame\Ensurance
11
 */
12
trait EnsuranceTrait
13
{
14
    /**
15
     * @var mixed
16
     */
17
    private $value;
18
    /**
19
     * @var bool
20
     */
21
    private $ensured = true;
22
    /**
23
     * @var
24
     */
25
    private $throwable;
26
27
    /**
28
     *
29
     */
30
    public function __destruct()
31
    {
32
        if ($this->hasThrowable()) {
33
            throw $this->throwable;
34
        }
35
    }
36
37
    /**
38
     * @param $value
39
     *
40
     * @return mixed
41
     */
42
    final public function then($value)
43
    {
44
        return $this->disregardThrowable()->isEnsured() ? $value : $this->value;
45
    }
46
47
    /**
48
     * @param $value
49
     *
50
     * @return mixed
51
     */
52
    final public function else($value)
0 ignored issues
show
Bug introduced by
Possible parse error: non-abstract method defined as abstract
Loading history...
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
53
    {
54
        return $this->disregardThrowable()->isEnsured() ? $this->value : $value;
55
    }
56
57
    /**
58
     * @param null $default
59
     *
60
     * @return null
61
     */
62
    final public function get($default = null)
63
    {
64
        return $this->value ?? $default;
65
    }
66
67
    /**
68
     * @param bool $condition
69
     *
70
     * @return self
71
     */
72
    final protected function ensure(bool $condition): self
73
    {
74
        $this->ensured = $condition;
75
76
        return $this;
77
    }
78
79
    /**
80
     * @return bool
81
     */
82
    final public function isEnsured(): bool
83
    {
84
        return $this->ensured;
85
    }
86
87
    /**
88
     * @return self
89
     */
90
    final public function disregardThrowable(): self
91
    {
92
        $this->throwable = null;
93
94
        return $this;
95
    }
96
97
    /**
98
     * @return Throwable
99
     */
100
    final public function releaseThrowable(): Throwable
101
    {
102
        try {
103
            return $this->throwable;
104
        } finally {
105
            $this->disregardThrowable();
0 ignored issues
show
Unused Code introduced by
$this->disregardThrowable(); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
106
        }
107
    }
108
109
    /**
110
     * @param EnsuranceInterface $ensurance
111
     *
112
     * @return self
113
     */
114
    final public function transferEnsurance(EnsuranceInterface $ensurance): self
115
    {
116
        $this->value = $ensurance->get();
117
        $this->ensure($ensurance->isEnsured());
118
        if ($ensurance->hasThrowable()) {
119
            $this->setThrowable($ensurance->releaseThrowable());
120
        }
121
122
        return $this;
123
    }
124
125
    /**
126
     * @param string $message
127
     * @param mixed  ...$args
128
     *
129
     * @return self
130
     */
0 ignored issues
show
Documentation introduced by
Consider making the type for parameter $args a bit more specific; maybe use array.
Loading history...
131
    final public function orThrow(string $message, ...$args): self
132
    {
133
        if (!$this->isEnsured()) {
134
            $this->setThrowable(new EnsuranceException(format($message, ...$args), $this->throwable));
135
        }
136
137
        return $this;
138
    }
139
140
    /**
141
     * @return bool
142
     */
143
    final public function hasThrowable(): bool
144
    {
145
        return $this->throwable !== null;
146
    }
147
148
    /**
149
     * @param Throwable $throwable
150
     *
151
     * @return self
152
     */
153
    final public function setThrowable(Throwable $throwable): self
154
    {
155
        if (!$this->isEnsured()) {
156
            $this->throwable = $throwable;
157
        }
158
159
        return $this;
160
    }
161
162
    /**
163
     * @return Throwable
164
     */
165
    final public function getThrowable(): Throwable
166
    {
167
        return $this->throwable;
168
    }
169
}