@@ -30,7 +30,7 @@ composer require georgii-web/php-typed-values:^1.0
3030$id = IntegerPositive::fromString('123');
3131```
3232
33- instead of duplicating this logic across your application like:
33+ instead of spreading this logic across your application like:
3434
3535``` php
3636$id = (int) '123';
@@ -53,35 +53,53 @@ Id::fromInt(123);
5353final readonly class Profile
5454{
5555 public function __construct(
56- public readonly IntegerPositive $id,
57- public readonly StringNonEmpty $firstName,
58- public readonly ?FloatNonNegative $height,
56+ private IntegerPositive $id,
57+ private StringNonEmpty|Undefined $firstName,
58+ private FloatPositive|Undefined $height,
5959 ) {}
6060
6161 public static function fromScalars(
6262 int $id,
63- string $firstName,
64- string|float|int|null $height,
65- ): static {
66- return new static(
67- IntegerPositive::fromInt($id),
68- StringNonEmpty::fromString($firstName), // Early fail
69- $height !== null ? FloatNonNegative::fromString((string) $height) : null,
63+ ?string $firstName,
64+ string|float|int|null $height = null,
65+ ): self {
66+ return new self(
67+ IntegerPositive::fromInt($id), // Early fail
68+ StringNonEmpty::tryFromMixed($firstName), // Late fail
69+ $height !== null
70+ ? FloatPositive::fromString((string) $height) // Early fail for not NULL
71+ : Undefined::create(), // Late fail for NULL
7072 );
7173 }
7274
73- public function getHeight(): FloatNonNegative |Undefined { // avoid using NULL, which could mean anything
74- return $this->height ?? Undefined::create(); // Late fail
75+ public function getHeight(): FloatPositive |Undefined {
76+ return $this->height;
7577 }
7678}
79+ ```
80+ VO strictly typed and must have all valid fields:
81+
82+ Use "Early fail" on wrong ` Id `
83+
84+ ``` php
85+ Profile::fromScalars(id: 0, firstName: 'Alice', height: '172.5'); // Early fail Exception
86+ ```
87+
88+ If VO partly valid but still must be created:
89+
90+ Use "Late fail" on a wrong ` firstName `
91+ ``` php
92+ $profile = Profile::fromScalars(id: 101, firstName: '', height: '172.5'); // Profile created
93+ $profile = Profile::fromScalars(id: 101, firstName: null, height: '172.5'); // Profile created
94+ $profile->getFirstName()->value(); // Late fail, "Undefined" class will throw an exception on trying to get the value
95+ ```
96+
97+ Or "Optioanal fail" on a wrong ` height `
98+ ``` php
99+ $profile = Profile::fromScalars(id: 101, firstName: 'Alice', height: -1); // Early fail Exception
77100
78- // Usage
79- \PhpTypedValues\Usage\Composite::fromScalars(id: 101, firstName: 'Alice', height: '172.5');
80- \PhpTypedValues\Usage\Composite::fromScalars(id: 157, firstName: 'Tom', height: null);
81- // From array
82- $profile = \PhpTypedValues\Usage\Composite::fromScalars(...[157, 'Tom', null]);
83- // Accessing values
84- $profile->getHeight(); // "172.5" OR "Undefined" type class (will throw an exception on trying to get value)
101+ $profile = Profile::fromScalars(id: 101, firstName: 'Alice', height: null); // Profile created
102+ $profile->getHeight()->value(); // Late fail, "Undefined" class will throw an exception on trying to get the value
85103```
86104
87105## Key Features
0 commit comments