Copy <?php
include_once('ArgsException.php');
include_once('ArgumentMarshaler/ArgumentMarshalerCollection.php');
include_once('ArgumentMarshaler/BooleanArgumentMarshaler.php');
include_once('ArgumentMarshaler/FloatArgumentMarshaler.php');
include_once('ArgumentMarshaler/IntegerArgumentMarshaler.php');
include_once('ArgumentMarshaler/StringArgumentMarshaler.php');
class Args
{
private const SCHEMA_SEPARATOR = ',';
/** @var ArgumentMarshalerCollection */
private $marshalers;
/** @var string[] */
private $args = [];
/** @var string[] */
private $argsFound = [];
/**
* Args constructor.
* @param string $schema
* @param string[] $args
* @throws ArgsException
*/
public function __construct(string $schema, array $args)
{
$this->marshalers = new ArgumentMarshalerCollection();
$this->args = $args;
$this->parseSchema($schema);
$this->parseArgumentStrings();
}
/**
* @param string $schema
* @return void
* @throws ArgsException
*/
private function parseSchema(string $schema): void
{
$elements = explode(self::SCHEMA_SEPARATOR, $schema);
foreach ($elements as $element) {
if (strlen($element) > 0) {
$this->parseSchemaElement(trim($element));
}
}
}
/**
* @param string $element
* @return void
* @throws ArgsException
*/
private function parseSchemaElement(string $element): void
{
$elementId = $element[0];
$elementTail = substr($element, 1);
$this->validateSchemaElementId($elementId);
if (strlen($elementTail) === 0) {
$this->marshalers->put($elementId, new BooleanArgumentMarshaler());
} elseif ($elementTail === StringArgumentMarshaler::SYMBOL) {
$this->marshalers->put($elementId, new StringArgumentMarshaler());
} elseif ($elementTail === IntegerArgumentMarshaler::SYMBOL) {
$this->marshalers->put($elementId, new IntegerArgumentMarshaler());
} elseif ($elementTail === FloatArgumentMarshaler::SYMBOL) {
$this->marshalers->put($elementId, new FloatArgumentMarshaler());
} else {
throw new ArgsException(ArgsException::INVALID_ARGUMENT_FORMAT, $elementId, $elementTail);
}
}
/**
* @param string $elementId
* @return void
* @throws ArgsException
*/
private function validateSchemaElementId(string $elementId): void
{
if (!ctype_alpha($elementId)) {
throw new ArgsException(ArgsException::INVALID_ARGUMENT_NAME, $elementId);
}
}
/**
* @return void
* @throws ArgsException
*/
private function parseArgumentStrings(): void
{
foreach ($this->args as $arg) {
if (substr($arg, 0, 1) === '-') {
$this->parseArgumentCharacters(substr($arg, 1));
}
}
}
/**
* @param string $argChars
* @return void
* @throws ArgsException
*/
private function parseArgumentCharacters(string $argChars): void
{
for ($i = 0; $i < strlen($argChars); $i++) {
$this->parseArgumentCharacter($argChars[$i]);
}
}
/**
* @param string $argChar
* @return void
* @throws ArgsException
*/
private function parseArgumentCharacter(string $argChar): void
{
$am = $this->marshalers->get($argChar);
$am->set(next($this->args));
$this->argsFound[] = $argChar;
}
/**
* @param string $arg
* @return bool
*/
public function has(string $arg): bool
{
return in_array($arg, $this->argsFound);
}
/**
* @param string $arg
* @return bool
* @throws ArgsException
*/
public function getBoolean(string $arg): bool
{
return BooleanArgumentMarshaler::getValue($this->marshalers->get($arg));
}
/**
* @param string $arg
* @return string
* @throws ArgsException
*/
public function getString(string $arg): string
{
return StringArgumentMarshaler::getValue($this->marshalers->get($arg));
}
/**
* @param string $arg
* @return int
* @throws ArgsException
*/
public function getInteger(string $arg): int
{
return IntegerArgumentMarshaler::getValue($this->marshalers->get($arg));
}
/**
* @param string $arg
* @return float
* @throws ArgsException
*/
public function getFloat(string $arg): float
{
return FloatArgumentMarshaler::getValue($this->marshalers->get($arg));
}
}