Passed
Push — master ( 8da22b...e96104 )
by Def
14:26 queued 46s
created

ArrayParser::parse()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 2
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Pgsql;
6
7
use function in_array;
8
9
/**
10
 * Array representation to PHP array parser for PostgreSQL Server.
11
 */
12
final class ArrayParser
13
{
14
    /**
15
     * Convert an array from PostgresSQL to PHP.
16
     *
17
     * @param string|null $value String to convert.
18
     */
19 3
    public function parse(string|null $value): array|null
20
    {
21 3
        return $value !== null
22 3
            ? $this->parseArray($value)
23 3
            : null;
24
    }
25
26
    /**
27
     * Parse PostgreSQL array encoded in string.
28
     *
29
     * @param string $value String to parse.
30
     * @param int $i parse starting position.
31
     */
32 3
    private function parseArray(string $value, int &$i = 0): array
33
    {
34 3
        if ($value[++$i] === '}') {
35 1
            ++$i;
36 1
            return [];
37
        }
38
39 3
        for ($result = [];; ++$i) {
40 3
            $result[] = match ($value[$i]) {
41 3
                '{' => $this->parseArray($value, $i),
42 3
                ',', '}' => null,
43 3
                default => $this->parseString($value, $i),
44 3
            };
45
46 3
            if ($value[$i] === '}') {
47 3
                ++$i;
48 3
                return $result;
49
            }
50
        }
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return array. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
51
    }
52
53
    /**
54
     * Parses PostgreSQL encoded string.
55
     *
56
     * @param string $value String to parse.
57
     * @param int $i Parse starting position.
58
     */
59 3
    private function parseString(string $value, int &$i): string|null
60
    {
61 3
        return $value[$i] === '"'
62 2
            ? $this->parseQuotedString($value, $i)
63 3
            : $this->parseUnquotedString($value, $i);
64
    }
65
66
    /**
67
     * Parses quoted string.
68
     */
69 2
    private function parseQuotedString(string $value, int &$i): string
70
    {
71 2
        for ($result = '', ++$i;; ++$i) {
72 2
            if ($value[$i] === '\\') {
73 2
                ++$i;
74 2
            } elseif ($value[$i] === '"') {
75 2
                ++$i;
76 2
                return $result;
77
            }
78
79 2
            $result .= $value[$i];
80
        }
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return string. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
81
    }
82
83
    /**
84
     * Parses unquoted string.
85
     */
86 3
    private function parseUnquotedString(string $value, int &$i): string|null
87
    {
88 3
        for ($result = '';; ++$i) {
89 3
            if (in_array($value[$i], [',', '}'], true)) {
90 3
                return $result !== 'NULL'
91 3
                    ? $result
92 3
                    : null;
93
            }
94
95 3
            $result .= $value[$i];
96
        }
97
    }
98
}
99