GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — develop ( 870d79...a1e45f )
by Baptiste
05:29
created

Str::matches()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 1
eloc 1
c 2
b 0
f 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\Immutable;
5
6
use Innmind\Immutable\{
7
    Exception\RegexException,
8
    Exception\SubstringException,
9
    Exception\LogicException
10
};
11
12
final class Str
13
{
14
    private const PAD_RIGHT = STR_PAD_RIGHT;
15
    private const PAD_LEFT = STR_PAD_LEFT;
16
    private const PAD_BOTH = STR_PAD_BOTH;
17
    private const PREG_NO_FLAGS = 0;
18
    private const PREG_SPLIT_NO_EMPTY = PREG_SPLIT_NO_EMPTY;
19
    private const PREG_SPLIT_DELIM_CAPTURE = PREG_SPLIT_DELIM_CAPTURE;
20
    private const PREG_SPLIT_OFFSET_CAPTURE = PREG_SPLIT_OFFSET_CAPTURE;
21
    private const PREG_OFFSET_CAPTURE = PREG_OFFSET_CAPTURE;
22
23
    private string $value;
24
    private ?string $encoding;
25
26 313
    private function __construct(string $value, string $encoding = null)
27
    {
28 313
        $this->value = $value;
29 313
        $this->encoding = $encoding;
30 313
    }
31
32 313
    public static function of(string $value, string $encoding = null): self
33
    {
34 313
        return new self($value, $encoding);
35
    }
36
37
    /**
38
     * {@inheritdoc}
39
     */
40 311
    public function __toString(): string
41
    {
42 311
        return $this->value;
43
    }
44
45 291
    public function encoding(): self
46
    {
47 291
        if (\is_null($this->encoding)) {
48 287
            $this->encoding = \mb_internal_encoding();
49
        }
50
51 291
        return new self($this->encoding);
52
    }
53
54 15
    public function toEncoding(string $encoding): self
55
    {
56 15
        return new self($this->value, $encoding);
57
    }
58
59
    /**
60
     * Split the string into a collection of ones
61
     *
62
     * @return Sequence<self>
63
     */
64 8
    public function split(string $delimiter = null): Sequence
65
    {
66 8
        if (\is_null($delimiter) || $delimiter === '') {
67 3
            return $this->chunk();
68
        }
69
70 6
        $parts = \explode($delimiter, $this->value);
71 6
        $sequence = Sequence::of(self::class);
72
73 6
        foreach ($parts as $part) {
74 6
            $sequence = $sequence->add(new self($part, $this->encoding));
75
        }
76
77 6
        return $sequence;
78
    }
79
80
    /**
81
     * Returns a collection of the string splitted by the given chunk size
82
     *
83
     * @return Sequence<self>
84
     */
85 7
    public function chunk(int $size = 1): Sequence
86
    {
87 7
        $sequence = Sequence::of(self::class);
88 7
        $parts = \mb_str_split($this->value, $size, (string) $this->encoding());
89
90 7
        foreach ($parts as $value) {
91 7
            $sequence = $sequence->add(new self($value, $this->encoding));
92
        }
93
94 7
        return $sequence;
95
    }
96
97
    /**
98
     * Returns the position of the first occurence of the string
99
     *
100
     * @throws SubstringException If the string is not found
101
     */
102 274
    public function position(string $needle, int $offset = 0): int
103
    {
104 274
        $position = \mb_strpos($this->value, $needle, $offset, (string) $this->encoding());
105
106 274
        if ($position === false) {
107 272
            throw new SubstringException(\sprintf(
108 272
                'Substring "%s" not found',
109 272
                $needle
110
            ));
111
        }
112
113 7
        return (int) $position;
114
    }
115
116
    /**
117
     * Replace all occurences of the search string with the replacement one
118
     */
119 2
    public function replace(string $search, string $replacement): self
120
    {
121 2
        if (!$this->contains($search)) {
122 1
            return $this;
123
        }
124
125
        return $this
126 2
            ->split($search)
127 2
            ->join($replacement);
128
    }
129
130
    /**
131
     * Returns the string following the given delimiter
132
     *
133
     * @throws SubstringException If the string is not found
134
     */
135 3
    public function str(string $delimiter): self
136
    {
137 3
        $sub = \mb_strstr($this->value, $delimiter, false, (string) $this->encoding());
138
139 3
        if ($sub === false) {
140 1
            throw new SubstringException(\sprintf(
141 1
                'Substring "%s" not found',
142 1
                $delimiter
143
            ));
144
        }
145
146 2
        return new self($sub, $this->encoding);
147
    }
148
149
    /**
150
     * Return the string in upper case
151
     */
152 3
    public function toUpper(): self
153
    {
154 3
        return new self(\mb_strtoupper($this->value), $this->encoding);
155
    }
156
157
    /**
158
     * Return the string in lower case
159
     */
160 3
    public function toLower(): self
161
    {
162 3
        return new self(\mb_strtolower($this->value), $this->encoding);
163
    }
164
165
    /**
166
     * Return the string length
167
     */
168 15
    public function length(): int
169
    {
170 15
        return \mb_strlen($this->value, (string) $this->encoding());
171
    }
172
173 1
    public function empty(): bool
174
    {
175 1
        return $this->value === '';
176
    }
177
178
    /**
179
     * Reverse the string
180
     */
181 1
    public function reverse(): self
182
    {
183
        return $this
184 1
            ->chunk()
185 1
            ->reverse()
186 1
            ->join('');
187
    }
188
189
    /**
190
     * Pad to the right
191
     */
192 1
    public function rightPad(int $length, string $character = ' '): self
193
    {
194 1
        return $this->pad($length, $character, self::PAD_RIGHT);
195
    }
196
197
    /**
198
     * Pad to the left
199
     */
200 1
    public function leftPad(int $length, string $character = ' '): self
201
    {
202 1
        return $this->pad($length, $character, self::PAD_LEFT);
203
    }
204
205
    /**
206
     * Pad both sides
207
     */
208 1
    public function uniPad(int $length, string $character = ' '): self
209
    {
210 1
        return $this->pad($length, $character, self::PAD_BOTH);
211
    }
212
213
    /**
214
     * Find length of initial segment not matching mask
215
     */
216 1
    public function cspn(string $mask, int $start = 0, int $length = null): int
217
    {
218 1
        if ($length === null) {
219 1
            $value = \strcspn($this->value, $mask, $start);
220
        } else {
221 1
            $value = \strcspn(
222 1
                $this->value,
223 1
                $mask,
224 1
                $start,
225 1
                $length
226
            );
227
        }
228
229 1
        return (int) $value;
230
    }
231
232
    /**
233
     * Repeat the string n times
234
     */
235 1
    public function repeat(int $repeat): self
236
    {
237 1
        return new self(\str_repeat($this->value, $repeat), $this->encoding);
238
    }
239
240
    /**
241
     * Shuffle the string
242
     */
243 2
    public function shuffle(): self
244
    {
245 2
        $parts = $this->chunk()->toArray();
246 2
        \shuffle($parts);
247
248 2
        return new self(\implode('', $parts), $this->encoding);
249
    }
250
251 1
    public function stripSlashes(): self
252
    {
253 1
        return new self(\stripslashes($this->value), $this->encoding);
254
    }
255
256
    /**
257
     * Strip C-like slashes
258
     */
259 1
    public function stripCSlashes(): self
260
    {
261 1
        return new self(\stripcslashes($this->value), $this->encoding);
262
    }
263
264
    /**
265
     * Return the word count
266
     */
267 1
    public function wordCount(string $charlist = ''): int
268
    {
269 1
        return (int) \str_word_count(
270 1
            $this->value,
271 1
            0,
272 1
            $charlist
273
        );
274
    }
275
276
    /**
277
     * Return the collection of words
278
     *
279
     * @return Map<int, self>
280
     */
281 1
    public function words(string $charlist = ''): Map
282
    {
283 1
        $words = \str_word_count($this->value, 2, $charlist);
284 1
        $map = Map::of('int', self::class);
285
286 1
        foreach ($words as $position => $word) {
287 1
            $map = $map->put($position, new self($word, $this->encoding));
288
        }
289
290 1
        return $map;
291
    }
292
293
    /**
294
     * Split the string using a regular expression
295
     *
296
     * @return Sequence<self>
297
     */
298 2
    public function pregSplit(string $regex, int $limit = -1): Sequence
299
    {
300 2
        $strings = \preg_split($regex, $this->value, $limit);
301 2
        $sequence = Sequence::of(self::class);
302
303 2
        foreach ($strings as $string) {
304 2
            $sequence = $sequence->add(new self($string, $this->encoding));
305
        }
306
307 2
        return $sequence;
308
    }
309
310
    /**
311
     * Check if the string match the given regular expression
312
     *
313
     * @throws Exception If the regex failed
314
     */
315 2
    public function matches(string $regex): bool
316
    {
317 2
        return RegExp::of($regex)->matches($this);
318
    }
319
320
    /**
321
     * Return a collection of the elements matching the regex
322
     *
323
     * @throws Exception If the regex failed
324
     *
325
     * @return Map<scalar, self>
326
     */
327 3
    public function capture(string $regex): Map
328
    {
329 3
        return RegExp::of($regex)->capture($this);
330
    }
331
332
    /**
333
     * Replace part of the string by using a regular expression
334
     *
335
     * @throws Exception If the regex failed
336
     */
337 1
    public function pregReplace(
338
        string $regex,
339
        string $replacement,
340
        int $limit = -1
341
    ): self {
342 1
        $value = \preg_replace(
343 1
            $regex,
344 1
            $replacement,
345 1
            $this->value,
346 1
            $limit
347
        );
348
349 1
        if ($value === null) {
350
            throw new RegexException('', \preg_last_error());
351
        }
352
353 1
        return new self($value, $this->encoding);
354
    }
355
356
    /**
357
     * Return part of the string
358
     */
359 12
    public function substring(int $start, int $length = null): self
360
    {
361 12
        if ($this->length() === 0) {
362 1
            return $this;
363
        }
364
365 12
        $sub = \mb_substr($this->value, $start, $length, (string) $this->encoding());
366
367 12
        return new self($sub, $this->encoding);
368
    }
369
370 1
    public function take(int $size): self
371
    {
372 1
        return $this->substring(0, $size);
373
    }
374
375 2
    public function takeEnd(int $size): self
376
    {
377 2
        return $this->substring(-$size);
378
    }
379
380 2
    public function drop(int $size): self
381
    {
382 2
        return $this->substring($size);
383
    }
384
385 1
    public function dropEnd(int $size): self
386
    {
387 1
        return $this->substring(0, $this->length() - $size);
388
    }
389
390
    /**
391
     * Return a formatted string
392
     */
393 1
    public function sprintf(...$values): self
394
    {
395 1
        return new self(\sprintf($this->value, ...$values), $this->encoding);
396
    }
397
398
    /**
399
     * Return the string with the first letter as uppercase
400
     */
401 2
    public function ucfirst(): self
402
    {
403
        return $this
404 2
            ->substring(0, 1)
405 2
            ->toUpper()
406 2
            ->append((string) $this->substring(1));
407
    }
408
409
    /**
410
     * Return the string with the first letter as lowercase
411
     */
412 2
    public function lcfirst(): self
413
    {
414
        return $this
415 2
            ->substring(0, 1)
416 2
            ->toLower()
417 2
            ->append((string) $this->substring(1));
418
    }
419
420
    /**
421
     * Return a CamelCase representation of the string
422
     */
423 1
    public function camelize(): self
424
    {
425
        return $this
426 1
            ->pregSplit('/_| /')
427
            ->map(function(self $part) {
428 1
                return $part->ucfirst();
429 1
            })
430 1
            ->join('')
431 1
            ->lcfirst()
432 1
            ->toEncoding((string) $this->encoding());
433
    }
434
435
    /**
436
     * Append a string at the end of the current one
437
     */
438 4
    public function append(string $string): self
439
    {
440 4
        return new self((string) $this.$string, $this->encoding);
441
    }
442
443
    /**
444
     * Prepend a string at the beginning of the current one
445
     */
446 1
    public function prepend(string $string): self
447
    {
448 1
        return new self($string.(string) $this, $this->encoding);
449
    }
450
451
    /**
452
     * Check if the 2 strings are equal
453
     */
454 1
    public function equals(self $string): bool
455
    {
456 1
        return (string) $this === (string) $string;
457
    }
458
459
    /**
460
     * Trim the string
461
     */
462 1
    public function trim(string $mask = null): self
463
    {
464 1
        return new self(
465 1
            $mask === null ? \trim((string) $this) : \trim((string) $this, $mask),
466 1
            $this->encoding
467
        );
468
    }
469
470
    /**
471
     * Trim the right side of the string
472
     */
473 1
    public function rightTrim(string $mask = null): self
474
    {
475 1
        return new self(
476 1
            $mask === null ? \rtrim((string) $this) : \rtrim((string) $this, $mask),
477 1
            $this->encoding
478
        );
479
    }
480
481
    /**
482
     * Trim the left side of the string
483
     */
484 1
    public function leftTrim(string $mask = null): self
485
    {
486 1
        return new self(
487 1
            $mask === null ? \ltrim((string) $this) : \ltrim((string) $this, $mask),
488 1
            $this->encoding
489
        );
490
    }
491
492
    /**
493
     * Check if the given string is present in the current one
494
     */
495 271
    public function contains(string $value): bool
496
    {
497
        try {
498 271
            $this->position($value);
499
500 5
            return true;
501 270
        } catch (SubstringException $e) {
502 270
            return false;
503
        }
504
    }
505
506
    /**
507
     * Check if the current string starts with the given string
508
     */
509 270
    public function startsWith(string $value): bool
510
    {
511 270
        if ($value === '') {
512 1
            return true;
513
        }
514
515
        try {
516 270
            return $this->position($value) === 0;
517 270
        } catch (SubstringException $e) {
518 270
            return false;
519
        }
520
    }
521
522
    /**
523
     * Check if the current string ends with the given string
524
     */
525 1
    public function endsWith(string $value): bool
526
    {
527 1
        if ($value === '') {
528 1
            return true;
529
        }
530
531 1
        return (string) $this->takeEnd(self::of($value, $this->encoding)->length()) === $value;
532
    }
533
534
    /**
535
     * Quote regular expression characters
536
     */
537 1
    public function pregQuote(string $delimiter = ''): self
538
    {
539 1
        return new self(\preg_quote((string) $this, $delimiter), $this->encoding);
540
    }
541
542
    /**
543
     * Pad the string
544
     */
545 1
    private function pad(
546
        int $length,
547
        string $character = ' ',
548
        int $direction = self::PAD_RIGHT
549
    ): self {
550 1
        return new self(\str_pad(
551 1
            $this->value,
552 1
            $length,
553 1
            $character,
554 1
            $direction
555 1
        ), $this->encoding);
556
    }
557
}
558