Skip to content

Commit ce36071

Browse files
committed
Move Convert::toValue() to Get::apparent() and add test
1 parent 5da66b8 commit ce36071

File tree

4 files changed

+92
-40
lines changed

4 files changed

+92
-40
lines changed

src/Db/DbConnector.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
use Lkrms\Concern\TFullyReadable;
66
use Lkrms\Contract\IReadable;
77
use Lkrms\Exception\UnexpectedValueException;
8-
use Lkrms\Utility\Convert;
98
use Lkrms\Utility\Env;
109
use Lkrms\Utility\Format;
10+
use Lkrms\Utility\Get;
1111
use ADOConnection;
1212

1313
/**
@@ -96,7 +96,7 @@ final class DbConnector implements IReadable
9696
public function __construct(string $name, int $driver = null)
9797
{
9898
$driver = $driver === null
99-
? Convert::toValue(Env::get("{$name}_driver"), false, false)
99+
? Get::apparent(Env::get("{$name}_driver"), false, false)
100100
: $driver;
101101

102102
$this->Name = $name;

src/Utility/Convert.php

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use Lkrms\Support\Date\DateFormatter;
88
use Lkrms\Support\Date\DateFormatterInterface;
99
use DateTimeInterface;
10-
use LogicException;
1110
use Stringable;
1211

1312
/**
@@ -21,41 +20,6 @@
2120
*/
2221
final class Convert extends Utility
2322
{
24-
/**
25-
* Convert a scalar to the type it appears to be
26-
*
27-
* @param mixed $value
28-
* @param bool $toFloat If `true` (the default), convert float strings to
29-
* `float`s.
30-
* @param bool $toBool If `true` (the default), convert boolean strings to
31-
* `bool`s.
32-
* @return int|float|string|bool|null
33-
*/
34-
public static function toValue($value, bool $toFloat = true, bool $toBool = true)
35-
{
36-
if ($value === null || is_bool($value) || is_int($value) || is_float($value)) {
37-
return $value;
38-
}
39-
if (!is_string($value)) {
40-
throw new LogicException('$value must be a scalar');
41-
}
42-
if (Pcre::match('/^' . Regex::INTEGER_STRING . '$/', $value)) {
43-
return (int) $value;
44-
}
45-
if ($toFloat && is_numeric($value)) {
46-
return (float) $value;
47-
}
48-
if ($toBool && Pcre::match(
49-
'/^' . Regex::BOOLEAN_STRING . '$/',
50-
$value,
51-
$match,
52-
\PREG_UNMATCHED_AS_NULL
53-
)) {
54-
return $match['true'] !== null;
55-
}
56-
return $value;
57-
}
58-
5923
/**
6024
* Convert a value to an integer, preserving null
6125
*

src/Utility/Get.php

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Lkrms\Concept\Utility;
66
use Lkrms\Container\Contract\SingletonInterface;
77
use Lkrms\Contract\Arrayable;
8+
use Lkrms\Exception\InvalidArgumentTypeException;
89
use Lkrms\Exception\UncloneableObjectException;
910
use Lkrms\Support\Catalog\RegularExpression as Regex;
1011
use Lkrms\Utility\Catalog\CopyFlag;
@@ -21,7 +22,7 @@
2122
final class Get extends Utility
2223
{
2324
/**
24-
* Convert a value to boolean, preserving null
25+
* Cast a value to boolean, converting boolean strings and preserving null
2526
*
2627
* @see Test::isBoolValue()
2728
*
@@ -47,7 +48,45 @@ public static function boolean($value): ?bool
4748
}
4849

4950
/**
50-
* If a value is callable, get its return value
51+
* Convert a scalar to the type it appears to be
52+
*
53+
* @param int|float|string|bool|null $value
54+
* @param bool $toFloat If `true` (the default), convert float strings to
55+
* `float`s.
56+
* @param bool $toBool If `true` (the default), convert boolean strings to
57+
* `bool`s.
58+
* @return int|float|string|bool|null
59+
*/
60+
public static function apparent($value, bool $toFloat = true, bool $toBool = true)
61+
{
62+
if ($value === null || is_bool($value) || is_int($value) || is_float($value)) {
63+
return $value;
64+
}
65+
if (!is_string($value)) {
66+
throw new InvalidArgumentTypeException(1, 'value', 'int|float|string|bool|null', $value);
67+
}
68+
if (Str::lower(trim($value)) === 'null') {
69+
return null;
70+
}
71+
if (Pcre::match('/^' . Regex::INTEGER_STRING . '$/', $value)) {
72+
return (int) $value;
73+
}
74+
if ($toFloat && is_numeric($value)) {
75+
return (float) $value;
76+
}
77+
if ($toBool && Pcre::match(
78+
'/^' . Regex::BOOLEAN_STRING . '$/',
79+
$value,
80+
$match,
81+
\PREG_UNMATCHED_AS_NULL
82+
)) {
83+
return $match['true'] !== null;
84+
}
85+
return $value;
86+
}
87+
88+
/**
89+
* Resolve a callable to its return value
5190
*
5291
* @template T
5392
*

tests/unit/Utility/GetTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Lkrms\Tests\Utility;
44

55
use Lkrms\Container\Container;
6+
use Lkrms\Exception\InvalidArgumentException;
67
use Lkrms\Exception\UncloneableObjectException;
78
use Lkrms\Tests\Utility\Get\ClassWithCloneMethod;
89
use Lkrms\Tests\Utility\Get\ClassWithRefs;
@@ -53,6 +54,54 @@ public static function booleanProvider(): array
5354
];
5455
}
5556

57+
/**
58+
* @dataProvider apparentProvider
59+
*
60+
* @param int|float|string|bool|null $expected
61+
* @param int|float|string|bool|null $value
62+
*/
63+
public function testApparent($expected, $value, bool $toFloat = true, bool $toBool = true): void
64+
{
65+
$this->assertSame($expected, Get::apparent($value, $toFloat, $toBool));
66+
}
67+
68+
/**
69+
* @return array<array{int|float|string|bool|null,int|float|string|bool|null,2?:bool,3?:bool}>
70+
*/
71+
public static function apparentProvider(): array
72+
{
73+
return [
74+
[null, null],
75+
['', ''],
76+
[0, 0],
77+
[1, 1],
78+
[3.14, 3.14],
79+
[false, false],
80+
[true, true],
81+
[null, 'null'],
82+
[null, ' NULL '],
83+
[0, '0'],
84+
[0, ' 0 '],
85+
[1, '1'],
86+
[1, ' 1 '],
87+
[3.14, '3.14'],
88+
[3.14, ' 3.14 '],
89+
[false, 'false'],
90+
[false, ' no '],
91+
[true, 'true'],
92+
[true, ' YES '],
93+
['3.14', '3.14', false],
94+
['false', 'false', true, false],
95+
];
96+
}
97+
98+
public function testApparentWithInvalidValue(): void
99+
{
100+
$this->expectException(InvalidArgumentException::class);
101+
$this->expectExceptionMessage('Argument #1 ($value) must be of type int|float|string|bool|null, stdClass given');
102+
Get::apparent(new stdClass());
103+
}
104+
56105
/**
57106
* @dataProvider valueProvider
58107
*

0 commit comments

Comments
 (0)