Test Failed
Push — master ( b7ab7b...94ee03 )
by Kirill
02:59
created

Name::fromString()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
nc 1
nop 2
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 2
rs 10
c 0
b 0
f 0
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\IR\Type;
11
12
use function Railt\SDL\object_to_string;
13
14
/**
15
 * Class Name
16
 */
17
class Name implements TypeNameInterface, \JsonSerializable, \Countable
18
{
19
    /**
20
     * @var array|string[]
21
     */
22
    private $chunks;
23
24
    /**
25
     * @var int
26
     */
27
    private $size;
28
29
    /**
30
     * @var string|null
31
     */
32
    private $fqn;
33
34
    /**
35
     * @var bool
36
     */
37
    private $global;
38
39
    /**
40
     * TypeName constructor.
41
     * @param array $chunks
42
     * @param bool $global
43
     */
44 120
    public function __construct(array $chunks, bool $global = false)
45
    {
46 120
        $this->chunks = $chunks;
47 120
        $this->global = $global;
48 120
        $this->size = \count($chunks);
49 120
    }
50
51
    /**
52
     * @param string|iterable|TypeNameInterface|null $name
53
     * @param bool|null $global
54
     * @return TypeNameInterface
55
     */
56 120
    public static function new($name, bool $global = null): TypeNameInterface
57
    {
58
        switch (true) {
59 120
            case $name === null || !$name:
60 1
                return static::empty((bool)$global);
61
62 120
            case $name instanceof TypeNameInterface:
63 15
                return $name;
64
65 120
            case \is_array($name):
66 2
                return static::fromArray($name, (bool)$global);
67
68 120
            case \is_iterable($name):
69 2
                return static::fromArray(\iterator_to_array($name, false), (bool)$global);
70
71 120
            case \is_scalar($name):
72 119
                return static::fromString((string)$name, $global);
73
74
            default:
75 1
                $error = 'Unsupported argument type of %s(self|array|iterable|scalar $name = %s)';
76 1
                $given = \is_object($name) ? object_to_string($name) : \gettype($name);
77
78 1
                throw new \InvalidArgumentException(\sprintf($error, __METHOD__, $given));
79
        }
80
    }
81
82
    /**
83
     * @param string|iterable|TypeNameInterface|null $name
84
     * @return bool
85
     */
86 52
    public static function isValid($name): bool
87
    {
88 52
        return $name === null || \is_scalar($name) || \is_iterable($name) || $name instanceof TypeNameInterface;
89
    }
90
91
    /**
92
     * @param array $chunks
93
     * @param bool $global
94
     * @return Name
95
     */
96 5
    public static function fromArray(array $chunks, bool $global = false): TypeNameInterface
97
    {
98 5
        return new static($chunks, $global);
99
    }
100
101
    /**
102
     * @param string $fqn
103
     * @param bool|null $global
104
     * @return TypeNameInterface
105
     */
106 120
    public static function fromString(string $fqn, bool $global = null): TypeNameInterface
107
    {
108 120
        $name = \ltrim($fqn, self::NAMESPACE_SEPARATOR);
109 120
        $chunks = \explode(self::NAMESPACE_SEPARATOR, $name);
110
111 120
        return new static($chunks, \is_bool($global) ? $global : $name !== $fqn);
112
    }
113
114
    /**
115
     * @param bool $global
116
     * @return TypeNameInterface
117
     */
118 3
    public static function empty(bool $global = false): TypeNameInterface
119
    {
120 3
        return new static([], $global);
121
    }
122
123
    /**
124
     * @return \Traversable
125
     */
126 1
    public function getIterator(): \Traversable
127
    {
128 1
        return new \ArrayIterator($this->chunks);
129
    }
130
131
    /**
132
     * @return bool
133
     */
134 66
    public function isGlobal(): bool
135
    {
136 66
        return $this->global;
137
    }
138
139
    /**
140
     * @return TypeNameInterface
141
     */
142 1
    public function lock(): TypeNameInterface
143
    {
144 1
        $this->global = true;
145
146 1
        return $this;
147
    }
148
149
    /**
150
     * @return TypeNameInterface
151
     */
152 1
    public function unlock(): TypeNameInterface
153
    {
154 1
        $this->global = false;
155
156 1
        return $this;
157
    }
158
159
    /**
160
     * @return string
161
     */
162 14
    public function getName(): string
163
    {
164 14
        return $this->size > 0 ? $this->chunks[$this->size - 1] : '';
165
    }
166
167
    /**
168
     * @param string|iterable|TypeNameInterface|null $prefix
169
     * @return TypeNameInterface
170
     */
171 66
    public function in($prefix): TypeNameInterface
172
    {
173 66
        if ($this->global) {
174 59
            return clone $this;
175
        }
176
177 8
        return new static(\array_merge(self::new($prefix)->getChunks(), $this->getChunks()));
178
    }
179
180
    /**
181
     * @param string|iterable|TypeNameInterface|null $suffix
182
     * @return TypeNameInterface
183
     */
184 1
    public function append($suffix): TypeNameInterface
185
    {
186 1
        return self::new($suffix)->in($this);
187
    }
188
189
    /**
190
     * @return array|string[]
191
     */
192 8
    public function getChunks(): array
193
    {
194 8
        return $this->chunks;
195
    }
196
197
    /**
198
     * @return string
199
     */
200 1
    public function __toString(): string
201
    {
202 1
        return $this->getFullyQualifiedName();
203
    }
204
205
    /**
206
     * @return array
207
     */
208
    public function __debugInfo(): array
209
    {
210
        return [
211
            'name' => $this->getFullyQualifiedName(),
212
            'root' => $this->global
213
        ];
214
    }
215
216
    /**
217
     * @return string
218
     */
219 169
    public function getFullyQualifiedName(): string
220
    {
221 169
        if ($this->fqn === null) {
222 84
            $this->fqn = \implode(static::NAMESPACE_SEPARATOR, $this->chunks);
223
        }
224
225 169
        return $this->fqn;
226
    }
227
228
    /**
229
     * @param string|iterable|TypeNameInterface|null $name
230
     * @return bool
231
     */
232 64
    public function is($name): bool
233
    {
234 64
        return self::new($name)->getFullyQualifiedName() === $this->getFullyQualifiedName();
235
    }
236
237
    /**
238
     * @return string
239
     */
240 1
    public function jsonSerialize(): string
241
    {
242 1
        return $this->getFullyQualifiedName();
243
    }
244
245
    /**
246
     * @return int
247
     */
248 1
    public function count(): int
249
    {
250 1
        return $this->size;
251
    }
252
}
253