diff --git a/src/Parsing/ParserState.php b/src/Parsing/ParserState.php index e17c3f3a..df825377 100644 --- a/src/Parsing/ParserState.php +++ b/src/Parsing/ParserState.php @@ -279,6 +279,27 @@ public function consume($value = 1): string return $result; } + /** + * If the possibly-expected next content is next, consume it. + * + * @param non-empty-string $nextContent + * + * @return bool whether the possibly-expected content was found and consumed + */ + public function consumeIfComes(string $nextContent): bool + { + $length = $this->strlen($nextContent); + if (!$this->streql($this->substr($this->currentPosition, $length), $nextContent)) { + return false; + } + + $numberOfLines = \substr_count($nextContent, "\n"); + $this->lineNumber += $numberOfLines; + $this->currentPosition += $this->strlen($nextContent); + + return true; + } + /** * @param string $expression * @param int<1, max>|null $maximumLength diff --git a/tests/Unit/Parsing/ParserStateTest.php b/tests/Unit/Parsing/ParserStateTest.php index 245b083f..bd22508a 100644 --- a/tests/Unit/Parsing/ParserStateTest.php +++ b/tests/Unit/Parsing/ParserStateTest.php @@ -97,4 +97,64 @@ static function (Comment $comment): string { ); self::assertSame($expectedComments, $commentsAsText); } + + /** + * @test + */ + public function consumeIfComesComsumesMatchingContent(): void + { + $subject = new ParserState('abc', Settings::create()); + + $subject->consumeIfComes('ab'); + + self::assertSame('c', $subject->peek()); + } + + /** + * @test + */ + public function consumeIfComesDoesNotComsumeNonMatchingContent(): void + { + $subject = new ParserState('a', Settings::create()); + + $subject->consumeIfComes('x'); + + self::assertSame('a', $subject->peek()); + } + + /** + * @test + */ + public function consumeIfComesReturnsTrueIfContentConsumed(): void + { + $subject = new ParserState('abc', Settings::create()); + + $result = $subject->consumeIfComes('ab'); + + self::assertTrue($result); + } + + /** + * @test + */ + public function consumeIfComesReturnsFalseIfContentNotConsumed(): void + { + $subject = new ParserState('a', Settings::create()); + + $result = $subject->consumeIfComes('x'); + + self::assertFalse($result); + } + + /** + * @test + */ + public function consumeIfComesUpdatesLineNumber(): void + { + $subject = new ParserState("\n", Settings::create()); + + $subject->consumeIfComes("\n"); + + self::assertSame(2, $subject->currentLine()); + } }