• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

azjezz / psl / 22680098232

04 Mar 2026 05:02PM UTC coverage: 97.34% (-1.0%) from 98.375%
22680098232

push

github

azjezz
perf: replace PSL calls with native PHP builtins and fix O(n2) algorithms

Signed-off-by: azjezz <azjezz@protonmail.com>

319 of 355 new or added lines in 90 files covered. (89.86%)

64 existing lines in 12 files now uncovered.

9258 of 9511 relevant lines covered (97.34%)

34.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.44
/src/Psl/Type/Internal/VectorType.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Psl\Type\Internal;
6

7
use Override;
8
use Psl\Collection;
9
use Psl\Str;
10
use Psl\Type;
11
use Psl\Type\Exception\AssertException;
12
use Psl\Type\Exception\CoercionException;
13
use Throwable;
14

15
use function is_iterable;
16
use function is_object;
17

18
/**
19
 * @template T
20
 *
21
 * @extends Type\Type<Collection\VectorInterface<T>>
22
 *
23
 * @internal
24
 */
25
final readonly class VectorType extends Type\Type
26
{
27
    /**
28
     * @psalm-mutation-free
29
     *
30
     * @param Type\TypeInterface<T> $value_type
31
     */
32
    public function __construct(
33
        private Type\TypeInterface $value_type,
34
    ) {}
53✔
35

36
    /**
37
     * @psalm-assert-if-true Collection\VectorInterface<T> $value
38
     */
39
    #[Override]
40
    public function matches(mixed $value): bool
41
    {
42
        if (!is_object($value) || !$value instanceof Collection\VectorInterface) {
18✔
43
            return false;
10✔
44
        }
45

46
        // @mago-expect analysis:mixed-assignment
47
        foreach ($value as $v) {
8✔
48
            if (!$this->value_type->matches($v)) {
8✔
NEW
49
                return false;
×
50
            }
51
        }
52

53
        return true;
8✔
54
    }
55

56
    /**
57
     * @throws CoercionException
58
     *
59
     * @return Collection\VectorInterface<T>
60
     */
61
    #[Override]
62
    public function coerce(mixed $value): Collection\VectorInterface
63
    {
64
        if (is_iterable($value)) {
23✔
65
            /** @var Type\Type<T> $value_type */
66
            $value_type = $this->value_type;
16✔
67

68
            /**
69
             * @var list<T> $values
70
             */
71
            $values = [];
16✔
72
            $i = null;
16✔
73
            $v = null;
16✔
74
            /** @var bool $iterating */
75
            $iterating = true;
16✔
76

77
            try {
78
                /**
79
                 * @var T $v
80
                 * @var array-key $i
81
                 */
82
                foreach ($value as $i => $v) {
16✔
83
                    $iterating = false;
15✔
84
                    $values[] = $value_type->coerce($v);
15✔
85
                    $iterating = true;
12✔
86
                }
87
            } catch (Throwable $e) {
6✔
88
                throw match (true) {
89
                    $iterating => CoercionException::withValue(
6✔
90
                        null,
6✔
91
                        $this->toString(),
6✔
92
                        PathExpression::iteratorError($i),
6✔
93
                        $e,
6✔
94
                    ),
6✔
95
                    default => CoercionException::withValue($v, $this->toString(), PathExpression::path($i), $e),
3✔
96
                };
97
            }
98

99
            return new Collection\Vector($values);
10✔
100
        }
101

102
        throw CoercionException::withValue($value, $this->toString());
7✔
103
    }
104

105
    /**
106
     * @param mixed $value
107
     *
108
     * @throws AssertException
109
     *
110
     * @return Collection\VectorInterface<T>
111
     *
112
     * @psalm-assert Collection\VectorInterface<T> $value
113
     */
114
    #[Override]
115
    public function assert(mixed $value): Collection\VectorInterface
116
    {
117
        if (is_object($value) && $value instanceof Collection\VectorInterface) {
21✔
118
            /** @var Type\Type<T> $value_type */
119
            $value_type = $this->value_type;
10✔
120

121
            /**
122
             * @var list<T> $values
123
             */
124
            $values = [];
10✔
125
            $i = null;
10✔
126
            $v = null;
10✔
127

128
            try {
129
                /**
130
                 * @var T $v
131
                 * @var array-key $i
132
                 */
133
                foreach ($value as $i => $v) {
10✔
134
                    $values[] = $value_type->assert($v);
10✔
135
                }
136
            } catch (AssertException $e) {
2✔
137
                throw AssertException::withValue($v, $this->toString(), PathExpression::path($i), $e);
2✔
138
            }
139

140
            return new Collection\Vector($values);
8✔
141
        }
142

143
        throw AssertException::withValue($value, $this->toString());
11✔
144
    }
145

146
    #[Override]
147
    public function toString(): string
148
    {
149
        return Str\format('%s<%s>', Collection\VectorInterface::class, $this->value_type->toString());
29✔
150
    }
151
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc