Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
36 / 36
94.12% covered (success)
94.12%
32 / 34
4.76% covered (danger)
4.76%
2 / 42
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
DslSplitter
100.00% covered (success)
100.00%
36 / 36
94.12% covered (success)
94.12%
32 / 34
4.76% covered (danger)
4.76%
2 / 42
100.00% covered (success)
100.00%
2 / 2
209.36
100.00% covered (success)
100.00%
1 / 1
 split
100.00% covered (success)
100.00%
35 / 35
96.67% covered (success)
96.67%
29 / 30
2.50% covered (danger)
2.50%
1 / 40
100.00% covered (success)
100.00%
1 / 1
195.66
 isEscapable
100.00% covered (success)
100.00%
1 / 1
75.00% covered (warning)
75.00%
3 / 4
50.00% covered (danger)
50.00%
1 / 2
100.00% covered (success)
100.00%
1 / 1
1.12
1<?php
2
3declare(strict_types=1);
4
5namespace Celemas\Sire;
6
7use ValueError;
8
9final class DslSplitter
10{
11    /**
12     * @mago-expect lint:halstead
13     * @return list<string>
14     */
15    public static function split(
16        string $input,
17        string $delimiter,
18        bool $preserveQuotes = false,
19    ): array {
20        $parts = [''];
21        $index = 0;
22        $quote = null;
23        $length = strlen($input);
24
25        for ($i = 0; $i < $length; $i++) {
26            $char = $input[$i];
27
28            if ($char === '\\') {
29                $nextChar = ($i + 1) < $length ? $input[$i + 1] : null;
30
31                if ($nextChar !== null && self::isEscapable($nextChar, $delimiter)) {
32                    $parts[$index] .= $nextChar;
33                    $i++;
34
35                    continue;
36                }
37
38                $parts[$index] .= $char;
39
40                continue;
41            }
42
43            if ($quote !== null) {
44                if ($char === $quote) {
45                    if ($preserveQuotes) {
46                        $parts[$index] .= $char;
47                    }
48
49                    $quote = null;
50
51                    continue;
52                }
53
54                $parts[$index] .= $char;
55
56                continue;
57            }
58
59            if ($char === '"' || $char === "'") {
60                if ($preserveQuotes) {
61                    $parts[$index] .= $char;
62                }
63
64                $quote = $char;
65
66                continue;
67            }
68
69            if ($char === $delimiter) {
70                $parts[] = '';
71                $index = count($parts) - 1;
72
73                continue;
74            }
75
76            $parts[$index] .= $char;
77        }
78
79        if ($quote !== null) {
80            throw new ValueError('Invalid rule definition: unclosed quote');
81        }
82
83        return $parts;
84    }
85
86    private static function isEscapable(string $char, string $delimiter): bool
87    {
88        return in_array($char, [$delimiter, '\\', '"', "'"], true);
89    }
90}