Optional   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 170
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 27
c 2
b 0
f 0
dl 0
loc 170
ccs 43
cts 43
cp 1
rs 10
wmc 20

17 Methods

Rating   Name   Duplication   Size   Complexity  
A __isset() 0 3 1
A map() 0 3 1
A nullable() 0 7 2
A __get() 0 3 1
A orThrows() 0 3 1
A apply() 0 3 1
A __construct() 0 3 1
A filter() 0 7 2
A __call() 0 3 1
A __set() 0 3 1
A empty() 0 3 1
A orSupply() 0 3 1
A present() 0 3 1
A or() 0 3 1
A of() 0 7 2
A get() 0 3 1
A stream() 0 3 1
1
<?php
2
3
namespace Bdf\Collection\Util;
4
5
use Bdf\Collection\Stream\SingletonStream;
6
use Bdf\Collection\Stream\StreamInterface;
7
use RuntimeException;
8
use TypeError;
9
10
/**
11
 * Handle null values, and create simple null objects
12
 *
13
 * <code>
14
 * Optional::nullable($input)
15
 *     ->map(function ($e) { // Transform $e })
16
 *     ->or($defaultValue)
17
 * ;
18
 * </code>
19
 *
20
 * @template T
21
 * @implements OptionalInterface<T>
22
 */
23
final class Optional implements OptionalInterface
24
{
25
    /**
26
     * @var T
0 ignored issues
show
Bug introduced by
The type Bdf\Collection\Util\T was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
27
     */
28
    private $value;
29
30
    /**
31
     * Optional constructor.
32
     *
33
     * @param T $value
34
     */
35 22
    private function __construct($value)
36
    {
37 22
        $this->value = $value;
38 22
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43 1
    public function filter(callable $predicate): OptionalInterface
44
    {
45 1
        if (!$predicate($this->value)) {
46 1
            return self::empty();
47
        }
48
49 1
        return $this;
50
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55 1
    public function map(callable $transformer): OptionalInterface
56
    {
57 1
        return self::nullable($transformer($this->value));
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63 2
    public function apply(callable $consumer): void
64
    {
65 2
        $consumer($this->value);
66 2
    }
67
68
    /**
69
     * {@inheritdoc}
70
     */
71 1
    public function or($value)
72
    {
73 1
        return $this->value;
74
    }
75
76
    /**
77
     * {@inheritdoc}
78
     */
79 1
    public function orSupply(callable $supplier)
80
    {
81 1
        return $this->value;
82
    }
83
84
    /**
85
     * {@inheritdoc}
86
     */
87 1
    public function orThrows($exception = RuntimeException::class)
88
    {
89 1
        return $this->value;
90
    }
91
92
    /**
93
     * {@inheritdoc}
94
     */
95 2
    public function present(): bool
96
    {
97 2
        return true;
98
    }
99
100
    /**
101
     * {@inheritdoc}
102
     */
103 3
    public function get()
104
    {
105 3
        return $this->value;
106
    }
107
108
    /**
109
     * {@inheritdoc}
110
     */
111 1
    public function __call(string $name, array $arguments): OptionalInterface
112
    {
113 1
        return self::nullable($this->value->$name(...$arguments));
114
    }
115
116
    /**
117
     * {@inheritdoc}
118
     */
119 1
    public function __get(string $name): OptionalInterface
120
    {
121 1
        return self::nullable($this->value->$name);
122
    }
123
124
    /**
125
     * {@inheritdoc}
126
     */
127 1
    public function __isset(string $name): bool
128
    {
129 1
        return isset($this->value->$name);
130
    }
131
132
    /**
133
     * {@inheritdoc}
134
     */
135 1
    public function __set(string $name, $value): void
136
    {
137 1
        $this->value->$name = $value;
138 1
    }
139
140
    /**
141
     * {@inheritdoc}
142
     */
143 1
    public function stream(): StreamInterface
144
    {
145 1
        return new SingletonStream($this->value);
146
    }
147
148
    /**
149
     * Wrap a nullable value into an Optional
150
     * If the value is null, an empty optional is returned
151
     *
152
     * @param mixed $value
153
     *
154
     * @return OptionalInterface
155
     */
156 16
    public static function nullable($value): OptionalInterface
157
    {
158 16
        if ($value === null) {
159 3
            return self::empty();
160
        }
161
162 16
        return new self($value);
163
    }
164
165
    /**
166
     * Get an empty Optional instance
167
     *
168
     * @return EmptyOptional
169
     */
170 18
    public static function empty(): EmptyOptional
171
    {
172 18
        return EmptyOptional::instance();
173
    }
174
175
    /**
176
     * Wrap value into an optional
177
     * The value MUST not be null
178
     *
179
     * @param R $value
0 ignored issues
show
Bug introduced by
The type Bdf\Collection\Util\R was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
180
     *
181
     * @return Optional<R>
182
     * @throws TypeError If null value is given
183
     *
184
     * @template R
185
     */
186 22
    public static function of($value): Optional
187
    {
188 22
        if ($value === null) {
189 1
            throw new TypeError('The value should not be null');
190
        }
191
192 21
        return new Optional($value);
193
    }
194
}
195