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

azjezz / psl / 22680190548

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

Pull #610

github

web-flow
Merge 54e750308 into caa083fec
Pull Request #610: perf: replace PSL calls with native PHP builtins and fix O(n2) algorithms

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/MutableVectorType.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\MutableVectorInterface<T>>
22
 *
23
 * @internal
24
 */
25
final readonly class MutableVectorType extends Type\Type
26
{
27
    /**
28
     * @psalm-mutation-free
29
     *
30
     * @param Type\TypeInterface<T> $value_type
31
     */
32
    public function __construct(
33
        private readonly Type\TypeInterface $value_type,
34
    ) {}
51✔
35

36
    /**
37
     * @psalm-assert-if-true Collection\MutableVectorInterface<T> $value
38
     */
39
    #[Override]
40
    public function matches(mixed $value): bool
41
    {
42
        if (!is_object($value) || !$value instanceof Collection\MutableVectorInterface) {
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\MutableVectorInterface<T>
60
     */
61
    #[Override]
62
    public function coerce(mixed $value): Collection\MutableVectorInterface
63
    {
64
        if (is_iterable($value)) {
21✔
65
            /** @var Type\Type<T> $value_type */
66
            $value_type = $this->value_type;
14✔
67

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

77
            try {
78
                /**
79
                 * @var T $v
80
                 * @var array-key $i
81
                 */
82
                foreach ($value as $i => $v) {
14✔
83
                    $iterating = false;
13✔
84
                    $values[] = $value_type->coerce($v);
13✔
85
                    $iterating = true;
10✔
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\MutableVector($values);
8✔
100
        }
101

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

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

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

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

138
            return new Collection\MutableVector($values);
8✔
139
        }
140

141
        throw AssertException::withValue($value, $this->toString());
10✔
142
    }
143

144
    #[Override]
145
    public function toString(): string
146
    {
147
        return Str\format('%s<%s>', Collection\MutableVectorInterface::class, $this->value_type->toString());
28✔
148
    }
149
}
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