Skip to content

Commit

Permalink
Splitting Group into separate classes
Browse files Browse the repository at this point in the history
  • Loading branch information
rudashi committed Jul 13, 2024
1 parent c0a1077 commit 920ad0a
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 78 deletions.
16 changes: 1 addition & 15 deletions src/Concerns/Group.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Rudashi\Concerns;

use LogicException;
use Rudashi\FluentBuilder;

trait Group
Expand All @@ -16,20 +15,7 @@ trait Group
*/
public function capture(callable $callback, bool $lookbehind = false, bool $lookahead = false): FluentBuilder
{
if ($lookbehind && $lookahead) {
throw new LogicException('Unable to look behind and ahead at the same time.');
}

$behind = $lookbehind ? '?<=' : '';
$ahead = $lookahead ? '?=' : '';

$this->pushToPattern('(' . $behind . $ahead);

$callback($this);

$this->pushToPattern(')');

return $this;
return $this->addToken()->capture($callback, \Rudashi\Tokens\Group::make($lookbehind, $lookahead));
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Concerns/HasTokens.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public function maybe(callable|string|int $callback): FluentBuilder
/**
* Adds a token to the pattern.
*/
private function addToken(): Token
public function addToken(): Token
{
return new Token($this, $this->isSub);
}
Expand Down
69 changes: 7 additions & 62 deletions src/Negate.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Rudashi;

use LogicException;
use Rudashi\Tokens\Group;

/**
* @mixin \Rudashi\FluentBuilder
Expand All @@ -18,6 +19,7 @@ final class Negate
*/
private static array $guardedMethods = [
// FluentBuilder
'get',
'check',
'match',
'addContext',
Expand Down Expand Up @@ -66,17 +68,7 @@ public function __call(string $method, array $arguments): FluentBuilder
$this->throwNegationException($method);
}

$this->builder->pushToPattern('[^');

$result = $this->builder->{$method}(...$arguments);

if ($result instanceof FluentBuilder) {
$this->builder->pushToPattern(']');

return $this->builder;
}

$this->throwNegationException($method);
return $this->builder->anyOf(static fn (FluentBuilder $fluent) => $fluent->raw('^')->{$method}(...$arguments));
}

/**
Expand All @@ -100,20 +92,7 @@ public function anyOf(string|int|callable $value): FluentBuilder
*/
public function capture(callable $callback, bool $lookbehind = false, bool $lookahead = false): FluentBuilder
{
if ($lookbehind && $lookahead) {
throw new LogicException('Unable to look behind and ahead at the same time.');
}

$behind = $lookbehind ? '?<!' : '';
$ahead = $lookahead ? '?!' : '';

$this->builder->pushToPattern('(' . (! $behind && ! $ahead ? '?:' : '') . $behind . $ahead);

$callback($this->builder);

$this->builder->pushToPattern(')');

return $this->builder;
return $this->builder->addToken()->capture($callback, Group::make($lookbehind, $lookahead, true));
}

/**
Expand All @@ -129,53 +108,19 @@ public function group(callable $callback, bool $lookbehind = false, bool $lookah
/**
* Adds optional captures to the pattern array.
*
* @param callable(\Rudashi\FluentBuilder):\Rudashi\FluentBuilder|string|int $callback
* @param callable(\Rudashi\FluentBuilder): \Rudashi\FluentBuilder|string|int $callback
*/
public function maybe(callable|string|int $callback): FluentBuilder
{
return is_callable($callback)
? $this->capture($callback)->zeroOrOne()
: $this->builder->character($callback)->zeroOrOne();
}

/**
* Adds a match to anything other than letter.
*/
public function letter(): FluentBuilder
{
$this->builder->pushToPattern('[^a-zA-Z]');

return $this->builder;
}

/**
* Adds a match to anything other than lower letter.
*/
public function lowerLetter(): FluentBuilder
{
$this->builder->pushToPattern('[^a-z]');

return $this->builder;
}

/**
* Adds a match to anything other than number.
*/
public function number(): FluentBuilder
{
$this->builder->pushToPattern('[^0-9]');

return $this->builder;
return (is_callable($callback) ? $this->capture($callback) : $this->builder->character($callback))->zeroOrOne();
}

/**
* Adds a match to anything other than numbers.
*/
public function numbers(): FluentBuilder
{
$this->builder->pushToPattern('[^0-9]+');

return $this->builder;
return $this->number()->oneOrMore();
}

/**
Expand Down
11 changes: 11 additions & 0 deletions src/Token.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@ public function __construct(
) {
}

public function capture(callable $callback, TokenContract $group): FluentBuilder
{
$this->builder->pushToPattern('(' . $group->getToken());

$callback($this->builder);

$this->builder->pushToPattern(')');

return $this->builder;
}

public function letter(string $first = 'a', string $last = 'z'): FluentBuilder
{
return $this->addToken(Letter::for($first, $last));
Expand Down
41 changes: 41 additions & 0 deletions src/Tokens/Group.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace Rudashi\Tokens;

use LogicException;
use Rudashi\Contracts\TokenContract;

final class Group implements TokenContract
{
public function __construct(
private readonly TokenContract $group,
) {
}

public function __toString(): string
{
return $this->group->getToken();
}

public static function make(
bool $lookbehind = false,
bool $lookahead = false,
bool $negative = false
): self {
if ($lookbehind && $lookahead) {
throw new LogicException('Unable to look behind and ahead at the same time.');
}

return new self(match ($negative) {
true => new NegativeGroup($lookbehind, $lookahead),
false => new PositiveGroup($lookbehind, $lookahead),
});
}

public function getToken(): string
{
return $this->__toString();
}
}
30 changes: 30 additions & 0 deletions src/Tokens/NegativeGroup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Rudashi\Tokens;

use Rudashi\Contracts\TokenContract;

final class NegativeGroup implements TokenContract
{
public function __construct(
private readonly bool $lookbehind = false,
private readonly bool $lookahead = false,
) {
}

public function __toString(): string
{
if (! $this->lookbehind && ! $this->lookahead) {
return '?:';
}

return ($this->lookbehind ? '?<!' : '') . ($this->lookahead ? '?!' : '');
}

public function getToken(): string
{
return $this->__toString();
}
}
26 changes: 26 additions & 0 deletions src/Tokens/PositiveGroup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Rudashi\Tokens;

use Rudashi\Contracts\TokenContract;

final class PositiveGroup implements TokenContract
{
public function __construct(
private readonly bool $lookbehind = false,
private readonly bool $lookahead = false,
) {
}

public function __toString(): string
{
return ($this->lookbehind ? '?<=' : '') . ($this->lookahead ? '?=' : '');
}

public function getToken(): string
{
return $this->__toString();
}
}

0 comments on commit 920ad0a

Please sign in to comment.