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

ArrayParser::parseUnquotedString()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 4

Importance

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