From 3661025aa3d08821856dafef1137a382a7256d1d Mon Sep 17 00:00:00 2001 From: Inhere Date: Sun, 22 May 2022 12:10:01 +0800 Subject: [PATCH] fix: fix some error on use json generate go code --- .../Attach/Golang/GenerateStructCmd.php | 27 ++++++-- app/Lib/Parser/Item/FieldItem.php | 4 +- app/Lib/Parser/Text/Json5ItemParser.php | 51 ++++++--------- app/Lib/Parser/Text/JsonItemParser.php | 62 +++++++++++++++++-- 4 files changed, 99 insertions(+), 45 deletions(-) diff --git a/app/Console/Attach/Golang/GenerateStructCmd.php b/app/Console/Attach/Golang/GenerateStructCmd.php index accaaf5..6119ebb 100644 --- a/app/Console/Attach/Golang/GenerateStructCmd.php +++ b/app/Console/Attach/Golang/GenerateStructCmd.php @@ -14,13 +14,16 @@ use Inhere\Kite\Lib\Parser\Text\TextItemParser; use Inhere\Kite\Lib\Parser\Text\TextParser; use InvalidArgumentException; +use PhpPkg\Config\ConfigUtil; use Toolkit\PFlag\FlagsParser; use Toolkit\PFlag\FlagType; use Toolkit\PFlag\Validator\EnumValidator; +use Toolkit\Stdlib\Json; use Toolkit\Stdlib\Str; use Toolkit\Stdlib\Util\Stream\ListStream; use function array_filter; use function array_merge; +use function get_class; use function str_replace; /** @@ -31,7 +34,7 @@ class GenerateStructCmd extends Command { protected static string $name = 'struct'; - protected static string $desc = 'quick generate an go struct by json, text and more'; + protected static string $desc = 'quick generate an go struct by json, yaml, text and more'; public static function aliases(): array { @@ -51,14 +54,16 @@ protected function configFlags(FlagsParser $fs): void '--is, --item-sep' => 'The item sep char. default is NL(newline).', '--vn, --value-num' => 'int;set the item value number(cols number), default get from first item.', '--vs, --value-sep' => 'The item value sep char for "space" parser. default is SPACE', - '--parser, --item-parser' => [ + '-t, --type, --parser' => [ 'type' => FlagType::STRING, 'desc' => 'The item parser name for difference data type. TYPE: space, text - parser substr by space, use for text data. - json, json5 - parser json(5) line', + json, json5 - parser json(5) line + yaml, yml - convert to json then parse. +', 'default' => 'text', - 'validator' => EnumValidator::new(['json', 'json5', 'text', 'space']) + 'validator' => EnumValidator::new(['json', 'json5', 'text', 'space', 'yaml', 'yml']) ] ]); @@ -94,10 +99,18 @@ protected function execute(Input $input, Output $output): void $p->setFields(Str::explode($nameString, ',')); } - switch ($fs->getOpt('item-parser')) { + switch ($fs->getOpt('parser')) { + case 'yml': + case 'yaml': + $data = ConfigUtil::parseYamlString($source); + $p->setText(Json::pretty($data)); + $itemParser = new Json5ItemParser; + $itemParser->setKeyField('name'); + break; case 'json': case 'json5': $itemParser = new Json5ItemParser; + $itemParser->setKeyField('name'); break; case 'text': case 'space': @@ -111,6 +124,9 @@ protected function execute(Input $input, Output $output): void $p->parse(); $data = $p->getData(true); // $output->aList($data, 'parsed field list'); + if (!$data) { + throw new InvalidArgumentException('no field data collected from the source.'); + } $lang = GenCodeFactory::LANG_GO; @@ -126,6 +142,7 @@ protected function execute(Input $input, Output $output): void $config = array_merge($config, array_filter([ 'tplDir' => $tplDir, 'tplFile' => $tplFile, + 'parser' => get_class($itemParser), ])); $output->aList($config); diff --git a/app/Lib/Parser/Item/FieldItem.php b/app/Lib/Parser/Item/FieldItem.php index 5b7b464..762c52d 100644 --- a/app/Lib/Parser/Item/FieldItem.php +++ b/app/Lib/Parser/Item/FieldItem.php @@ -23,12 +23,12 @@ class FieldItem extends AbstractObj implements JsonSerializable /** * @var string */ - public string $name; + public string $name = ''; /** * @var string */ - public string $type; + public string $type = ''; /** * sub-elem type on type is array diff --git a/app/Lib/Parser/Text/Json5ItemParser.php b/app/Lib/Parser/Text/Json5ItemParser.php index c9adb3d..048e730 100644 --- a/app/Lib/Parser/Text/Json5ItemParser.php +++ b/app/Lib/Parser/Text/Json5ItemParser.php @@ -2,8 +2,8 @@ namespace Inhere\Kite\Lib\Parser\Text; +use Toolkit\Stdlib\Str; use function in_array; -use function preg_match; use function preg_replace; use function strpos; use function substr; @@ -11,31 +11,8 @@ /** * class Json5LineParser - parse json5 line, get field and comments */ -class Json5ItemParser +class Json5ItemParser extends JsonItemParser { - public const KEY_FIELD = 'field'; - public const KEY_COMMENT = 'comment'; - - /** - * exclude fields - * - * @var array - */ - public array $exclude = []; - - /** - * @param array $exclude - * - * @return static - */ - public static function new(array $exclude = []): self - { - $self = new self(); - - $self->exclude = $exclude; - return $self; - } - /** * @param string $line * @@ -56,6 +33,13 @@ public function __invoke(string $line): array { $pos = strpos($line, '//'); if ($pos < 1) { + // fallback parse json line + if ($matches = self::matchField($line)) { + return [ + $this->keyField => $matches[1], + $this->keyComment => Str::toLowerWords($matches[1]), + ]; + } return []; } @@ -69,24 +53,25 @@ public function __invoke(string $line): array } // match field - if (!preg_match('/^\s*[\'"]?([a-zA-Z][\w_]+)/', $line, $matches)) { + if (!$matches = self::matchField($line)) { return []; } - $field = $matches[0]; - $item = [ - 'field' => $field, - ]; + $field = $matches[1]; if ($this->exclude && in_array($field, $this->exclude, true)) { return []; } + $item = [ + $this->keyField => $field, + $this->keyComment => Str::toLowerWords($field), + ]; + // get comments - if (!$comment = trim(substr($line, $pos + 2))) { - return []; + if ($comment = trim(substr($line, $pos + 2))) { + $item[$this->keyComment] = $comment; } - $item['comment'] = $comment; return $item; } } diff --git a/app/Lib/Parser/Text/JsonItemParser.php b/app/Lib/Parser/Text/JsonItemParser.php index dda0842..089b828 100644 --- a/app/Lib/Parser/Text/JsonItemParser.php +++ b/app/Lib/Parser/Text/JsonItemParser.php @@ -2,7 +2,9 @@ namespace Inhere\Kite\Lib\Parser\Text; +use Toolkit\Stdlib\Str; use function preg_match; +use function str_contains; /** * class JsonItemParser @@ -11,19 +13,69 @@ */ class JsonItemParser { - public const KEY_FIELD = 'field'; + public string $keyField = 'field'; + + public string $keyComment = 'comment'; + + /** + * exclude fields + * + * @var array + */ + public array $exclude = []; + + /** + * @param array $exclude + * + * @return static + */ + public static function new(array $exclude = []): self + { + $self = new self(); + + $self->exclude = $exclude; + return $self; + } + + /** + * @param string $line + * + * @return array + */ + public function __invoke(string $line): array + { + if ($matches = self::matchField($line)) { + return []; + } + + return [ + $this->keyField => $matches[1], + $this->keyComment => Str::toLowerWords($matches[1]), + ]; + } /** - * @param string $str + * @param string $line * * @return array */ - public function __invoke(string $str): array + public static function matchField(string $line): array { - if (!preg_match('/[a-zA-Z][\w_]+/', $str, $matches)) { + // is value of array. + if (!str_contains($line, '": ')) { return []; } - return [self::KEY_FIELD => $matches[1]]; + $ok = preg_match('/^\s*[\'"]?([a-zA-Z][\w_]+)/', $line, $matches); + + return $ok ? $matches : []; + } + + /** + * @param string $keyField + */ + public function setKeyField(string $keyField): void + { + $this->keyField = $keyField; } }