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

ArrayParser::parseQuotedString()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 4
nop 0
dl 0
loc 11
ccs 8
cts 8
cp 1
crap 4
rs 10
c 0
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
     * @var int Current parsing position
16
     */
17
    private int $pos = 0;
18
19
    /**
20
     * @param string $value The parse string from PostgresSQL
21
     */
22 3
    public function __construct(
23
        private string $value,
24 3
    ) {}
25
26
    /**
27
     * Parses PostgreSQL encoded array.
28
     */
29 3
    public function parse(): array
30
    {
31 3
        if ($this->value[++$this->pos] === '}') {
32 1
            ++$this->pos;
33 1
            return [];
34
        }
35
36 3
        for ($result = [];; ++$this->pos) {
37 3
            $result[] = match ($this->value[$this->pos]) {
38 3
                '{' => $this->parse(),
39 3
                ',', '}' => null,
40 3
                default => $this->parseString(),
41 3
            };
42
43 3
            if ($this->value[$this->pos] === '}') {
44 3
                ++$this->pos;
45 3
                return $result;
46
            }
47
        }
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...
48
    }
49
50
    /**
51
     * Parses PostgreSQL encoded string.
52
     */
53 3
    private function parseString(): string|null
54
    {
55 3
        return $this->value[$this->pos] === '"'
56 2
            ? $this->parseQuotedString()
57 3
            : $this->parseUnquotedString();
58
    }
59
60
    /**
61
     * Parses quoted string.
62
     *
63
     * @psalm-suppress LoopInvalidation
64
     */
65 2
    private function parseQuotedString(): string
66
    {
67 2
        for ($result = '', ++$this->pos;; ++$this->pos) {
68 2
            if ($this->value[$this->pos] === '\\') {
69 2
                ++$this->pos;
70 2
            } elseif ($this->value[$this->pos] === '"') {
71 2
                ++$this->pos;
72 2
                return $result;
73
            }
74
75 2
            $result .= $this->value[$this->pos];
76
        }
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...
77
    }
78
79
    /**
80
     * Parses unquoted string.
81
     */
82 3
    private function parseUnquotedString(): string|null
83
    {
84 3
        for ($result = '';; ++$this->pos) {
85 3
            if (in_array($this->value[$this->pos], [',', '}'], true)) {
86 3
                return $result !== 'NULL'
87 3
                    ? $result
88 3
                    : null;
89
            }
90
91 3
            $result .= $this->value[$this->pos];
92
        }
93
    }
94
}
95