Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
rudashi committed Jul 16, 2024
1 parent 0066486 commit b2d085c
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 84 deletions.
52 changes: 52 additions & 0 deletions src/Concerns/HasPatterns.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

namespace Rudashi\Concerns;

use Rudashi\Contracts\PatternContract;

trait HasPatterns
{
/**
* Dynamically handle call into builder instance.
*
* @param array<int, callable|string|int> $arguments
*
* @throws \BadMethodCallException
*/
public function __call(string $name, array $arguments): self
{
foreach ($this->patterns as $pattern) {
if ($pattern->getName() === $name || $pattern->alias() === $name) {
return $this->pushToPattern($pattern->getPattern());
}
}

$this->throwBadMethodException($name);
}

/**
* Dynamically call the registered pattern.
*/
public function pattern(string $string): self
{
return $this->__call($string, []);
}

/**
* Register the given Patterns with the builder.
*
* @param array<int, class-string<\Rudashi\Contracts\PatternContract>> $patterns
*/
private function registerPatterns(array $patterns): void
{
array_map(function (string $pattern): void {
if (! is_subclass_of($pattern, PatternContract::class)) {
$this->throwArgumentException(sprintf('Class "%s" must implement PatternContract.', $pattern));
}

$this->patterns[] = new $pattern();
}, $patterns);
}
}
18 changes: 18 additions & 0 deletions src/Concerns/Sanitizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Rudashi\Concerns;

trait Sanitizer
{
/**
* Sanitize the given expression value.
*/
public static function sanitize(string|int $value): string
{
$value = (string) $value;

return $value !== '' ? preg_quote($value, '/') : $value;
}
}
42 changes: 42 additions & 0 deletions src/Concerns/ThrowExceptions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace Rudashi\Concerns;

use BadMethodCallException;
use InvalidArgumentException;
use LogicException;

trait ThrowExceptions
{
/**
* Throws a bad method call exception for the given method.
*
* @throws \BadMethodCallException
*/
protected function throwBadMethodException(string $method): never
{
throw new BadMethodCallException(sprintf('Method "%s" does not exist in %s.', $method, self::class));
}

/**
* Throws a logic exception.
*
* @throws \LogicException
*/
protected function throwLogicException(string $message): never
{
throw new LogicException($message);
}

/**
* Throws an invalid argument exception.
*
* @throws \InvalidArgumentException
*/
protected function throwArgumentException(string $message): never
{
throw new InvalidArgumentException($message);
}
}
97 changes: 13 additions & 84 deletions src/FluentBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@

use ArgumentCountError;
use BackedEnum;
use BadMethodCallException;
use InvalidArgumentException;
use LogicException;
use Rudashi\Concerns\Dumpable;
use Rudashi\Concerns\Flags;
use Rudashi\Concerns\Group;
use Rudashi\Concerns\HasAnchors;
use Rudashi\Concerns\HasPatterns;
use Rudashi\Concerns\HasTokens;
use Rudashi\Concerns\Quantifiers;
use Rudashi\Concerns\Returnable;
use Rudashi\Concerns\Sanitizer;
use Rudashi\Concerns\ThrowExceptions;
use Rudashi\Contracts\PatternContract;

/**
Expand All @@ -26,11 +26,14 @@ final class FluentBuilder
{
use HasAnchors;
use HasTokens;
use HasPatterns;
use Flags;
use Dumpable;
use ThrowExceptions;
use Quantifiers;
use Group;
use Returnable;
use Sanitizer;

/**
* Regex delimiter value.
Expand Down Expand Up @@ -99,50 +102,20 @@ public function __get(string $name): mixed
try {
return $this->{$name}();
} catch (ArgumentCountError) {
throw new LogicException(
$this->throwLogicException(
sprintf('Cannot access property "%s". Use the "%s()" method instead.', $name, $name)
);
}
}

/**
* Dynamically handle call into builder instance.
*
* @param array<int, callable|string|int> $arguments
*
* @throws \BadMethodCallException
*/
public function __call(string $name, array $arguments): self
{
foreach ($this->patterns as $pattern) {
if ($pattern->getName() === $name || $pattern->alias() === $name) {
$this->pushToPattern($pattern->getPattern());

return $this;
}
}

$this->throwBadMethodException($name);
}

/**
* Throws a logical exception when assigning a property.
*
* @throws \LogicException
*/
public function __set(string $name, mixed $value): void
public function __set(string $name, mixed $value): never
{
throw new LogicException(sprintf('Setter "%s" is not acceptable.', $name));
}

/**
* Sanitize the given expression value.
*/
public static function sanitize(string|int $value): string
{
$value = (string) $value;

return $value !== '' ? preg_quote($value, '/') : $value;
$this->throwLogicException(sprintf('Setter "%s" is not acceptable.', $name));
}

/**
Expand All @@ -161,7 +134,7 @@ public function pushToPattern(string|BackedEnum $value): self
public function addContext(string $string): self
{
if ($this->isSub) {
throw new LogicException(
$this->throwLogicException(
sprintf('Method "%s" is not acceptable in sub patterns.', __FUNCTION__)
);
}
Expand All @@ -186,68 +159,24 @@ public function not(): Negate
*/
public function oneOf(string ...$value): self
{
$this->pushToPattern(
return $this->pushToPattern(
implode('|', array_map([$this, 'sanitize'], $value))
);

return $this;
}

/**
* Adds an alternative to the pattern.
*/
public function or(): self
{
$this->pushToPattern('|');

return $this;
return $this->pushToPattern('|');
}

/**
* Adds a match of any character to the pattern.
*/
public function anything(): self
{
$this->pushToPattern('.*');

return $this;
}

/**
* Dynamically call the registered pattern.
*/
public function pattern(string $string): self
{
return $this->__call($string, []);
}

/**
* Throws a bad method call exception for the given method.
*
* @throws \BadMethodCallException
*/
protected function throwBadMethodException(string $method): void
{
throw new BadMethodCallException(sprintf('Method "%s" does not exist in %s.', $method, self::class));
}

/**
* Register the given Patterns with the builder.
*
* @param array<int, class-string<\Rudashi\Contracts\PatternContract>> $patterns
*/
private function registerPatterns(array $patterns): self
{
foreach ($patterns as $pattern) {
if (! is_subclass_of($pattern, PatternContract::class)) {
throw new InvalidArgumentException(
sprintf('Class "%s" must implement PatternContract.', $pattern)
);
}

$this->patterns[] = new $pattern();
}

return $this;
return $this->pushToPattern('.*');
}
}

0 comments on commit b2d085c

Please sign in to comment.