Skip to content

Commit 80afd7a

Browse files
committed
refactor(options): Improve option normalization logic
- Streamline normalization of options in the HasOptions trait - Ensure string keys are used consistently in the normalization process - Improve error handling by strictly checking array type for options - Enhance test case to ensure normalization handles boolean values
1 parent febfebc commit 80afd7a

File tree

5 files changed

+49
-44
lines changed

5 files changed

+49
-44
lines changed

baselines/function.alreadyNarrowedType.neon

Lines changed: 0 additions & 8 deletions
This file was deleted.

baselines/loader.neon

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
# total 4 errors
1+
# total 3 errors
22
includes:
33
- disallowed.function.neon
4-
- function.alreadyNarrowedType.neon
54
- new.static.neon
65
- typePerfect.narrowPublicClassMethodParamType.neon

phpstan.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,13 @@ parameters:
6666
message: 'use config() instead'
6767
ignoreErrors:
6868
# - identifier: argument.templateType
69+
# - identifier: cast.string
6970
# - identifier: method.nonObject
7071
# - identifier: missingType.generics
7172
# - identifier: return.void
7273
# - identifier: typePerfect.noMixedMethodCaller
7374
- identifier: argument.type
7475
- identifier: binaryOp.invalid
75-
- identifier: cast.string
7676
- identifier: encapsedStringPart.nonString
7777
- identifier: logicalAnd.resultUnused
7878
- identifier: missingType.iterableValue

src/Concerns/HasOptions.php

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,6 +1275,7 @@ public function exceptOption(string $name): self
12751275
}
12761276

12771277
/**
1278+
* @throws \JsonException
12781279
* @throws \Guanguans\SoarPHP\Exceptions\InvalidOptionException
12791280
*/
12801281
protected function getNormalizedOptions(): array
@@ -1283,58 +1284,71 @@ protected function getNormalizedOptions(): array
12831284
}
12841285

12851286
/**
1287+
* @throws \JsonException
12861288
* @throws \Guanguans\SoarPHP\Exceptions\InvalidOptionException
12871289
*/
12881290
protected function normalizeOptions(array $options): array
12891291
{
1290-
return array_reduce_with_keys($options, function (array $normalizedOptions, mixed $value, int|string $name): array {
1291-
if ($normalizedOption = $this->normalizeOption($name, $value)) {
1292-
$normalizedOptions[\is_int($name) ? (string) $value : $name] = $normalizedOption;
1293-
}
1292+
return array_reduce_with_keys(
1293+
$options,
1294+
function (array $normalizedOptions, mixed $value, string $name): array {
1295+
$normalizedOptions[$name] = $this->normalizeOption($name, $value);
12941296

1295-
return $normalizedOptions;
1296-
}, []);
1297+
return $normalizedOptions;
1298+
},
1299+
[]
1300+
);
12971301
}
12981302

12991303
/**
1304+
* @throws \JsonException
13001305
* @throws \Guanguans\SoarPHP\Exceptions\InvalidOptionException
13011306
*/
1302-
protected function normalizeOption(int|string $name, mixed $value): string
1307+
protected function normalizeOption(string $name, mixed $value): string
13031308
{
1304-
$converter = function (mixed $value) {
1305-
/** @noinspection UselessIsComparisonInspection */
1306-
\is_callable($value) and !(\is_string($value) && \function_exists($value)) and $value = $value($this);
1307-
true === $value and $value = 'true';
1308-
false === $value and $value = 'false';
1309-
0 === $value and $value = '0';
1310-
1311-
return $value;
1312-
};
1309+
if (
1310+
\is_array($value)
1311+
&& !($value['disable'] ?? false)
1312+
&& \in_array($name, ['-test-dsn', '-online-dsn'], true)
1313+
) {
1314+
$value = "{$value['username']}:{$value['password']}@{$value['host']}:{$value['port']}/{$value['dbname']}";
1315+
}
13131316

1314-
$value = $converter($value);
1317+
return null === ($value = $this->normalizeValue($value)) ? $name : "$name=$value";
1318+
}
13151319

1316-
if (null === $value) {
1317-
return $name;
1320+
/**
1321+
* @throws \JsonException
1322+
* @throws \Guanguans\SoarPHP\Exceptions\InvalidOptionException
1323+
*/
1324+
private function normalizeValue(mixed $value): ?string
1325+
{
1326+
if (\is_string($value) || null === $value) {
1327+
return $value;
13181328
}
13191329

1320-
if (\is_scalar($value) || (\is_object($value) && method_exists($value, '__toString'))) {
1321-
if (\is_int($name)) {
1322-
return (string) $value;
1323-
}
1324-
1325-
return "$name=$value";
1330+
if (\is_scalar($value)) {
1331+
return json_encode($value, \JSON_THROW_ON_ERROR);
13261332
}
13271333

1328-
if (\is_array($value)) {
1329-
if (!($value['disable'] ?? false) && \in_array($name, ['-test-dsn', '-online-dsn'], true)) {
1330-
$dsn = "{$value['username']}:{$value['password']}@{$value['host']}:{$value['port']}/{$value['dbname']}";
1334+
if (\is_callable($value)) {
1335+
return $this->normalizeValue($value($this));
1336+
}
13311337

1332-
return "$name=$dsn";
1333-
}
1338+
if (\is_object($value) && method_exists($value, '__toString')) {
1339+
return (string) $value;
1340+
}
13341341

1335-
return "$name=".implode(',', array_map($converter, $value));
1342+
if (!\is_array($value)) {
1343+
throw new InvalidOptionException(\sprintf('Invalid option type [%s].', \gettype($value)));
13361344
}
13371345

1338-
throw new InvalidOptionException(\sprintf('Invalid configuration type(%s).', \gettype($value)));
1346+
return implode(
1347+
',',
1348+
array_filter(
1349+
array_map(fn (mixed $val): ?string => $this->normalizeValue($val), $value),
1350+
static fn (?string $v): bool => null !== $v
1351+
)
1352+
);
13391353
}
13401354
}

tests/Concerns/HasOptionsTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@
110110
expect(fn (): array => $this->getNormalizedOptions())
111111
->call(Soar::create([
112112
'foo' => 'bar',
113-
'-verbose',
113+
'-verbose' => true,
114114
'-test-dsn' => [
115115
'host' => 'you_host',
116116
'port' => 'you_port',

0 commit comments

Comments
 (0)