Sequence::of()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php declare(strict_types=1);
2
3
namespace Stratadox\Parser\Parsers;
4
5
use Stratadox\Parser\Helpers\Cast;
6
use Stratadox\Parser\Parser;
7
use Stratadox\Parser\Result;
8
use Stratadox\Parser\Results\Ok;
9
use function array_merge;
10
11
/**
12
 * Sequence / andThen
13
 *
14
 * Puts several parsers one after the other.
15
 * Leaves ignored results out of the returned list of results.
16
 */
17
final class Sequence extends Parser
18
{
19
    /** @param Parser[] $parsers */
20
    public function __construct(private array $parsers) {}
21
22
    public static function of(Parser|string ...$parsers): Parser
23
    {
24
        return new self(Cast::asParsers(...$parsers));
25
    }
26
27
    public function parse(string $input): Result
28
    {
29
        $sequence = [];
30
        $unparsed = $input;
31
        foreach ($this->parsers as $parser) {
32
            $result = $parser->parse($unparsed);
33
            if (!$result->ok()) {
34
                return $result;
35
            }
36
            if ($result->use()) {
37
                $sequence[] = $result->data();
38
            }
39
            $unparsed = $result->unparsed();
40
        }
41
        return Ok::with($sequence, $unparsed);
42
    }
43
44
    public function andThen(Parser|string ...$other): Parser
45
    {
46
        return new self(array_merge($this->parsers, Cast::asParsers(...$other)));
47
    }
48
}
49