summaryrefslogtreecommitdiff
path: root/src/PathSegment.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/PathSegment.php')
-rw-r--r--src/PathSegment.php123
1 files changed, 107 insertions, 16 deletions
diff --git a/src/PathSegment.php b/src/PathSegment.php
index 7f24660..5333d17 100644
--- a/src/PathSegment.php
+++ b/src/PathSegment.php
@@ -5,37 +5,66 @@ declare(strict_types=1);
namespace Lightscale\Router;
use Lightscale\Router\Enums\HttpMethod;
-use Lightscale\Router\Enums\SpecialSegment;
+use Lightscale\Router\Enums\PathSegmentType;
class PathSegment
{
private const MAX_ANCESTORY_DEPTH = 100;
- protected string $content;
-
- protected ?SpecialSegment $specialSegment = null;
-
/** @var array<string, self> */
protected array $children;
- /** @var array<value-of<HttpMethod>, Route[]> */
+ /** @var array<value-of<HttpMethod>, Route> */
protected array $routes = [];
+ protected ?self $parent = null;
+
public function __construct(
- SpecialSegment|string $content,
- protected ?self $parent = null,
+ protected ?string $value = null,
+ protected PathSegmentType $type = PathSegmentType::Raw,
) {
- if ($content instanceof SpecialSegment) {
- $this->content = $content->value;
- $this->specialSegment = $content;
- } else {
- $this->content = $content;
+ if (PathSegmentType::Root === $type) {
+ $this->value = null;
}
}
public function getContent(): string
{
- return $this->content;
+ return match ($this->type) {
+ PathSegmentType::Root => '',
+ default => $this->value ?? '',
+ };
+ }
+
+ public function getValue(): ?string
+ {
+ return $this->value;
+ }
+
+ private static function createKey(
+ ?string $value,
+ PathSegmentType $type,
+ ): string {
+ return match ($type) {
+ PathSegmentType::Raw => $value ?? '',
+ PathSegmentType::Root => '<root>',
+ PathSegmentType::Parameter => '<parameter>',
+ };
+ }
+
+ public function getKey(): string
+ {
+ return self::createKey($this->value, $this->type);
+ }
+
+ public function getType(): PathSegmentType
+ {
+ return $this->type;
+ }
+
+ public function setParent(?self $segment): void
+ {
+ $this->parent = $segment;
}
public function getParent(): ?self
@@ -72,7 +101,8 @@ class PathSegment
public function addChild(self $segment): void
{
- $this->children[$segment->getContent()] = $segment;
+ $segment->setParent($this);
+ $this->children[$segment->getKey()] = $segment;
}
/** @return array<string, self> */
@@ -81,7 +111,68 @@ class PathSegment
return $this->children;
}
- public function addRoute(): void
+ public function getChildrenCount(): int
+ {
+ return count($this->children);
+ }
+
+ public function findChild(
+ ?string $value = null,
+ ): ?PathSegment {
+ $key = self::createKey($value, PathSegmentType::Raw);
+ $seg = $this->children[$key] ?? null;
+
+ if ($seg instanceof self) {
+ return $seg;
+ }
+
+ $key = self::createKey($value, PathSegmentType::Parameter);
+ $seg = $this->children[$key] ?? null;
+
+ return $seg;
+ }
+
+ public function child(
+ ?string $value = null,
+ PathSegmentType $type = PathSegmentType::Raw,
+ ): self {
+ $key = self::createKey($value, $type);
+ $seg = $this->children[$key] ?? null;
+
+ if (null === $seg) {
+ $seg = new PathSegment($value, $type);
+ }
+
+ $this->addChild($seg);
+
+ return $seg;
+ }
+
+ public function getPath(): string
+ {
+ $parts = array_map(
+ fn ($seg) => $seg->getContent(),
+ $this->getAncestorsAndSelf()
+ );
+
+ return implode('/', $parts);
+ }
+
+ public function addRoute(Route $route): void
+ {
+ $route->setSegment($this);
+ $method = $route->getMethod()->value;
+ $this->routes[$method] = $route;
+ }
+
+ public function getRoute(HttpMethod $method): ?Route
+ {
+ return $this->routes[$method->value] ?? null;
+ }
+
+ /** @return array<value-of<HttpMethod>, Route> */
+ public function getRoutes(): array
{
+ return $this->routes;
}
}