From 1a386c38922f07d67e1d1913a3248d5f48b9cbe0 Mon Sep 17 00:00:00 2001 From: Khosro <52885484+mrkh995@users.noreply.github.com> Date: Sat, 31 May 2025 18:08:05 +0000 Subject: [PATCH 1/2] Add ofNullable factory method --- src/BigNumber.php | 28 ++++++++++++++++++++++++++++ tests/BigDecimalTest.php | 15 +++++++++++++++ tests/BigIntegerTest.php | 14 ++++++++++++++ tests/BigRationalTest.php | 16 ++++++++++++++++ 4 files changed, 73 insertions(+) diff --git a/src/BigNumber.php b/src/BigNumber.php index 5dabd31..f886f2e 100644 --- a/src/BigNumber.php +++ b/src/BigNumber.php @@ -71,6 +71,34 @@ final public static function of(BigNumber|int|float|string $value) : static return static::from($value); } + /** + * Creates a BigNumber of the given value, or returns null if the input is null. + * + * + * The concrete return type is dependent on the given value, with the following rules: + * + * - BigNumber instances are returned as is + * - null values are returned as is + * - integer numbers are returned as BigInteger + * - floating point numbers are converted to a string then parsed as such\ + * - strings containing a `/` character are returned as BigRational + * - strings containing a `.` character or using an exponential notation are returned as BigDecimal + * - strings containing only digits with an optional leading `+` or `-` sign are returned as BigInteger + * + * @param BigNumber|int|float|string|null $value The value to convert. + * + * @return static|null A BigNumber instance (of the called class type), or null if the input was null. + * + * @throws NumberFormatException If the format of the number is not valid. + * @throws DivisionByZeroException If the value represents a rational number with a denominator of zero. + * @throws RoundingNecessaryException If the value cannot be converted to an instance of the subclass without rounding. + */ + public static function ofNullable(BigNumber|int|float|string|null $value): ?static + { + if (is_null($value)) return null; + + return static::of($value); + } /** * @throws NumberFormatException If the format of the number is not valid. diff --git a/tests/BigDecimalTest.php b/tests/BigDecimalTest.php index 12cbe86..0441ad0 100644 --- a/tests/BigDecimalTest.php +++ b/tests/BigDecimalTest.php @@ -29,6 +29,21 @@ public function testOf(int|float|string $value, string $unscaledValue, int $scal self::assertBigDecimalInternalValues($unscaledValue, $scale, BigDecimal::of($value)); } + /** + * @param int|float|string $value The value to convert to a BigDecimal. + * @param string $unscaledValue The expected unscaled value. + * @param int $scale The expected scale. + */ + public function testOfNullableWithValidInputBehavesLikeOf(mixed $value, string $expected): void + { + $this->assertBigDecimalIs($expected, BigDecimal::ofNullable($value)); + } + + public function testOfNullableWithNullInput(): void + { + $this->assertNull(BigDecimal::ofNullable(null)); + } + public static function providerOf() : array { return [ diff --git a/tests/BigIntegerTest.php b/tests/BigIntegerTest.php index 5457ea8..c55e780 100644 --- a/tests/BigIntegerTest.php +++ b/tests/BigIntegerTest.php @@ -31,6 +31,20 @@ public function testOf(int|float|string $value, string $expected) : void self::assertBigIntegerEquals($expected, BigInteger::of($value)); } + /** + * @param int|float|string $value The value to convert to a BigInteger. + * @param string $expected The expected string value of the result. + */ + public function testOfNullableWithValidInputBehavesLikeOf(mixed $value, string $expected): void + { + self::assertBigIntegerEquals($expected, BigInteger::ofNullable($value)); + } + + public function testOfNullableWithNullInput(): void + { + $this->assertNull(BigInteger::ofNullable(null)); + } + public static function providerOf() : array { return [ diff --git a/tests/BigRationalTest.php b/tests/BigRationalTest.php index 75ff629..6c38172 100644 --- a/tests/BigRationalTest.php +++ b/tests/BigRationalTest.php @@ -61,6 +61,22 @@ public function testOf(string $numerator, string $denominator, string $string) : self::assertBigRationalInternalValues($numerator, $denominator, $rational); } + /** + * @param string $numerator The expected numerator. + * @param string $denominator The expected denominator. + * @param string $string The string to parse. + */ + public function testOfNullableWithValidInputBehavesLikeOf(mixed $value, string $expected): void + { + $rational = BigRational::ofNullable($string); + self::assertBigRationalInternalValues($numerator, $denominator, $rational); + } + + public function testOfNullableWithNullInput(): void + { + $this->assertNull(BigRational::ofNullable(null)); + } + public static function providerOf() : array { return [ From 11195126e4f39833da28fcd59067bc1e14953032 Mon Sep 17 00:00:00 2001 From: Khosro <52885484+mrkh995@users.noreply.github.com> Date: Sat, 31 May 2025 19:11:43 +0000 Subject: [PATCH 2/2] Add ofNullable factory method --- tests/BigDecimalTest.php | 5 +++-- tests/BigIntegerTest.php | 1 + tests/BigRationalTest.php | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/BigDecimalTest.php b/tests/BigDecimalTest.php index 0441ad0..c2706f4 100644 --- a/tests/BigDecimalTest.php +++ b/tests/BigDecimalTest.php @@ -34,9 +34,10 @@ public function testOf(int|float|string $value, string $unscaledValue, int $scal * @param string $unscaledValue The expected unscaled value. * @param int $scale The expected scale. */ - public function testOfNullableWithValidInputBehavesLikeOf(mixed $value, string $expected): void + #[DataProvider('providerOf')] + public function testOfNullableWithValidInputBehavesLikeOf(int|float|string $value, string $unscaledValue, int $scale) : void { - $this->assertBigDecimalIs($expected, BigDecimal::ofNullable($value)); + self::assertBigDecimalInternalValues($unscaledValue, $scale, BigDecimal::of($value)); } public function testOfNullableWithNullInput(): void diff --git a/tests/BigIntegerTest.php b/tests/BigIntegerTest.php index c55e780..498f114 100644 --- a/tests/BigIntegerTest.php +++ b/tests/BigIntegerTest.php @@ -35,6 +35,7 @@ public function testOf(int|float|string $value, string $expected) : void * @param int|float|string $value The value to convert to a BigInteger. * @param string $expected The expected string value of the result. */ + #[DataProvider('providerOf')] public function testOfNullableWithValidInputBehavesLikeOf(mixed $value, string $expected): void { self::assertBigIntegerEquals($expected, BigInteger::ofNullable($value)); diff --git a/tests/BigRationalTest.php b/tests/BigRationalTest.php index 6c38172..3e13967 100644 --- a/tests/BigRationalTest.php +++ b/tests/BigRationalTest.php @@ -66,10 +66,11 @@ public function testOf(string $numerator, string $denominator, string $string) : * @param string $denominator The expected denominator. * @param string $string The string to parse. */ - public function testOfNullableWithValidInputBehavesLikeOf(mixed $value, string $expected): void + #[DataProvider('providerOf')] + public function testOfNullableWithValidInputBehavesLikeOf(string $numerator, string $denominator, string $string) : void { $rational = BigRational::ofNullable($string); - self::assertBigRationalInternalValues($numerator, $denominator, $rational); + self::assertBigRationalInternalValues($numerator, $denominator, $rational); } public function testOfNullableWithNullInput(): void