Add configurable and state

This commit is contained in:
Aidan Woods 2019-01-20 02:12:46 +00:00
parent 7746c9df06
commit 1f06b47e6c
No known key found for this signature in database
GPG Key ID: 9A6A8EFAA512BBB9
2 changed files with 104 additions and 0 deletions

9
src/Configurable.php Normal file
View File

@ -0,0 +1,9 @@
<?php
namespace Erusev\Parsedown;
interface Configurable
{
/** @return static */
public static function default();
}

95
src/State.php Normal file
View File

@ -0,0 +1,95 @@
<?php
namespace Erusev\Parsedown;
use Erusev\Parsedown\AST\StateRenderable;
use Erusev\Parsedown\Html\Renderable;
final class State
{
/**
* @var array<class-string<Configurable>, Configurable>
* */
private $state;
/**
* @param Configurable[] $Configurables
*/
public function __construct(array $Configurables = [])
{
$this->state = \array_combine(
\array_map(
/** @return class-string */
function (Configurable $C) { return \get_class($C); },
$Configurables
),
$Configurables
);
}
/**
* @return self
*/
public function setting(Configurable $C)
{
return new self([\get_class($C) => $C] + $this->state);
}
/**
* @return self
*/
public function mergingWith(State $State)
{
return new self($State->state + $this->state);
}
/**
* @template T as Configurable
* @template-typeof T $configurableClass
* @param class-string<Configurable> $configurableClass
* @return T|null
* */
public function get($configurableClass)
{
return (isset($this->state[$configurableClass])
? $this->state[$configurableClass]
: null
);
}
/**
* @template T as Configurable
* @template-typeof T $configurableClass
* @param class-string<Configurable> $configurableClass
* @return T
* */
public function getOrDefault($configurableClass)
{
return (isset($this->state[$configurableClass])
? $this->state[$configurableClass]
: $configurableClass::default()
);
}
public function __clone()
{
$this->state = \array_map(
/** @return Configurable */
function (Configurable $C) { return clone($C); },
$this->state
);
}
/**
* @param StateRenderable[] $StateRenderables
* @return Renderable[]
*/
public function applyTo(array $StateRenderables)
{
return \array_map(
/** @return Renderable */
function (StateRenderable $SR) { return $SR->renderable($this); },
$StateRenderables
);
}
}