Skip to content

Commit 5ac7230

Browse files
committed
Add tryFromString and tryFromInt methods across integer types and update tests
- Introduced `tryFromString` and `tryFromInt` methods returning `Undefined` on invalid input for `IntType` implementations. - Updated interfaces to include `tryFromString` and `tryFromInt` declarations. - Enhanced unit tests to verify `tryFromString` and `tryFromInt` behavior. - Adjusted usage examples to demonstrate the new methods.
1 parent 397cbc6 commit 5ac7230

File tree

8 files changed

+142
-3
lines changed

8 files changed

+142
-3
lines changed

src/Abstract/Integer/IntTypeInterface.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,24 @@
44

55
namespace PhpTypedValues\Abstract\Integer;
66

7+
use PhpTypedValues\Undefined\Alias\Undefined;
8+
79
/**
810
* @psalm-immutable
911
*/
1012
interface IntTypeInterface
1113
{
1214
public function value(): int;
1315

16+
public static function fromString(string $value): static;
17+
1418
public static function fromInt(int $value): static;
1519

16-
public function toString(): string;
20+
public static function tryFromString(string $value): static|Undefined;
1721

18-
public static function fromString(string $value): static;
22+
public static function tryFromInt(int $value): static|Undefined;
23+
24+
public function toString(): string;
1925

2026
public function __toString(): string;
2127
}

src/Integer/IntegerNonNegative.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
use PhpTypedValues\Abstract\Integer\IntType;
88
use PhpTypedValues\Exception\IntegerTypeException;
9+
use PhpTypedValues\Exception\TypeException;
10+
use PhpTypedValues\Undefined\Alias\Undefined;
911

1012
use function sprintf;
1113

@@ -33,6 +35,24 @@ public function __construct(int $value)
3335
$this->value = $value;
3436
}
3537

38+
public static function tryFromString(string $value): static|Undefined
39+
{
40+
try {
41+
return static::fromString($value);
42+
} catch (TypeException) {
43+
return Undefined::create();
44+
}
45+
}
46+
47+
public static function tryFromInt(int $value): static|Undefined
48+
{
49+
try {
50+
return static::fromInt($value);
51+
} catch (TypeException) {
52+
return Undefined::create();
53+
}
54+
}
55+
3656
/**
3757
* @throws IntegerTypeException
3858
*/

src/Integer/IntegerPositive.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
use PhpTypedValues\Abstract\Integer\IntType;
88
use PhpTypedValues\Exception\IntegerTypeException;
9+
use PhpTypedValues\Exception\TypeException;
10+
use PhpTypedValues\Undefined\Alias\Undefined;
911

1012
use function sprintf;
1113

@@ -33,6 +35,24 @@ public function __construct(int $value)
3335
$this->value = $value;
3436
}
3537

38+
public static function tryFromString(string $value): static|Undefined
39+
{
40+
try {
41+
return static::fromString($value);
42+
} catch (TypeException) {
43+
return Undefined::create();
44+
}
45+
}
46+
47+
public static function tryFromInt(int $value): static|Undefined
48+
{
49+
try {
50+
return static::fromInt($value);
51+
} catch (TypeException) {
52+
return Undefined::create();
53+
}
54+
}
55+
3656
/**
3757
* @throws IntegerTypeException
3858
*/

src/Integer/IntegerStandard.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
use PhpTypedValues\Abstract\Integer\IntType;
88
use PhpTypedValues\Exception\IntegerTypeException;
9+
use PhpTypedValues\Exception\TypeException;
10+
use PhpTypedValues\Undefined\Alias\Undefined;
911

1012
/**
1113
* Represents any PHP integer.
@@ -23,6 +25,21 @@ public function __construct(int $value)
2325
$this->value = $value;
2426
}
2527

28+
public static function tryFromString(string $value): static|Undefined
29+
{
30+
try {
31+
return static::fromString($value);
32+
} catch (TypeException) {
33+
return Undefined::create();
34+
}
35+
}
36+
37+
public static function tryFromInt(int $value): static|Undefined
38+
{
39+
// IntegerStandard accepts any PHP int, so construction cannot fail.
40+
return new static($value);
41+
}
42+
2643
public static function fromInt(int $value): static
2744
{
2845
return new static($value);

src/Integer/IntegerWeekDay.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
use PhpTypedValues\Abstract\Integer\IntType;
88
use PhpTypedValues\Exception\IntegerTypeException;
9+
use PhpTypedValues\Exception\TypeException;
10+
use PhpTypedValues\Undefined\Alias\Undefined;
911

1012
use function sprintf;
1113

@@ -45,6 +47,24 @@ public function value(): int
4547
return $this->value;
4648
}
4749

50+
public static function tryFromString(string $value): static|Undefined
51+
{
52+
try {
53+
return static::fromString($value);
54+
} catch (TypeException) {
55+
return Undefined::create();
56+
}
57+
}
58+
59+
public static function tryFromInt(int $value): static|Undefined
60+
{
61+
try {
62+
return static::fromInt($value);
63+
} catch (TypeException) {
64+
return Undefined::create();
65+
}
66+
}
67+
4868
/**
4969
* @throws IntegerTypeException
5070
*/

src/Integer/MariaDb/IntTiny.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
use PhpTypedValues\Abstract\Integer\IntType;
88
use PhpTypedValues\Exception\IntegerTypeException;
9+
use PhpTypedValues\Exception\TypeException;
10+
use PhpTypedValues\Undefined\Alias\Undefined;
911

1012
use function sprintf;
1113

@@ -33,6 +35,24 @@ public function __construct(int $value)
3335
$this->value = $value;
3436
}
3537

38+
public static function tryFromString(string $value): static|Undefined
39+
{
40+
try {
41+
return static::fromString($value);
42+
} catch (TypeException) {
43+
return Undefined::create();
44+
}
45+
}
46+
47+
public static function tryFromInt(int $value): static|Undefined
48+
{
49+
try {
50+
return static::fromInt($value);
51+
} catch (TypeException) {
52+
return Undefined::create();
53+
}
54+
}
55+
3656
/**
3757
* @throws IntegerTypeException
3858
*/

src/Usage/integer.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@
2424
echo TinyInt::fromInt(-5)->toString() . \PHP_EOL;
2525
echo IntTiny::fromInt(-5)->toString() . \PHP_EOL;
2626
echo IntTiny::fromString('127')->toString() . \PHP_EOL;
27-
2827
echo NonNegativeInt::fromString('10')->toString() . \PHP_EOL;
2928
echo PositiveInt::fromString('10')->toString() . \PHP_EOL;
3029
echo IntegerStandard::fromString('10')->toString() . \PHP_EOL;
3130
echo Id::fromString('10')->toString() . \PHP_EOL;
3231
echo IntType::fromString('10')->toString() . \PHP_EOL;
3332
echo Integer::fromString('10')->toString() . \PHP_EOL;
33+
echo Integer::tryFromString('127')->toString() . \PHP_EOL;
34+
echo Integer::tryFromInt(127)->toString() . \PHP_EOL;
3435

3536
/**
3637
* Artificial functions.

tests/Unit/Integer/MariaDb/IntTinyTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PhpTypedValues\Exception\IntegerTypeException;
66
use PhpTypedValues\Integer\MariaDb\IntTiny;
7+
use PhpTypedValues\Undefined\Alias\Undefined;
78

89
it('accepts values within signed tinyint range and preserves value', function (): void {
910
$a = new IntTiny(-128);
@@ -38,3 +39,37 @@
3839
expect(fn() => IntTiny::fromString('12.3'))
3940
->toThrow(IntegerTypeException::class, 'String "12.3" has no valid strict integer value');
4041
});
42+
43+
it('IntTiny::tryFromString returns value within -128..127', function (): void {
44+
$vMin = IntTiny::tryFromString('-128');
45+
$v0 = IntTiny::tryFromString('0');
46+
$vMax = IntTiny::tryFromString('127');
47+
48+
expect($vMin)
49+
->toBeInstanceOf(IntTiny::class)
50+
->and($vMin->value())->toBe(-128)
51+
->and($v0)
52+
->toBeInstanceOf(IntTiny::class)
53+
->and($v0->value())->toBe(0)
54+
->and($vMax)
55+
->toBeInstanceOf(IntTiny::class)
56+
->and($vMax->value())->toBe(127);
57+
});
58+
59+
it('IntTiny::tryFromString returns Undefined outside range and for non-integer strings', function (): void {
60+
expect(IntTiny::tryFromString('128'))
61+
->toBeInstanceOf(Undefined::class)
62+
->and(IntTiny::tryFromString('5.0'))
63+
->toBeInstanceOf(Undefined::class);
64+
});
65+
66+
it('IntTiny::tryFromInt returns value within range and Undefined otherwise', function (): void {
67+
$ok = IntTiny::tryFromInt(-5);
68+
$bad = IntTiny::tryFromInt(200);
69+
70+
expect($ok)
71+
->toBeInstanceOf(IntTiny::class)
72+
->and($ok->value())->toBe(-5)
73+
->and($bad)
74+
->toBeInstanceOf(Undefined::class);
75+
});

0 commit comments

Comments
 (0)