Skip to content

Commit 1b7e13d

Browse files
committed
feat(Result): value is noe explicitly nullable, use null-safe operator.
This allows for managing errors inline, see Error Management.md changes.
1 parent 2852df5 commit 1b7e13d

File tree

8 files changed

+46
-52
lines changed

8 files changed

+46
-52
lines changed

docs/Custom Attributes.md

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,11 @@ function handler(#[HelloWorldAttribute] string $greeting){
2626
}
2727

2828
function main(ServerInterface $server, RouterInterface $router):Result {
29-
$router->addHandler("GET", "/", handler(...))->unwrap($error);
29+
$router->addHandler("GET", "/", handler(...))
30+
->unwrap($error) ?? die($error);
3031

31-
if ($error) {
32-
die($error)
33-
}
34-
35-
$server->start()->unwrap($error);
36-
37-
if ($error) {
38-
die($error)
39-
}
32+
$server->start()
33+
->unwrap($error) ?? die($error);
4034
}
4135
```
4236

docs/Error Management.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,26 @@ if($error){
5656

5757
The first advantage over throwing exceptions is that your control flow is linear and easier to understand because you are not required to use `try/catch` syntax.
5858

59+
Another advantage of representing errors as values is that you can use expressions and pattern matching to manage logic
60+
61+
```php
62+
use function CatPaw\Core\error;
63+
64+
class Error1 {}
65+
class Error2 {}
66+
67+
$result = error(new Error1)
68+
69+
$value = $result->unwrap($error) ?? match($error::class){
70+
Error1::class => "fallback value 1",
71+
Error2::class => "fallback value 2",
72+
default => "default value"
73+
};
74+
```
75+
76+
Note that php's match expression is exhaustive, meaning it forces you to provide a default value, which is good because it leaves no margin for ambiguous values.
77+
78+
5979
But the most important advantage is probably type safety.\
6080
While it is true you can check for native thrown exceptions using development tools like phpstan, psalm and so on, these tools don't guarantee your code is safely checked for errors, they are mere linting solutions.\
6181
Using results, the php type system itself will force you to `unwrap()` the value.

docs/RaspberryPi.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,8 @@ function main(GpioInterface $gpio):void {
2727
$writer = $gpio->createWriter('12');
2828
$active = true;
2929
while (true) {
30-
$writer->write($active?'1':'0')->unwrap($error);
31-
32-
if ($error) {
33-
die($error)
34-
}
30+
$writer->write($active?'1':'0')
31+
->unwrap($error) ?? die($error);
3532

3633
$active = !$active;
3734
delay(1);

docs/Server Router.md

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,11 @@ function main(
1818
ServerInterface $server,
1919
RouterInterface $router,
2020
):void {
21-
$router->addHandler("GET", "/cats", handler(...))->unwrap($error);
21+
$router->addHandler("GET", "/cats", handler(...))
22+
->unwrap($error) ?? die($error);
2223

23-
if ($error) {
24-
die($error)
25-
}
26-
27-
$server->start()->unwrap($error);
28-
29-
if ($error) {
30-
die($error)
31-
}
24+
$server->start()
25+
->unwrap($error) ?? die($error);
3226
}
3327
```
3428

@@ -53,17 +47,11 @@ function main(
5347
ServerInterface $server,
5448
RouterInterface $router,
5549
):void {
56-
$router->addHandler("POST", "/cats", handler(...))->unwrap($error);
57-
58-
if ($error) {
59-
die($error)
60-
}
61-
62-
$server->start()->unwrap($error);
50+
$router->addHandler("POST", "/cats", handler(...))
51+
->unwrap($error) ?? die($error);
6352

64-
if ($error) {
65-
die($error)
66-
}
53+
$server->start()
54+
->unwrap($error) ?? die($error);
6755
}
6856
```
6957

@@ -82,11 +70,7 @@ function main(ServerInterface $server):void {
8270
->withApiLocation("src/api")
8371
->withApiPrefix("/api/v1")
8472
->start()
85-
->unwrap($error);
86-
87-
if ($error) {
88-
die($error)
89-
}
73+
->unwrap($error) ?? die($error);
9074
}
9175
```
9276

src/lib/Core/Directory.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,23 +74,23 @@ public static function create(string $directoryName, int $mode = 0777):Result {
7474
*/
7575
public static function flat(string $directoryName):Result {
7676
try {
77-
$result = [];
78-
$list = Directory::list($directoryName)->unwrap($error);
77+
$items = [];
78+
$list = Directory::list($directoryName)->unwrap($error);
7979
if ($error) {
8080
return error($error);
8181
}
8282
foreach ($list as $fileName) {
8383
if (isFile($fileName)) {
84-
$result[] = $fileName;
84+
$items[] = $fileName;
8585
} else {
86-
$flatList = Directory::flat($fileName)->unwrap($error);
86+
$flatList = Directory::flat($fileName)->unwrap($error) ?? [];
8787
if ($error) {
8888
return error($error);
8989
}
90-
$result = [...$result, ...$flatList];
90+
$items = [...$items, ...$flatList];
9191
}
9292
}
93-
return ok($result);
93+
return ok($items);
9494
} catch(Throwable $e) {
9595
return error($e);
9696
}

src/lib/Core/File.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ public static function readFile(string $fileName):Result {
214214
if ($error) {
215215
return error($error);
216216
}
217-
$contents = $file->readAll()->unwrap($error);
217+
$contents = $file->readAll()->unwrap($error) ?? "";
218218
if ($error) {
219219
return error($error);
220220
}

src/lib/Core/Result.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
readonly class Result {
1717
/**
18-
* @param T $value
18+
* @param null|T $value
1919
* @param null|Error $error
2020
*/
2121
public function __construct(
@@ -65,13 +65,12 @@ public function logError():void {
6565

6666
/**
6767
*
68-
* @param Error $error
69-
* @return T
68+
* @param Error $error
69+
* @return null|T
7070
*/
7171
public function unwrap(&$error = null) {
7272
if ($this->error) {
7373
$error = $this->error;
74-
/** @var T */
7574
return null;
7675
}
7776
$error = null;

src/lib/Web/Implementations/ByteRange/SimpleByteRange.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ public function contentType():Result {
234234
}
235235

236236
public function contentLength():Result {
237-
$size = File::size($this->fileName)->unwrap($error);
237+
$size = File::size($this->fileName)->unwrap($error) ?? 0;
238238
if ($error) {
239239
return error($error);
240240
}

0 commit comments

Comments
 (0)