Skip to content

Commit

Permalink
introduce Result abstract class with a few helper static methods
Browse files Browse the repository at this point in the history
  • Loading branch information
someniatko committed Jul 29, 2022
1 parent 41e8a4f commit bcc17aa
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/Error.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

/**
* @template-covariant TError
* @template-implements ResultInterface<never-return, TError>
* @template-extends Result<never, TError>
* @psalm-immutable
*/
final class Error implements ResultInterface
final class Error extends Result
{
/** @var TError */
private $value;
Expand Down
94 changes: 94 additions & 0 deletions src/Result.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

declare(strict_types=1);

namespace Someniatko\ResultType;

/**
* @template-covariant TSuccess
* @template-covariant TError
* @template-implements ResultInterface<TSuccess, TError>
* @psalm-immutable
*/
abstract class Result implements ResultInterface
{
/**
* @template T
* @param T $value
* @return Success<T>
*/
public static function success($value): Success
{
return new Success($value);
}

/**
* @template T
* @param T $value
* @return Error<T>
*/
public static function error($value): Error
{
return new Error($value);
}

/**
* Filters and extracts values only of Success results from the given array.
*
* @template S
* @param list<ResultInterface<S, mixed>> $results
* @return list<S>
*/
public static function extractSuccesses(array $results): array
{
return array_reduce(
$results,
/**
* @param list<S> $carry
* @param ResultInterface<S, mixed> $result
* @return list<S>
*/
static fn(array $carry, ResultInterface $result) => $result
->mapError(fn() => $carry)
->map(
/**
* @param S $t
* @return list<S>
*/
fn($t) => array_merge($carry, [ $t ])
)
->get(),
[],
);
}

/**
* Filters and extracts values only of Error results from the given array.
*
* @template E
* @param list<ResultInterface<mixed, E>> $results
* @return list<E>
*/
public static function extractErrors(array $results): array
{
return array_reduce(
$results,
/**
* @param list<E> $carry
* @param ResultInterface<mixed, E> $result
* @return list<E>
*/
static fn(array $carry, ResultInterface $result) => $result
->map(fn() => $carry)
->mapError(
/**
* @param E $t
* @return list<E>
*/
fn($t) => array_merge($carry, [ $t ])
)
->get(),
[],
);
}
}
4 changes: 2 additions & 2 deletions src/Success.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

/**
* @template-covariant TSuccess
* @template-implements ResultInterface<TSuccess, never-return>
* @template-extends Result<TSuccess, never>
* @psalm-immutable
*/
final class Success implements ResultInterface
final class Success extends Result
{
/** @var TSuccess */
private $value;
Expand Down
27 changes: 27 additions & 0 deletions test/ResultTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use PHPUnit\Framework\TestCase;
use Someniatko\ResultType\Error;
use Someniatko\ResultType\Result;
use Someniatko\ResultType\ResultInterface;
use Someniatko\ResultType\Success;

Expand Down Expand Up @@ -146,4 +147,30 @@ public function testGetOrThrowOnError(): void
/** @psalm-suppress UnusedMethodCall */
$result->getOrThrow(new \RuntimeException('expected'));
}

public function testSuccesses(): void
{
$results = [
Result::success(1),
Result::success(2),
Result::error(3),
Result::success(4),
Result::error(5),
];

self::assertEquals([ 1, 2, 4 ], Result::extractSuccesses($results));
}

public function testErrors(): void
{
$results = [
Result::success(1),
Result::success(2),
Result::error(3),
Result::success(4),
Result::error(5),
];

self::assertEquals([ 3, 5 ], Result::extractErrors($results));
}
}

0 comments on commit bcc17aa

Please sign in to comment.