Passed
Pull Request — master (#289)
by
unknown
03:23
created

ArrayParser::parseString()   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 2
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 3
    private function parseString(string $value, int &$i): string|null
57
    {
58 3
        return $value[$i] === '"'
59 2
            ? $this->parseQuotedString($value, $i)
60 3
            : $this->parseUnquotedString($value, $i);
61
    }
62
63
    /**
64
     * Parses quoted string.
65
     */
66 2
    private function parseQuotedString(string $value, int &$i): string
67
    {
68 2
        for ($result = '', ++$i;; ++$i) {
69 2
            if ($value[$i] === '\\') {
70 2
                ++$i;
71 2
            } elseif ($value[$i] === '"') {
72 2
                ++$i;
73 2
                return $result;
74
            }
75
76 2
            $result .= $value[$i];
77
        }
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...
78
    }
79
80
    /**
81
     * Parses unquoted string.
82
     */
83 3
    private function parseUnquotedString(string $value, int &$i): string|null
84
    {
85 3
        for ($result = '';; ++$i) {
86 3
            if (in_array($value[$i], [',', '}'], true)) {
87 3
                return $result !== 'NULL'
88 3
                    ? $result
89 3
                    : null;
90
            }
91
92 3
            $result .= $value[$i];
93
        }
94
    }
95
}
96