Skip to content

Commit

Permalink
implement trait and higher order proxies
Browse files Browse the repository at this point in the history
  • Loading branch information
bert-w committed May 8, 2024
1 parent e18e284 commit da50f82
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 68 deletions.
24 changes: 8 additions & 16 deletions src/Illuminate/Config/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
use ArrayAccess;
use Illuminate\Contracts\Config\Repository as ConfigContract;
use Illuminate\Support\Arr;
use Illuminate\Support\StrongTypeable;
use Illuminate\Support\Traits\Macroable;
use Illuminate\Support\Traits\StrongTypeable;

class Repository implements ArrayAccess, ConfigContract
{
use Macroable;
use Macroable,
StrongTypeable;

/**
* All of the configuration items.
Expand All @@ -19,13 +20,6 @@ class Repository implements ArrayAccess, ConfigContract
*/
protected $items = [];

/**
* The strong typeable instance for retrieving configuration values.
*
* @var StrongTypeable
*/
protected StrongTypeable $typeable;

/**
* Create a new configuration repository.
*
Expand All @@ -35,8 +29,6 @@ class Repository implements ArrayAccess, ConfigContract
public function __construct(array $items = [])
{
$this->items = $items;

$this->typeable = new StrongTypeable($this, 'get');
}

/**
Expand Down Expand Up @@ -96,7 +88,7 @@ public function getMany($keys)
*/
public function string(string $key, $default = null): string
{
return $this->typeable->string($key, $default);
return $this->typed()->get->string($key, $default);
}

/**
Expand All @@ -108,7 +100,7 @@ public function string(string $key, $default = null): string
*/
public function integer(string $key, $default = null): int
{
return $this->typeable->integer($key, $default);
return $this->typed()->get->integer($key, $default);
}

/**
Expand All @@ -120,7 +112,7 @@ public function integer(string $key, $default = null): int
*/
public function float(string $key, $default = null): float
{
return $this->typeable->float($key, $default);
return $this->typed()->get->float($key, $default);
}

/**
Expand All @@ -132,7 +124,7 @@ public function float(string $key, $default = null): float
*/
public function boolean(string $key, $default = null): bool
{
return $this->typeable->boolean($key, $default);
return $this->typed()->get->boolean($key, $default);
}

/**
Expand All @@ -144,7 +136,7 @@ public function boolean(string $key, $default = null): bool
*/
public function array(string $key, $default = null): array
{
return $this->typeable->array($key, $default);
return $this->typed()->get->array($key, $default);
}

/**
Expand Down
22 changes: 3 additions & 19 deletions src/Illuminate/Console/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use Illuminate\Console\View\Components\Factory;
use Illuminate\Contracts\Console\Isolatable;
use Illuminate\Support\Traits\Macroable;
use Illuminate\Support\Typeable;
use Illuminate\Support\Traits\Typeable;
use Symfony\Component\Console\Command\Command as SymfonyCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
Expand All @@ -19,7 +19,8 @@ class Command extends SymfonyCommand
Concerns\InteractsWithIO,
Concerns\InteractsWithSignals,
Concerns\PromptsForMissingInput,
Macroable;
Macroable,
Typeable;

/**
* The Laravel application instance.
Expand Down Expand Up @@ -84,20 +85,6 @@ class Command extends SymfonyCommand
*/
protected $aliases;

/**
* The typeable instance for retrieving command arguments.
*
* @var Typeable<Command>
*/
public Typeable $argument;

/**
* The typeable instance for retrieving command options.
*
* @var Typeable<Command>
*/
public Typeable $option;

/**
* Create a new console command instance.
*
Expand Down Expand Up @@ -138,9 +125,6 @@ public function __construct()
if ($this instanceof Isolatable) {
$this->configureIsolation();
}

$this->argument = new Typeable($this, 'argument');
$this->option = new Typeable($this, 'option');
}

/**
Expand Down
8 changes: 4 additions & 4 deletions src/Illuminate/Http/Concerns/InteractsWithInput.php
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ public function str($key, $default = null)
*/
public function string($key, $default = null)
{
return $this->typeable->string($key, $default);
return $this->typed()->input->string($key, $default);
}

/**
Expand All @@ -342,7 +342,7 @@ public function string($key, $default = null)
*/
public function boolean($key = null, $default = false)
{
return $this->typeable->boolean($key, $default);
return $this->typed()->input->boolean($key, $default);
}

/**
Expand All @@ -354,7 +354,7 @@ public function boolean($key = null, $default = false)
*/
public function integer($key, $default = 0)
{
return $this->typeable->integer($key, $default);
return $this->typed()->input->integer($key, $default);
}

/**
Expand All @@ -366,7 +366,7 @@ public function integer($key, $default = 0)
*/
public function float($key, $default = 0.0)
{
return $this->typeable->float($key, $default);
return $this->typed()->input->float($key, $default);
}

/**
Expand Down
14 changes: 2 additions & 12 deletions src/Illuminate/Http/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Closure;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Session\SymfonySessionDecorator;
use Illuminate\Support;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Support\Traits\Macroable;
Expand All @@ -27,13 +28,9 @@ class Request extends SymfonyRequest implements Arrayable, ArrayAccess
Concerns\InteractsWithContentTypes,
Concerns\InteractsWithFlashData,
Concerns\InteractsWithInput,
Support\Traits\Typeable,
Macroable;

/**
* @var Typeable<Request>
*/
public Typeable $typeable;

/**
* The decoded JSON content for the request.
*
Expand Down Expand Up @@ -62,13 +59,6 @@ class Request extends SymfonyRequest implements Arrayable, ArrayAccess
*/
protected $routeResolver;

public function __construct(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null)
{
parent::__construct($query, $request, $attributes, $cookies, $files, $server, $content);

$this->typeable = $this->typeable();
}

/**
* Create a new Illuminate HTTP request from server variables.
*
Expand Down
11 changes: 6 additions & 5 deletions src/Illuminate/Routing/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,18 @@
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Support\Traits\Macroable;
use Illuminate\Support\Typeable;
use Illuminate\Support\Traits\Typeable;
use Laravel\SerializableClosure\SerializableClosure;
use LogicException;
use Symfony\Component\Routing\Route as SymfonyRoute;

class Route
{
use CreatesRegularExpressionRouteConstraints, FiltersControllerMiddleware, Macroable, ResolvesRouteDependencies;
use CreatesRegularExpressionRouteConstraints,
FiltersControllerMiddleware,
Macroable,
ResolvesRouteDependencies,
Typeable;

/**
* The URI pattern the route responds to.
Expand Down Expand Up @@ -131,8 +135,6 @@ class Route
*/
public $compiled;

public Typeable $typeable;

/**
* The router instance used by the route.
*
Expand Down Expand Up @@ -174,7 +176,6 @@ public function __construct($methods, $uri, $action)
$this->uri = $uri;
$this->methods = (array) $methods;
$this->action = Arr::except($this->parseAction($action), ['prefix']);
$this->typeable = new Typeable($this, 'parameter');

if (in_array('GET', $this->methods) && ! in_array('HEAD', $this->methods)) {
$this->methods[] = 'HEAD';
Expand Down
28 changes: 28 additions & 0 deletions src/Illuminate/Support/HigherOrderStrongTypeableProxy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Illuminate\Support;

class HigherOrderStrongTypeableProxy
{
/**
* Create a new strong-typeable proxy instance.
*
* @param mixed $target
* @return void
*/
public function __construct(protected mixed $target)
{
//
}

/**
* Dynamically access properties from the target.
*
* @param string $key
* @return \Illuminate\Support\StrongTypeable
*/
public function __get(string $key): StrongTypeable
{
return new StrongTypeable($this->target, $key);
}
}
28 changes: 28 additions & 0 deletions src/Illuminate/Support/HigherOrderTypeableProxy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Illuminate\Support;

class HigherOrderTypeableProxy
{
/**
* Create a new typeable proxy instance.
*
* @param mixed $target
* @return void
*/
public function __construct(protected mixed $target)
{
//
}

/**
* Dynamically access properties from the target.
*
* @param string $key
* @return \Illuminate\Support\Typeable
*/
public function __get(string $key): Typeable
{
return new Typeable($this->target, $key);
}
}
18 changes: 18 additions & 0 deletions src/Illuminate/Support/Traits/StrongTypeable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Illuminate\Support\Traits;

use Illuminate\Support\HigherOrderStrongTypeableProxy;

trait StrongTypeable
{
/**
* Retrieve a higher order strong-typeable proxy.
*
* @return HigherOrderStrongTypeableProxy
*/
public function typed(): HigherOrderStrongTypeableProxy
{
return new HigherOrderStrongTypeableProxy($this);
}
}
18 changes: 18 additions & 0 deletions src/Illuminate/Support/Traits/Typeable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Illuminate\Support\Traits;

use Illuminate\Support\HigherOrderTypeableProxy;

trait Typeable
{
/**
* Retrieve a higher order typeable proxy.
*
* @return HigherOrderTypeableProxy
*/
public function typed(): HigherOrderTypeableProxy
{
return new HigherOrderTypeableProxy($this);
}
}
22 changes: 10 additions & 12 deletions tests/Support/SupportTypeableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

namespace Illuminate\Tests\Support;

use Illuminate\Config\Repository as Config;
use Illuminate\Console\Application;
use Illuminate\Console\Command;
use Illuminate\Container\Container;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Http\Request;
use Illuminate\Routing\Route;
Expand Down Expand Up @@ -45,16 +43,16 @@ public function testTypeableRoute(): void

$route->bind($request);

$this->assertInstanceOf(Stringable::class, $route->typeable->string('userid'));
$this->assertEquals('1234', $route->typeable->string('userid'));
$this->assertInstanceOf(Stringable::class, $route->typed()->parameter->string('userid'));
$this->assertEquals('1234', $route->typed()->parameter->string('userid'));

$this->assertIsBool($boolean = $route->typeable->boolean('unexisting'));
$this->assertIsBool($boolean = $route->typed()->parameter->boolean('unexisting'));
$this->assertFalse($boolean);

$this->assertIsInt($integer = $route->typeable->integer('userid'));
$this->assertIsInt($integer = $route->typed()->parameter->integer('userid'));
$this->assertEquals(1234, $integer);

$this->assertIsFloat($float = $route->typeable->float('userid'));
$this->assertIsFloat($float = $route->typed()->parameter->float('userid'));
$this->assertEquals(1234.0, $float);
}

Expand All @@ -75,19 +73,19 @@ public function testTypeableCommand(): void

$command->run($input, $output);

$this->assertInstanceOf(Stringable::class, $string = $command->option->string('userid'));
$this->assertInstanceOf(Stringable::class, $string = $command->typed()->option->string('userid'));
$this->assertEquals('4', $string);

$this->assertIsBool($boolean = $command->option->boolean('all'));
$this->assertIsBool($boolean = $command->typed()->option->boolean('all'));
$this->assertTrue($boolean);

$this->assertIsInt($integer = $command->option->integer('userid'));
$this->assertIsInt($integer = $command->typed()->option->integer('userid'));
$this->assertEquals(4, $integer);

$this->assertIsFloat($float = $command->option->float('userid'));
$this->assertIsFloat($float = $command->typed()->option->float('userid'));
$this->assertEquals(4.0, $float);

$this->assertIsArray($array = $command->argument->array('theargument'));
$this->assertIsArray($array = $command->typed()->argument->array('theargument'));
$this->assertSame(['first', 'second'], $array);
}
}
Expand Down

0 comments on commit da50f82

Please sign in to comment.