mirror of
https://github.com/ZorgCC/lumen-generators.git
synced 2025-04-27 07:19:25 +03:00
114 lines
3.4 KiB
PHP
114 lines
3.4 KiB
PHP
<?php namespace Wn\Generators\Argument;
|
|
|
|
use Wn\Generators\Argument\ArgumentFormat;
|
|
|
|
|
|
class ArgumentParser {
|
|
|
|
protected $format;
|
|
|
|
public function __construct(ArgumentFormat $format)
|
|
{
|
|
$this->format = $format;
|
|
}
|
|
|
|
public function parse($args)
|
|
{
|
|
return $this->parseToken($args, $this->format);
|
|
}
|
|
|
|
protected function parseToken($token, ArgumentFormat $format){
|
|
switch($format->type) {
|
|
case 'string':
|
|
return $token;
|
|
case 'number':
|
|
return $this->parseNumber($token);
|
|
case 'boolean':
|
|
return $this->parseBoolean($token, $format->name);
|
|
case 'array':
|
|
return $this->parseArray($token, $format->separator, $format->format);
|
|
case 'object':
|
|
return $this->parseObject($token, $format->separator, $format->format);
|
|
default:
|
|
throw new ArgumentParserException("Unknown format type: '{$format->type}'");
|
|
}
|
|
}
|
|
|
|
protected function parseNumber($token)
|
|
{
|
|
if(! is_numeric($token)) {
|
|
throw new ArgumentParserException("Unable to parse '{$token}' as number");
|
|
}
|
|
return $token + 0;
|
|
}
|
|
|
|
protected function parseBoolean($token, $name)
|
|
{
|
|
if(in_array($token, ['yes', 'true', '1', $name])) {
|
|
return true;
|
|
} else if(in_array($token, ['no', 'false', '0', "!{$name}"])){
|
|
return false;
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
protected function parseArray($token, $separator, Format $format)
|
|
{
|
|
$result = [];
|
|
$tokens = explode($separator, $token);
|
|
foreach($tokens as $value) {
|
|
array_push($result, $this->parseToken($value, $format));
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
protected function parseObject($token, $separator, $fields)
|
|
{
|
|
$result = [];
|
|
$tokens = explode($separator, $token);
|
|
$tokensNumber = count($tokens);
|
|
|
|
$requiredFieldsIndexes = [];
|
|
$optionalFieldsIndexes = [];
|
|
foreach($fields as $index => $format) {
|
|
if($format->default === null) {
|
|
array_push($requiredFieldsIndexes, $index);
|
|
} else {
|
|
array_push($optionalFieldsIndexes, $index);
|
|
}
|
|
}
|
|
$requiredFieldsIndexesNumber = count($requiredFieldsIndexes);
|
|
|
|
if($tokensNumber < $requiredFieldsIndexesNumber) {
|
|
$requiredFields = array_map(function($index) use ($fields) {
|
|
return $fields[$index]->name;
|
|
}, $requiredFieldsIndexes);
|
|
$requiredFields = implode($separator, $requiredFields);
|
|
throw new ArgumentParserException("Required field missing: {$tokensNumber} given "
|
|
. "({$token}) but {$requiredFieldsIndexesNumber} required ({$requiredFields})");
|
|
}
|
|
|
|
$givenOptionalFieldsIndexes = array_slice(
|
|
$optionalFieldsIndexes, 0, $tokensNumber - $requiredFieldsIndexesNumber);
|
|
$notPresentFieldsIndexes = array_slice(
|
|
$optionalFieldsIndexes, $tokensNumber - $requiredFieldsIndexesNumber);
|
|
$givenFieldsIndexes = array_merge($requiredFieldsIndexes, $givenOptionalFieldsIndexes);
|
|
sort($givenFieldsIndexes);
|
|
|
|
// Fill the given fields
|
|
for($i = 0; $i < $tokensNumber; $i ++) {
|
|
$fieldFormat = $fields[$givenFieldsIndexes[$i]];
|
|
$result[$fieldFormat->name] = $this->parseToken($tokens[$i], $fieldFormat);
|
|
}
|
|
|
|
// Fill other fields with default values
|
|
foreach($notPresentFieldsIndexes as $index) {
|
|
$fieldFormat = $fields[$index];
|
|
$result[$fieldFormat->name] = $fieldFormat->default;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
} |