Skip to content

Commit

Permalink
Move DI functionality to Settings object
Browse files Browse the repository at this point in the history
This is actually a Service Locator, but the term 'settings' fits better with pre-existing FastRoute language.
  • Loading branch information
pmjones committed Mar 30, 2024
1 parent fcc6278 commit 389a549
Show file tree
Hide file tree
Showing 11 changed files with 287 additions and 153 deletions.
2 changes: 2 additions & 0 deletions src/Dispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
use FastRoute\Dispatcher\Result\MethodNotAllowed;
use FastRoute\Dispatcher\Result\NotMatched;

/** @phpstan-import-type ParsedRoutes from RouteParser */
interface Dispatcher
{
public const NOT_FOUND = 0;
public const FOUND = 1;
public const METHOD_NOT_ALLOWED = 2;

/** @param ParsedRoutes $processedData */
public function with(array $processedData): self;

/**
Expand Down
1 change: 1 addition & 0 deletions src/Dispatcher/RegexBasedAbstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public function with(array $data): self
$clone = clone $this;
$clone->staticRouteMap = $data[0];
$clone->variableRouteData = $data[1];

return $clone;
}

Expand Down
130 changes: 13 additions & 117 deletions src/FastRoute.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
namespace FastRoute;

use Closure;
use FastRoute\Cache\FileCache;

use function assert;
use function is_string;
Expand All @@ -16,123 +15,16 @@ final class FastRoute
private ?array $processedConfiguration = null;

/**
* @param Closure(ConfigureRoutes):void $routeDefinitionCallback
* @param class-string<DataGenerator> $dataGenerator
* @param class-string<Dispatcher> $dispatcher
* @param class-string<ConfigureRoutes> $routesConfiguration
* @param class-string<GenerateUri> $uriGenerator
* @param Cache|class-string<Cache>|null $cacheDriver
* @param non-empty-string|null $cacheKey
* @param Closure(ConfigureRoutes):void $routeDefinitionCallback
* @param non-empty-string|null $cacheKey
*/
public function __construct(
private Closure $routeDefinitionCallback,
private DataGenerator $dataGenerator,
private Dispatcher $dispatcher,
private ConfigureRoutes $routesConfiguration,
private GenerateUri $uriGenerator,
private ?Cache $cacheDriver,
private ?string $cacheKey,
private Settings $settings = new FastSettings(),
) {
}

/**
* @param Closure(ConfigureRoutes):void $routeDefinitionCallback
* @param non-empty-string $cacheKey
*/
public static function recommendedSettings(Closure $routeDefinitionCallback, string $cacheKey): self
{
return new self(
$routeDefinitionCallback,
new DataGenerator\MarkBased(),
new Dispatcher\MarkBased(),
new RouteCollector(new RouteParser\Std()),
new GenerateUri\FromProcessedConfiguration,
new FileCache(),
$cacheKey,
);
}

public function disableCache(): self
{
return new self(
$this->routeDefinitionCallback,
$this->dataGenerator,
$this->dispatcher,
$this->routesConfiguration,
$this->uriGenerator,
null,
null,
);
}

/**
* @param Cache|class-string<Cache> $driver
* @param non-empty-string $cacheKey
*/
public function withCache(Cache $driver, string $cacheKey): self
{
return new self(
$this->routeDefinitionCallback,
$this->dataGenerator,
$this->dispatcher,
$this->routesConfiguration,
$this->uriGenerator,
$driver,
$cacheKey,
);
}

public function useCharCountDispatcher(): self
{
return $this->useCustomDispatcher(new DataGenerator\CharCountBased(), new Dispatcher\CharCountBased());
}

public function useGroupCountDispatcher(): self
{
return $this->useCustomDispatcher(new DataGenerator\GroupCountBased(), new Dispatcher\GroupCountBased());
}

public function useGroupPosDispatcher(): self
{
return $this->useCustomDispatcher(new DataGenerator\GroupPosBased(), new Dispatcher\GroupPosBased());
}

public function useMarkDispatcher(): self
{
return $this->useCustomDispatcher(new DataGenerator\MarkBased(), new Dispatcher\MarkBased());
}

/**
* @param class-string<DataGenerator> $dataGenerator
* @param class-string<Dispatcher> $dispatcher
*/
public function useCustomDispatcher(DataGenerator $dataGenerator, Dispatcher $dispatcher): self
{
return new self(
$this->routeDefinitionCallback,
$dataGenerator,
$dispatcher,
$this->routesConfiguration,
$this->uriGenerator,
$this->cacheDriver,
$this->cacheKey,
);
}

/** @param class-string<GenerateUri> $uriGenerator */
public function withUriGenerator(GenerateUri $uriGenerator): self
{
return new self(
$this->routeDefinitionCallback,
$this->dataGenerator,
$this->dispatcher,
$this->routesConfiguration,
$uriGenerator,
$this->cacheDriver,
$this->cacheKey,
);
}

/** @return ProcessedData */
private function buildConfiguration(): array
{
Expand All @@ -141,26 +33,30 @@ private function buildConfiguration(): array
}

$loader = function (): array {
($this->routeDefinitionCallback)($this->routesConfiguration);
return $this->routesConfiguration->processedRoutes($this->dataGenerator);
$routesConfiguration = $this->settings->getRoutesConfiguration();
($this->routeDefinitionCallback)($routesConfiguration);

return $routesConfiguration->processedRoutes($this->settings->getDataGenerator());
};

if ($this->cacheDriver === null) {
$cacheDriver = $this->settings->getCacheDriver();

if ($cacheDriver === null) {
return $this->processedConfiguration = $loader();
}

assert(is_string($this->cacheKey));

return $this->processedConfiguration = $this->cacheDriver->get($this->cacheKey, $loader);
return $this->processedConfiguration = $cacheDriver->get($this->cacheKey, $loader);
}

public function dispatcher(): Dispatcher
{
return $this->dispatcher->with($this->buildConfiguration());
return $this->settings->getDispatcher()->with($this->buildConfiguration());
}

public function uriGenerator(): GenerateUri
{
return $this->uriGenerator->with($this->buildConfiguration()[2]);
return $this->settings->getUriGenerator()->with($this->buildConfiguration()[2]);
}
}
182 changes: 182 additions & 0 deletions src/FastSettings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
<?php
declare(strict_types=1);

namespace FastRoute;

use FastRoute\Cache\FileCache;

use function is_string;

/** @phpstan-import-type ProcessedData from ConfigureRoutes */
final class FastSettings implements Settings
{
/**
* @param RouteParser|class-string<RouteParser> $routeParser
* @param DataGenerator|class-string<DataGenerator> $dataGenerator
* @param Dispatcher|class-string<Dispatcher> $dispatcher
* @param ConfigureRoutes|class-string<ConfigureRoutes> $routesConfiguration
* @param GenerateUri|class-string<GenerateUri> $uriGenerator
* @param Cache|class-string<Cache>|null $cacheDriver
*/
public function __construct(
private RouteParser|string $routeParser = RouteParser\Std::class,
private DataGenerator|string $dataGenerator = DataGenerator\MarkBased::class,
private Dispatcher|string $dispatcher = Dispatcher\MarkBased::class,
private ConfigureRoutes|string $routesConfiguration = RouteCollector::class,
private GenerateUri|string $uriGenerator = GenerateUri\FromProcessedConfiguration::class,
private Cache|string|null $cacheDriver = FileCache::class,
) {
}

public function getRouteParser(): RouteParser
{
if (is_string($this->routeParser)) {
$this->routeParser = new $this->routeParser();
}

return $this->routeParser;
}

public function getDataGenerator(): DataGenerator
{
if (is_string($this->dataGenerator)) {
$this->dataGenerator = new $this->dataGenerator();
}

return $this->dataGenerator;
}

public function getDispatcher(): Dispatcher
{
if (is_string($this->dispatcher)) {
$this->dispatcher = new $this->dispatcher();
}

return $this->dispatcher;
}

public function getRoutesConfiguration(): ConfigureRoutes
{
if (is_string($this->routesConfiguration)) {
$this->routesConfiguration = new $this->routesConfiguration($this->getRouteParser());
}

return $this->routesConfiguration;
}

public function getUriGenerator(): GenerateUri
{
if (is_string($this->uriGenerator)) {
$this->uriGenerator = new $this->uriGenerator();
}

return $this->uriGenerator;
}

public function getCacheDriver(): ?Cache
{
if (is_string($this->cacheDriver)) {
$this->cacheDriver = new $this->cacheDriver();
}

return $this->cacheDriver;
}

public static function recommended(): self
{
return new self(
RouteParser\Std::class,
DataGenerator\MarkBased::class,
Dispatcher\MarkBased::class,
RouteCollector::class,
GenerateUri\FromProcessedConfiguration::class,
FileCache::class,
);
}

public function disableCache(): self
{
return new self(
$this->routeParser,
$this->dataGenerator,
$this->dispatcher,
$this->routesConfiguration,
$this->uriGenerator,
null,
);
}

/** @param Cache|class-string<Cache> $driver */
public function withCache(Cache|string $driver): self
{
return new self(
$this->routeParser,
$this->dataGenerator,
$this->dispatcher,
$this->routesConfiguration,
$this->uriGenerator,
$driver,
);
}

public function useCharCountDispatcher(): self
{
return $this->useCustomDispatcher(
DataGenerator\CharCountBased::class,
Dispatcher\CharCountBased::class,
);
}

public function useGroupCountDispatcher(): self
{
return $this->useCustomDispatcher(
DataGenerator\GroupCountBased::class,
Dispatcher\GroupCountBased::class,
);
}

public function useGroupPosDispatcher(): self
{
return $this->useCustomDispatcher(
DataGenerator\GroupPosBased::class,
Dispatcher\GroupPosBased::class,
);
}

public function useMarkDispatcher(): self
{
return $this->useCustomDispatcher(
DataGenerator\MarkBased::class,
Dispatcher\MarkBased::class,
);
}

/**
* @param DataGenerator|class-string<DataGenerator> $dataGenerator
* @param Dispatcher|class-string<Dispatcher> $dispatcher
*/
public function useCustomDispatcher(DataGenerator|string $dataGenerator, Dispatcher|string $dispatcher): self
{
return new self(
$this->routeParser,
$dataGenerator,
$dispatcher,
$this->routesConfiguration,
$this->uriGenerator,
$this->cacheDriver,
);
}

/** @param GenerateUri|class-string<GenerateUri> $uriGenerator */
public function withUriGenerator(GenerateUri|string $uriGenerator): self
{
return new self(
$this->routeParser,
$this->dataGenerator,
$this->dispatcher,
$this->routesConfiguration,
$uriGenerator,
$this->cacheDriver,
);
}
}
1 change: 1 addition & 0 deletions src/GenerateUri.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
interface GenerateUri
{
/** @param ParsedRoutes $processedConfiguration */
public function with(array $processedConfiguration): self;

/**
Expand Down
Loading

0 comments on commit 389a549

Please sign in to comment.