Skip to content

Commit cd448f2

Browse files
committed
feat: add new formatter for pretty JSON render
1 parent a90478f commit cd448f2

File tree

3 files changed

+111
-29
lines changed

3 files changed

+111
-29
lines changed

Diff for: src/Component/Formatter/JSONPretty.php

+75-18
Original file line numberDiff line numberDiff line change
@@ -9,52 +9,109 @@
99

1010
namespace Inhere\Console\Component\Formatter;
1111

12-
use Inhere\Console\Component\MessageFormatter;
13-
use Toolkit\Stdlib\Str;
12+
use JsonException;
13+
use Toolkit\Cli\Color\ColorTag;
14+
use Toolkit\Stdlib\Helper\JsonHelper;
15+
use Toolkit\Stdlib\Obj\AbstractObj;
16+
use Toolkit\Stdlib\Str\StrBuffer;
17+
use function array_merge;
18+
use function explode;
19+
use function is_numeric;
1420
use function json_decode;
21+
use function preg_replace_callback;
22+
use function rtrim;
23+
use function str_contains;
24+
use function str_ends_with;
25+
use function trim;
1526

1627
/**
1728
* class JSONPretty
1829
*/
19-
class JSONPretty extends MessageFormatter
30+
class JSONPretty extends AbstractObj
2031
{
32+
public const DEFAULT_THEME = [
33+
'keyName' => 'mga',
34+
'strVal' => 'info',
35+
'intVal' => 'cyan',
36+
'boolVal' => 'red',
37+
];
38+
39+
/**
40+
* @var array{keyName: string, strVal: string, intVal: string, boolVal: string}
41+
*/
42+
protected array $theme = self::DEFAULT_THEME;
43+
2144
/**
22-
* @var array|iterable
45+
* @var int
2346
*/
24-
public $data;
47+
public int $maxDepth = 10;
2548

2649
/**
2750
* @param string $json
2851
*
29-
* @return static
52+
* @return string
53+
* @throws JsonException
3054
*/
31-
public static function newFromString(string $json): self
55+
public function render(string $json): string
3256
{
33-
$self = new self();
34-
$self->setData((array)json_decode($json, true));
57+
$data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
3558

36-
return $self;
59+
return $this->renderData($data);
3760
}
3861

3962
/**
63+
* @param array $data
64+
*
4065
* @return string
4166
*/
42-
public function format(): string
67+
public function renderData(array $data): string
4368
{
44-
$buf = Str\StrBuffer::new();
69+
$buf = StrBuffer::new();
70+
$json = JsonHelper::prettyJSON($data);
4571

46-
foreach ($this->data as $key => $item) {
47-
// TODO
72+
foreach (explode("\n", $json) as $line) {
73+
$trimmed = trim($line);
74+
// start or end chars. eg: {} []
75+
if (!str_contains($trimmed, ': ')) {
76+
$buf->writeln($line);
77+
continue;
78+
}
79+
80+
[$key, $val] = explode(': ', $line);
81+
82+
// format key name.
83+
if ($keyTag = $this->theme['keyName']) {
84+
$key = preg_replace_callback('/"[\w-]+"/', static function ($m) use ($keyTag) {
85+
return ColorTag::wrap($m[0], $keyTag);
86+
}, $key);
87+
}
88+
89+
// has end ',' clear it.
90+
if ($hasEndComma = str_ends_with($val, ',')) {
91+
$val = rtrim($val, ',');
92+
}
93+
94+
// bool val
95+
if ($val === 'true' || $val === 'false') {
96+
$val = ColorTag::wrap($val, $this->theme['boolVal']);
97+
} elseif (is_numeric($val)) { // number
98+
$val = ColorTag::wrap($val, $this->theme['intVal']);
99+
} else { // string
100+
$val = ColorTag::wrap($val, $this->theme['strVal']);
101+
}
102+
103+
$buf->writeln($key . ': ' . $val . ($hasEndComma ? ',' : ''));
48104
}
49105

50-
return $buf->toString();
106+
return $buf->getAndClear();
51107
}
52108

53109
/**
54-
* @param array|iterable $data
110+
* @param array $theme
55111
*/
56-
public function setData($data): void
112+
public function setTheme(array $theme): void
57113
{
58-
$this->data = $data;
114+
$this->theme = array_merge($this->theme, $theme);
59115
}
60116
}
117+

Diff for: src/IO/Input.php

+27-11
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class Input extends AbstractInput
3838
*
3939
* @var resource
4040
*/
41-
protected $inputStream;
41+
protected $stream;
4242

4343
/**
4444
* Input constructor.
@@ -51,15 +51,10 @@ public function __construct(array $args = null)
5151
$args = $_SERVER['argv'];
5252
}
5353

54-
$this->inputStream = Cli::getInputStream();
54+
$this->stream = Cli::getInputStream();
5555
$this->collectInfo($args);
5656
}
5757

58-
public function resetInputStream(): void
59-
{
60-
$this->inputStream = Cli::getInputStream();
61-
}
62-
6358
/**
6459
* @return string
6560
*/
@@ -88,6 +83,14 @@ protected function tokenEscape(string $token): string
8883
return $token;
8984
}
9085

86+
/**
87+
* @return string
88+
*/
89+
public function readAll(): string
90+
{
91+
return File::streamReadAll($this->stream);
92+
}
93+
9194
/**
9295
* Read input information
9396
*
@@ -99,10 +102,23 @@ protected function tokenEscape(string $token): string
99102
public function readln(string $question = '', bool $nl = false): string
100103
{
101104
if ($question) {
102-
fwrite($this->inputStream, $question . ($nl ? "\n" : ''));
105+
fwrite($this->stream, $question . ($nl ? "\n" : ''));
103106
}
104107

105-
return File::streamFgets($this->inputStream);
108+
return File::streamFgets($this->stream);
109+
}
110+
111+
/**
112+
* @return resource
113+
*/
114+
public function getInputStream()
115+
{
116+
return $this->stream;
117+
}
118+
119+
public function resetInputStream(): void
120+
{
121+
$this->stream = Cli::getInputStream();
106122
}
107123

108124
/***********************************************************************************
@@ -128,9 +144,9 @@ public function getFullCommand(): string
128144
/**
129145
* @return resource
130146
*/
131-
public function getInputStream()
147+
public function getStream()
132148
{
133-
return $this->inputStream;
149+
return $this->stream;
134150
}
135151

136152
/**

Diff for: src/IO/Output.php

+9
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Inhere\Console\Console;
1414
use Inhere\Console\Concern\FormatOutputAwareTrait;
1515
use Toolkit\Cli\Cli;
16+
use Toolkit\FsUtil\File;
1617

1718
/**
1819
* Class Output
@@ -130,6 +131,14 @@ public function read(string $question = '', bool $nl = false): string
130131
return Console::read($question, $nl);
131132
}
132133

134+
/**
135+
* @return string
136+
*/
137+
public function readAll(): string
138+
{
139+
return File::streamReadAll($this->outputStream);
140+
}
141+
133142
/**
134143
* Write a message to standard error output stream.
135144
*

0 commit comments

Comments
 (0)