Skip to content

Commit 016de79

Browse files
committed
refactor(ConfigToml): Add fromString() factory
1 parent d7ed634 commit 016de79

File tree

3 files changed

+47
-47
lines changed

3 files changed

+47
-47
lines changed

src/Common/EnvConfig/Client/ConfigToml.php

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,21 @@
4545
*/
4646
final class ConfigToml
4747
{
48-
/**
49-
* @var array<non-empty-string, ConfigProfile>
50-
*/
51-
public readonly array $profiles;
48+
public function __construct(
49+
/**
50+
* @var array<non-empty-string, ConfigProfile>
51+
*/
52+
public readonly array $profiles,
53+
) {}
5254

5355
/**
5456
* @param string $toml TOML content
55-
* @param bool $strict Whether to use strict parsing
5657
*/
57-
public function __construct(
58-
string $toml,
59-
) {
58+
public static function fromString(string $toml): self
59+
{
6060
\class_exists(Toml::class) or throw new TomlParserNotFoundException();
6161
$data = Toml::parseToArray($toml);
62-
$this->profiles = $this->parseProfiles($data['profile'] ?? []);
62+
return new self(self::parseProfiles($data['profile'] ?? []));
6363
}
6464

6565
/**
@@ -70,7 +70,7 @@ public function __construct(
7070
* @return false Returns false if the assertion passes
7171
* @throws \InvalidArgumentException If the assertion fails.
7272
*/
73-
private function notAssert(bool $condition, string $message): bool
73+
private static function notAssert(bool $condition, string $message): bool
7474
{
7575
$condition or throw new \InvalidArgumentException($message);
7676
return false;
@@ -83,25 +83,25 @@ private function notAssert(bool $condition, string $message): bool
8383
* @return array<non-empty-string, ConfigProfile>
8484
* @throws \InvalidArgumentException If the configuration is invalid.
8585
*/
86-
private function parseProfiles(mixed $profile): array
86+
private static function parseProfiles(mixed $profile): array
8787
{
88-
if ($this->notAssert(\is_array($profile), 'The `profile` section must be an array.')) {
88+
if (self::notAssert(\is_array($profile), 'The `profile` section must be an array.')) {
8989
return [];
9090
}
9191

9292
$result = [];
9393
foreach ($profile as $name => $config) {
9494
if (
95-
$this->notAssert(\is_array($config), 'Each profile configuration must be an array.')
96-
|| $this->notAssert(\strlen($name) > 0, 'Profile name must be a non-empty string.')
95+
self::notAssert(\is_array($config), 'Each profile configuration must be an array.')
96+
|| self::notAssert(\strlen($name) > 0, 'Profile name must be a non-empty string.')
9797
) {
9898
continue;
9999
}
100100

101101
$apiKey = $config['api_key'] ?? null;
102102
$tls = $config['tls'] ?? null;
103103
$tlsConfig = match (true) {
104-
\is_array($tls) => $this->parseTls($tls),
104+
\is_array($tls) => self::parseTls($tls),
105105
$apiKey !== null || $tls === true => new ConfigTls(),
106106
default => new ConfigTls(disabled: true),
107107
};
@@ -112,33 +112,33 @@ private function parseProfiles(mixed $profile): array
112112
apiKey: $apiKey,
113113
tlsConfig: $tlsConfig,
114114
grpcMeta: $config['grpc_meta'] ?? [],
115-
codecConfig: isset($config['codec']) && \is_array($config['codec']) ? $this->parseCodec($config['codec']) : null,
115+
codecConfig: isset($config['codec']) && \is_array($config['codec']) ? self::parseCodec($config['codec']) : null,
116116
);
117117
}
118118

119119
return $result;
120120
}
121121

122-
private function parseTls(array $tls): ?ConfigTls
122+
private static function parseTls(array $tls): ?ConfigTls
123123
{
124124
// cert_data and cert_path must not be used together
125125
$rootCert = $tls['server_ca_cert_path'] ?? $tls['server_ca_cert_data'] ?? null;
126126
$privateKey = $tls['client_key_path'] ?? $tls['client_key_data'] ?? null;
127127
$certChain = $tls['client_cert_path'] ?? $tls['client_cert_data'] ?? null;
128128

129-
$rootCert === null or $this->notAssert(
129+
$rootCert === null or self::notAssert(
130130
isset($tls['server_ca_cert_path']) xor isset($tls['server_ca_cert_data']),
131131
'Cannot specify both `server_ca_cert_path` and `server_ca_cert_data`.',
132132
);
133-
$privateKey === null or $this->notAssert(
133+
$privateKey === null or self::notAssert(
134134
isset($tls['client_key_path']) xor isset($tls['client_key_data']),
135135
'Cannot specify both `client_key_path` and `client_key_data`.',
136136
);
137-
$certChain === null or $this->notAssert(
137+
$certChain === null or self::notAssert(
138138
isset($tls['client_cert_path']) xor isset($tls['client_cert_data']),
139139
'Cannot specify both `client_cert_path` and `client_cert_data`.',
140140
);
141-
$this->notAssert(
141+
self::notAssert(
142142
($privateKey === null) === ($certChain === null),
143143
'Both `client_key_*` and `client_cert_*` must be specified for mTLS.',
144144
);
@@ -158,7 +158,7 @@ private function parseTls(array $tls): ?ConfigTls
158158
* @param array $codec Codec configuration array
159159
* @return ConfigCodec|null Parsed codec configuration or null if empty
160160
*/
161-
private function parseCodec(array $codec): ?ConfigCodec
161+
private static function parseCodec(array $codec): ?ConfigCodec
162162
{
163163
$endpoint = $codec['endpoint'] ?? null;
164164
$auth = $codec['auth'] ?? null;

src/Common/EnvConfig/ConfigClient.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ public static function loadFromToml(string $source): self
135135

136136
$toml === false and throw new InvalidConfigException("Failed to read configuration file: {$source}");
137137

138-
$config = new ConfigToml($toml);
138+
$config = ConfigToml::fromString($toml);
139139
return new self(self::normalizeProfileNames($config->profiles));
140140
} catch (ConfigException $e) {
141141
throw $e;

tests/Unit/Common/EnvConfig/Client/ConfigTomlTest.php

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ public function testConstructorParsesDefaultProfileWithTlsPaths(): void
182182
TOML;
183183

184184
// Act
185-
$config = new ConfigToml($toml);
185+
$config = ConfigToml::fromString($toml);
186186

187187
// Assert
188188
self::assertCount(1, $config->profiles);
@@ -220,7 +220,7 @@ public function testConstructorParsesMultipleProfiles(): void
220220
TOML;
221221

222222
// Act
223-
$config = new ConfigToml($toml);
223+
$config = ConfigToml::fromString($toml);
224224

225225
// Assert
226226
self::assertCount(2, $config->profiles);
@@ -257,7 +257,7 @@ public function testConstructorParsesProfileWithApiKeyAndGrpcMeta(): void
257257
TOML;
258258

259259
// Act
260-
$config = new ConfigToml($toml);
260+
$config = ConfigToml::fromString($toml);
261261

262262
// Assert
263263
self::assertCount(2, $config->profiles);
@@ -295,7 +295,7 @@ public function testConstructorParsesProfileWithTlsDisabled(): void
295295
TOML;
296296

297297
// Act
298-
$config = new ConfigToml($toml);
298+
$config = ConfigToml::fromString($toml);
299299

300300
// Assert
301301
self::assertCount(1, $config->profiles);
@@ -323,7 +323,7 @@ public function testConstructorParsesProfileWithTlsCertData(): void
323323
TOML;
324324

325325
// Act
326-
$config = new ConfigToml($toml);
326+
$config = ConfigToml::fromString($toml);
327327

328328
// Assert
329329
self::assertCount(1, $config->profiles);
@@ -345,7 +345,7 @@ public function testConstructorHandlesEmptyToml(): void
345345
$toml = '';
346346

347347
// Act
348-
$config = new ConfigToml($toml);
348+
$config = ConfigToml::fromString($toml);
349349

350350
// Assert
351351
self::assertEmpty($config->profiles);
@@ -360,7 +360,7 @@ public function testConstructorHandlesTomlWithoutProfiles(): void
360360
TOML;
361361

362362
// Act
363-
$config = new ConfigToml($toml);
363+
$config = ConfigToml::fromString($toml);
364364

365365
// Assert
366366
self::assertEmpty($config->profiles);
@@ -382,7 +382,7 @@ public function testConstructorInStrictModeThrowsExceptionForDuplicateCertPath()
382382
$this->expectExceptionMessage('Cannot specify both `server_ca_cert_path` and `server_ca_cert_data`.');
383383

384384
// Act
385-
new ConfigToml($toml);
385+
ConfigToml::fromString($toml);
386386
}
387387

388388
public function testConstructorInStrictModeThrowsExceptionForDuplicateClientKeyPath(): void
@@ -401,7 +401,7 @@ public function testConstructorInStrictModeThrowsExceptionForDuplicateClientKeyP
401401
$this->expectExceptionMessage('Cannot specify both `client_key_path` and `client_key_data`.');
402402

403403
// Act
404-
new ConfigToml($toml);
404+
ConfigToml::fromString($toml);
405405
}
406406

407407
public function testConstructorInStrictModeThrowsExceptionForDuplicateClientCertPath(): void
@@ -420,7 +420,7 @@ public function testConstructorInStrictModeThrowsExceptionForDuplicateClientCert
420420
$this->expectExceptionMessage('Cannot specify both `client_cert_path` and `client_cert_data`.');
421421

422422
// Act
423-
new ConfigToml($toml);
423+
ConfigToml::fromString($toml);
424424
}
425425

426426
public function testConstructorInStrictModeThrowsExceptionForMissingClientKey(): void
@@ -438,7 +438,7 @@ public function testConstructorInStrictModeThrowsExceptionForMissingClientKey():
438438
$this->expectExceptionMessage('Both `client_key_*` and `client_cert_*` must be specified for mTLS.');
439439

440440
// Act
441-
new ConfigToml($toml);
441+
ConfigToml::fromString($toml);
442442
}
443443

444444
public function testConstructorInStrictModeThrowsExceptionForMissingClientCert(): void
@@ -456,7 +456,7 @@ public function testConstructorInStrictModeThrowsExceptionForMissingClientCert()
456456
$this->expectExceptionMessage('Both `client_key_*` and `client_cert_*` must be specified for mTLS.');
457457

458458
// Act
459-
new ConfigToml($toml);
459+
ConfigToml::fromString($toml);
460460
}
461461

462462
#[DataProvider('provideInvalidProfileStructures')]
@@ -469,7 +469,7 @@ public function testConstructorInStrictModeThrowsExceptionForInvalidStructure(
469469
$this->expectExceptionMessage($expectedMessage);
470470

471471
// Act
472-
new ConfigToml($toml);
472+
ConfigToml::fromString($toml);
473473
}
474474

475475
#[DataProvider('provideComplexConfigurations')]
@@ -479,7 +479,7 @@ public function testConstructorHandlesComplexConfigurations(
479479
array $profileChecks,
480480
): void {
481481
// Act
482-
$config = new ConfigToml($toml);
482+
$config = ConfigToml::fromString($toml);
483483

484484
// Assert
485485
self::assertCount($expectedProfileCount, $config->profiles);
@@ -516,7 +516,7 @@ public function testConstructorParsesProfilesWithOnlyTlsServerName(): void
516516
TOML;
517517

518518
// Act
519-
$config = new ConfigToml($toml);
519+
$config = ConfigToml::fromString($toml);
520520

521521
// Assert
522522
self::assertCount(1, $config->profiles);
@@ -539,7 +539,7 @@ public function testConstructorHandlesEmptyGrpcMeta(): void
539539
TOML;
540540

541541
// Act
542-
$config = new ConfigToml($toml);
542+
$config = ConfigToml::fromString($toml);
543543

544544
// Assert
545545
self::assertCount(1, $config->profiles);
@@ -558,7 +558,7 @@ public function testConstructorParsesProfileWithTlsEnabledByApiKey(): void
558558
TOML;
559559

560560
// Act
561-
$config = new ConfigToml($toml);
561+
$config = ConfigToml::fromString($toml);
562562

563563
// Assert
564564
self::assertCount(1, $config->profiles);
@@ -586,7 +586,7 @@ public function testConstructorParsesProfileWithTlsDisabledByDefault(): void
586586
TOML;
587587

588588
// Act
589-
$config = new ConfigToml($toml);
589+
$config = ConfigToml::fromString($toml);
590590

591591
// Assert
592592
self::assertCount(1, $config->profiles);
@@ -610,7 +610,7 @@ public function testConstructorParsesProfileWithTlsEnabledExplicitly(): void
610610
TOML;
611611

612612
// Act
613-
$config = new ConfigToml($toml);
613+
$config = ConfigToml::fromString($toml);
614614

615615
// Assert
616616
self::assertCount(1, $config->profiles);
@@ -633,7 +633,7 @@ public function testConstructorParsesProfileWithDisabledFalse(): void
633633
TOML;
634634

635635
// Act
636-
$config = new ConfigToml($toml);
636+
$config = ConfigToml::fromString($toml);
637637

638638
// Assert
639639
self::assertCount(1, $config->profiles);
@@ -659,7 +659,7 @@ public function testConstructorThrowsExceptionWhenCodecEndpointIsConfigured(): v
659659
$this->expectExceptionMessage('Remote codec configuration is not supported in the PHP SDK');
660660

661661
// Act
662-
new ConfigToml($toml);
662+
ConfigToml::fromString($toml);
663663
}
664664

665665
public function testConstructorThrowsExceptionWhenCodecAuthIsConfigured(): void
@@ -677,7 +677,7 @@ public function testConstructorThrowsExceptionWhenCodecAuthIsConfigured(): void
677677
$this->expectExceptionMessage('Remote codec configuration is not supported in the PHP SDK');
678678

679679
// Act
680-
new ConfigToml($toml);
680+
ConfigToml::fromString($toml);
681681
}
682682

683683
public function testConstructorThrowsExceptionWhenBothCodecFieldsAreConfigured(): void
@@ -696,7 +696,7 @@ public function testConstructorThrowsExceptionWhenBothCodecFieldsAreConfigured()
696696
$this->expectExceptionMessage('Remote codec configuration is not supported in the PHP SDK');
697697

698698
// Act
699-
new ConfigToml($toml);
699+
ConfigToml::fromString($toml);
700700
}
701701

702702
public function testConstructorDoesNotThrowExceptionForEmptyCodecSection(): void
@@ -709,7 +709,7 @@ public function testConstructorDoesNotThrowExceptionForEmptyCodecSection(): void
709709
TOML;
710710

711711
// Act
712-
$config = new ConfigToml($toml);
712+
$config = ConfigToml::fromString($toml);
713713

714714
// Assert
715715
self::assertCount(1, $config->profiles);

0 commit comments

Comments
 (0)