Skip to content

Commit

Permalink
feat(option): add Option::proceed() method (#433)
Browse files Browse the repository at this point in the history
* feat(option): add `Option::match()` method

* Requested changes, static analysis tests

* Rewritten some tests from a complex example to a simpler one
  • Loading branch information
devnix authored Dec 29, 2023
1 parent 6f19d45 commit bbc9eba
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/Psl/Option/Option.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,29 @@ public function contains(mixed $value): bool
return false;
}

/**
* Matches the contained option value with the provided closures and returns the result.
*
* @template Ts
*
* @param (Closure(T): Ts) $some A closure to be called when the option is some.
* The closure must accept the option value as its only argument and can return a value.
* Example: `fn($value) => $value + 10`
* @param (Closure(): Ts) $none A closure to be called when the option is none.
* The closure must not accept any arguments and can return a value.
* Example: `fn() => 'Default value'`
*
* @return Ts The result of calling the appropriate closure.
*/
public function proceed(Closure $some, Closure $none): mixed
{
if ($this->option !== null) {
return $some($this->option[0]);
}

return $none();
}

/**
* Maps an `Option<T>` to `Option<Tu>` by applying a function to a contained value.
*
Expand Down
21 changes: 21 additions & 0 deletions tests/static-analysis/Option/proceed.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

use Psl\Option;

function proceed(): void
{
/**
* @param Option\Option<int> $option
*
* @return non-empty-string
*/
function test_proceed(Option\Option $option): string
{
return $option->proceed(
static fn (int $value) => "There is $value of them.",
static fn () => 'There are none.',
);
}
}
11 changes: 11 additions & 0 deletions tests/unit/Option/NoneTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Psl\Comparison\Order;
use Psl\Option;
use Psl\Option\Exception\NoneException;
use Psl\Str;

final class NoneTest extends TestCase
{
Expand Down Expand Up @@ -84,6 +85,16 @@ public function testContains(): void
static::assertFalse($option->contains(4));
}

public function testProceed(): void
{
$result = Option\none()->proceed(
static fn ($i) => Str\format('Value is %d', $i),
static fn () => 'There is no value',
);

static::assertSame('There is no value', $result);
}

public function testMap(): void
{
$option = Option\none();
Expand Down
11 changes: 11 additions & 0 deletions tests/unit/Option/SomeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Psl\Comparison\Equable;
use Psl\Comparison\Order;
use Psl\Option;
use Psl\Str;
use Psl\Tests\Fixture;
use Psl\Type;

Expand Down Expand Up @@ -83,6 +84,16 @@ public function testContains(): void
static::assertTrue($option->contains(2));
}

public function testProceed(): void
{
$result = Option\some(1)->proceed(
static fn ($i) => Str\format('Value is %d', $i),
static fn () => 'There is no value',
);

static::assertSame('Value is 1', $result);
}

public function testMap(): void
{
$option = Option\some(2);
Expand Down

0 comments on commit bbc9eba

Please sign in to comment.