Skip to content

Commit 4ddbf40

Browse files
authored
Merge pull request #5 from GeorgII-web/bool
Add `BoolType` abstract structure with `BoolStandard` implementation,…
2 parents c53df4f + 87e8a9c commit 4ddbf40

File tree

11 files changed

+251
-0
lines changed

11 files changed

+251
-0
lines changed

src/Abstract/Bool/BoolType.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpTypedValues\Abstract\Bool;
6+
7+
/**
8+
* @psalm-immutable
9+
*/
10+
abstract readonly class BoolType implements BoolTypeInterface
11+
{
12+
abstract protected function __construct(bool $value);
13+
14+
public function toString(): string
15+
{
16+
return $this->value() ? 'true' : 'false';
17+
}
18+
19+
public static function fromBool(bool $value): self
20+
{
21+
return new static($value);
22+
}
23+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpTypedValues\Abstract\Bool;
6+
7+
/**
8+
* @psalm-immutable
9+
*/
10+
interface BoolTypeInterface
11+
{
12+
public function value(): bool;
13+
14+
public static function fromString(string $value): self;
15+
16+
public static function fromBool(bool $value): self;
17+
18+
public function toString(): string;
19+
}

src/Bool/Alias/Boolean.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpTypedValues\Bool\Alias;
6+
7+
use PhpTypedValues\Bool\BoolStandard;
8+
9+
/**
10+
* @psalm-immutable
11+
*/
12+
readonly class Boolean extends BoolStandard
13+
{
14+
}

src/Bool/BoolStandard.php

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpTypedValues\Bool;
6+
7+
use PhpTypedValues\Abstract\Bool\BoolType;
8+
use PhpTypedValues\Exception\BoolTypeException;
9+
10+
use function sprintf;
11+
12+
/**
13+
* Boolean value.
14+
*
15+
* Example "true"
16+
*
17+
* @psalm-immutable
18+
*/
19+
readonly class BoolStandard extends BoolType
20+
{
21+
protected bool $value;
22+
23+
public function __construct(bool $value)
24+
{
25+
$this->value = $value;
26+
}
27+
28+
/**
29+
* @throws BoolTypeException
30+
*/
31+
public static function fromString(string $value): static
32+
{
33+
$lowerCaseValue = strtolower($value);
34+
35+
if ($lowerCaseValue === 'true') {
36+
$boolValue = true;
37+
} elseif ($lowerCaseValue === 'false') {
38+
$boolValue = false;
39+
} else {
40+
throw new BoolTypeException(sprintf('Expected string "true" or "false", got "%s"', $value));
41+
}
42+
43+
return new static($boolValue);
44+
}
45+
46+
/**
47+
* @throws BoolTypeException
48+
*/
49+
public static function fromInt(int $value): static
50+
{
51+
if ($value === 1) {
52+
$boolValue = true;
53+
} elseif ($value === 0) {
54+
$boolValue = false;
55+
} else {
56+
throw new BoolTypeException(sprintf('Expected int "1" or "0", got "%s"', $value));
57+
}
58+
59+
return new static($boolValue);
60+
}
61+
62+
public function value(): bool
63+
{
64+
return $this->value;
65+
}
66+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpTypedValues\Exception;
6+
7+
class BoolTypeException extends TypeException
8+
{
9+
}

src/Float/Alias/Double.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpTypedValues\Float\Alias;
6+
7+
use PhpTypedValues\Float\FloatStandard;
8+
9+
/**
10+
* @psalm-immutable
11+
*/
12+
readonly class Double extends FloatStandard
13+
{
14+
}

src/Integer/Alias/Integer.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpTypedValues\Integer\Alias;
6+
7+
use PhpTypedValues\Integer\IntegerStandard;
8+
9+
/**
10+
* @psalm-immutable
11+
*/
12+
readonly class Integer extends IntegerStandard
13+
{
14+
}

src/String/Alias/Str.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpTypedValues\String\Alias;
6+
7+
use PhpTypedValues\String\StringStandard;
8+
9+
/**
10+
* @psalm-immutable
11+
*/
12+
readonly class Str extends StringStandard
13+
{
14+
}

src/psalmTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,20 @@
88

99
require_once 'vendor/autoload.php';
1010

11+
use PhpTypedValues\Abstract\Bool\BoolTypeInterface;
12+
use PhpTypedValues\Bool\Alias\Boolean;
13+
use PhpTypedValues\Bool\BoolStandard;
1114
use PhpTypedValues\DateTime\DateTimeAtom;
1215
use PhpTypedValues\DateTime\DateTimeRFC3339;
1316
use PhpTypedValues\DateTime\Timestamp\TimestampMilliseconds;
1417
use PhpTypedValues\DateTime\Timestamp\TimestampSeconds;
18+
use PhpTypedValues\Float\Alias\Double;
1519
use PhpTypedValues\Float\Alias\FloatType;
1620
use PhpTypedValues\Float\Alias\NonNegativeFloat;
1721
use PhpTypedValues\Float\FloatNonNegative;
1822
use PhpTypedValues\Float\FloatStandard;
1923
use PhpTypedValues\Integer\Alias\Id;
24+
use PhpTypedValues\Integer\Alias\Integer;
2025
use PhpTypedValues\Integer\Alias\IntType;
2126
use PhpTypedValues\Integer\Alias\NonNegativeInt;
2227
use PhpTypedValues\Integer\Alias\PositiveInt;
@@ -27,6 +32,7 @@
2732
use PhpTypedValues\Integer\IntegerStandard;
2833
use PhpTypedValues\Integer\IntegerWeekDay;
2934
use PhpTypedValues\String\Alias\NonEmptyStr;
35+
use PhpTypedValues\String\Alias\Str;
3036
use PhpTypedValues\String\Alias\StrType;
3137
use PhpTypedValues\String\StringNonEmpty;
3238
use PhpTypedValues\String\StringStandard;
@@ -49,6 +55,7 @@
4955
echo IntegerStandard::fromString('10')->toString() . \PHP_EOL;
5056
echo Id::fromString('10')->toString() . \PHP_EOL;
5157
echo IntType::fromString('10')->toString() . \PHP_EOL;
58+
echo Integer::fromString('10')->toString() . \PHP_EOL;
5259

5360
/**
5461
* String.
@@ -59,6 +66,7 @@
5966
echo StringStandard::fromString('hi')->toString() . \PHP_EOL;
6067
echo NonEmptyStr::fromString('hi')->toString() . \PHP_EOL;
6168
echo StrType::fromString('hi')->toString() . \PHP_EOL;
69+
echo Str::fromString('hi')->toString() . \PHP_EOL;
6270

6371
/**
6472
* Float.
@@ -68,11 +76,22 @@
6876
echo FloatStandard::fromString('2.71828')->toString() . \PHP_EOL;
6977
echo NonNegativeFloat::fromString('2.71828')->toString() . \PHP_EOL;
7078
echo FloatType::fromString('2.71828')->toString() . \PHP_EOL;
79+
echo Double::fromString('2.71828')->toString() . \PHP_EOL;
7180

7281
// PositiveFloat usage
7382
testPositiveFloat(FloatNonNegative::fromFloat(0.5)->value());
7483
echo FloatNonNegative::fromString('3.14159')->toString() . \PHP_EOL;
7584

85+
/**
86+
* Boolean.
87+
*/
88+
echo BoolStandard::fromString('true')->toString() . \PHP_EOL;
89+
echo BoolStandard::fromInt(1)->toString() . \PHP_EOL;
90+
echo BoolStandard::fromBool(true)->toString() . \PHP_EOL;
91+
echo Boolean::fromBool(Boolean::fromBool(true)->value())->toString() . \PHP_EOL;
92+
// Ensure interface method usage is visible to Psalm
93+
echo (testBool(BoolStandard::fromBool(true)) ? 'true' : 'false') . \PHP_EOL;
94+
7695
/**
7796
* DateTime.
7897
*/
@@ -145,3 +164,11 @@ function testPositiveFloat(float $f): float
145164
{
146165
return $f;
147166
}
167+
168+
/**
169+
* Exercise BoolTypeInterface::value() for Psalm.
170+
*/
171+
function testBool(BoolTypeInterface $b): bool
172+
{
173+
return $b->value();
174+
}

tests/Arch/StructureTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
declare(strict_types=1);
44

5+
use PhpTypedValues\Abstract\Bool\BoolType;
56
use PhpTypedValues\Abstract\DateTime\DateTimeType;
67
use PhpTypedValues\Abstract\Float\FloatType;
78
use PhpTypedValues\Abstract\Integer\IntType;
@@ -36,3 +37,9 @@
3637
->toExtend(DateTimeType::class)
3738
->toBeClasses()
3839
->toBeReadonly();
40+
41+
arch('Boolean classes are final and read-only')
42+
->expect('PhpTypedValues\Bool')
43+
->toExtend(BoolType::class)
44+
->toBeClasses()
45+
->toBeReadonly();

0 commit comments

Comments
 (0)