refactor: remove dependency on ext-ctype

This commit is contained in:
Ben Ramsey
2022-09-16 09:43:44 -05:00
parent 59414d4e58
commit 4000e896f9
8 changed files with 78 additions and 69 deletions
+49 -37
View File
@@ -17,10 +17,10 @@ namespace Ramsey\Uuid\Type;
use Ramsey\Uuid\Exception\InvalidArgumentException;
use ValueError;
use function ctype_digit;
use function ltrim;
use function assert;
use function is_numeric;
use function preg_match;
use function sprintf;
use function str_starts_with;
use function substr;
/**
@@ -46,40 +46,7 @@ final class Integer implements NumberInterface
public function __construct(float | int | string | self $value)
{
$value = (string) $value;
$sign = '+';
// If the value contains a sign, remove it for ctype_digit() check.
if (str_starts_with($value, '-') || str_starts_with($value, '+')) {
$sign = substr($value, 0, 1);
$value = substr($value, 1);
}
if (!ctype_digit($value)) {
throw new InvalidArgumentException(
'Value must be a signed integer or a string containing only '
. 'digits 0-9 and, optionally, a sign (+ or -)'
);
}
// Trim any leading zeros.
$value = ltrim($value, '0');
// Set to zero if the string is empty after trimming zeros.
if ($value === '') {
$value = '0';
}
// Add the negative sign back to the value.
if ($sign === '-' && $value !== '0') {
$value = $sign . $value;
$this->isNegative = true;
}
/** @psalm-var numeric-string $numericValue */
$numericValue = $value;
$this->value = $numericValue;
$this->value = $value instanceof self ? (string) $value : $this->prepareValue($value);
}
public function isNegative(): bool
@@ -95,6 +62,9 @@ final class Integer implements NumberInterface
return $this->value;
}
/**
* @psalm-return numeric-string
*/
public function __toString(): string
{
return $this->toString();
@@ -143,4 +113,46 @@ final class Integer implements NumberInterface
$this->unserialize($data['string']);
}
/**
* @return numeric-string
*/
private function prepareValue(float | int | string $value): string
{
$value = (string) $value;
$sign = '+';
// If the value contains a sign, remove it for digit pattern check.
if (str_starts_with($value, '-') || str_starts_with($value, '+')) {
$sign = substr($value, 0, 1);
$value = substr($value, 1);
}
if (!preg_match('/^\d+$/', $value)) {
throw new InvalidArgumentException(
'Value must be a signed integer or a string containing only '
. 'digits 0-9 and, optionally, a sign (+ or -)'
);
}
// Trim any leading zeros.
$value = ltrim($value, '0');
// Set to zero if the string is empty after trimming zeros.
if ($value === '') {
$value = '0';
}
// Add the negative sign back to the value.
if ($sign === '-' && $value !== '0') {
$value = $sign . $value;
/** @psalm-suppress InaccessibleProperty */
$this->isNegative = true;
}
assert(is_numeric($value));
return $value;
}
}