Skip to content

Commit 03613bd

Browse files
committed
feat: Resultモナドにmatchメソッドを追加し、OkとErrの処理を統一
Fixes #38
1 parent 294a7bb commit 03613bd

File tree

4 files changed

+117
-0
lines changed

4 files changed

+117
-0
lines changed

src/Result.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,16 @@ public function ok(): Option;
190190
* @return Option<E>
191191
*/
192192
public function err(): Option;
193+
194+
/**
195+
* Applies one of two functions depending on whether the result is Ok or Err.
196+
* Comparable to neverthrow's `match` method.
197+
*
198+
* @template U
199+
* @template V
200+
* @param Closure(T): U $okFn Function to apply if the Result is Ok
201+
* @param Closure(E): V $errFn Function to apply if the Result is Err
202+
* @return U|V The result of applying the appropriate function
203+
*/
204+
public function match(Closure $okFn, Closure $errFn): mixed;
193205
}

src/Result/Err.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,4 +245,10 @@ public function getIterator(): Traversable
245245
{
246246
return new EmptyIterator();
247247
}
248+
249+
#[Override]
250+
public function match(Closure $okFn, Closure $errFn): mixed
251+
{
252+
return $errFn($this->value);
253+
}
248254
}

src/Result/Ok.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,4 +238,10 @@ public function getIterator(): Traversable
238238
{
239239
yield $this->value;
240240
}
241+
242+
#[Override]
243+
public function match(Closure $okFn, Closure $errFn): mixed
244+
{
245+
return $okFn($this->value);
246+
}
241247
}

tests/Unit/Result/MatchTest.php

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace WizDevelop\PhpMonad\Tests\Unit\Result;
6+
7+
use PHPUnit\Framework\Attributes\CoversClass;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
use PHPUnit\Framework\Attributes\Test;
10+
use PHPUnit\Framework\Attributes\TestDox;
11+
use WizDevelop\PhpMonad\Result;
12+
use WizDevelop\PhpMonad\Tests\Assert;
13+
use WizDevelop\PhpMonad\Tests\TestCase;
14+
15+
#[TestDox('Result - MatchTest')]
16+
#[CoversClass(Result::class)]
17+
final class MatchTest extends TestCase
18+
{
19+
/**
20+
* @return Result<int, string>
21+
*/
22+
public function createResult(): Result
23+
{
24+
return Result\ok(42);
25+
}
26+
27+
/**
28+
* @template T
29+
* @template E
30+
* @template U
31+
* @param Result<T, E> $result
32+
* @param U $okValue Value to return when Result is Ok
33+
* @param U $errValue Value to return when Result is Err
34+
* @param U $expected Expected outcome
35+
* @param array<T|E> $expectedCalls Values that should be passed to the callbacks
36+
*/
37+
#[Test]
38+
#[TestDox('match test')]
39+
#[DataProvider('matchMatrix')]
40+
public function match(
41+
Result $result,
42+
mixed $okValue,
43+
mixed $errValue,
44+
mixed $expected,
45+
array $expectedCalls
46+
): void {
47+
$calls = [];
48+
49+
$actual = $result->match(
50+
static function (mixed $value) use ($okValue, &$calls): mixed {
51+
$calls[] = $value;
52+
53+
return $okValue;
54+
},
55+
static function (mixed $value) use ($errValue, &$calls): mixed {
56+
$calls[] = $value;
57+
58+
return $errValue;
59+
}
60+
);
61+
62+
Assert::assertSame($expected, $actual);
63+
Assert::assertSame($expectedCalls, $calls);
64+
}
65+
66+
/**
67+
* @return iterable<array{
68+
* Result\Ok<int>|Result\Err<string>,
69+
* string,
70+
* string,
71+
* string,
72+
* array<int|string>
73+
* }>
74+
*/
75+
public static function matchMatrix(): iterable
76+
{
77+
yield 'ok' => [
78+
Result\ok(42),
79+
'success',
80+
'failure',
81+
'success',
82+
[42],
83+
];
84+
85+
yield 'err' => [
86+
Result\err('error'),
87+
'success',
88+
'failure',
89+
'failure',
90+
['error'],
91+
];
92+
}
93+
}

0 commit comments

Comments
 (0)