Skip to content

Commit

Permalink
review type hints and refactor Error class
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelmaudo committed Apr 5, 2022
1 parent 5cf281a commit bf5b31e
Show file tree
Hide file tree
Showing 12 changed files with 807 additions and 222 deletions.
118 changes: 71 additions & 47 deletions src/AbstractResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,36 @@
use Hereldar\Results\Exceptions\UnusedResult;
use Hereldar\Results\Interfaces\IResult;
use RuntimeException;
use Throwable;

/**
* @template T
* @template E of Throwable
*
* @implements IResult<T>
* @implements IResult<T, E>
*/
abstract class AbstractResult implements IResult
{
protected bool $used = false;
private string $trace;
protected readonly ?Throwable $exception;
private readonly string $trace;

/**
* @param T $value
* @param E|string $exception
*/
public function __construct(
protected readonly mixed $value = null,
protected readonly string $message = ''
Throwable|string $exception = null
) {
ob_start();
debug_print_backtrace(limit: 5);
$this->trace = ob_get_contents();
ob_end_clean();

$this->exception = (is_string($exception))
? new RuntimeException($exception)
: $exception;
}

public function __destruct()
Expand All @@ -40,32 +48,46 @@ public function __destruct()
}

/**
* @template T2
* @template U
* @template F of Throwable
*
* @param IResult<T2>|Closure(T):IResult<T2> $default
* @param IResult<U, F>|Closure(T):IResult<U, F> $result
*
* @return IResult<T2>|$this
* @return IResult<U, E|F>
*/
public function andThen(IResult|Closure $default): IResult
public function andThen(IResult|Closure $result): IResult
{
$this->used = true;

if ($this->isError()) {
return $this;
}

if ($default instanceof Closure) {
return $default($this->value());
if ($result instanceof Closure) {
return $result($this->value());
}

return $default;
return $result;
}

public function hasMessage(): bool
/**
* @return E|null
*/
public function exception(): ?Throwable
{
$this->used = true;

return $this->exception;
}

public function hasException(): bool
{
$this->used = true;

return ($this->message !== '');
return isset($this->exception);
}

public function hasMessage(): bool
{
return ($this->message() !== '');
}

public function hasValue(): bool
Expand All @@ -83,40 +105,40 @@ public function message(): string
{
$this->used = true;

return $this->message;
if (!isset($this->exception)) {
return '';
}

return $this->exception->getMessage();
}

/**
* @template T2
* @template U
*
* @param T2|Closure():T2 $default
* @param U|Closure():U $value
*
* @return T|T2
* @return T|U
*/
public function or(mixed $default): mixed
public function or(mixed $value): mixed
{
$this->used = true;

if ($this->isOk()) {
return $this->value;
}

if ($default instanceof Closure) {
return $default();
if ($value instanceof Closure) {
return $value();
}

return $default;
return $value;
}

/**
* @return T
*/
public function orDie(int|string $status = null): mixed
{
$this->used = true;

if ($this->isOk()) {
return null;
return $this->value;
}

if (isset($status)) {
Expand All @@ -127,41 +149,45 @@ public function orDie(int|string $status = null): mixed
}

/**
* @template T2
* @template U
* @template F of Throwable
*
* @param IResult<T2>|Closure():IResult<T2> $default
* @param IResult<U, F>|Closure():IResult<U, F> $result
*
* @return $this|IResult<T2>
* @return IResult<T|U, F>
*/
public function orElse(IResult|Closure $default): IResult
public function orElse(IResult|Closure $result): IResult
{
$this->used = true;

if ($this->isOk()) {
return $this;
}

if ($default instanceof Closure) {
return $default();
if ($result instanceof Closure) {
return $result();
}

return $default;
return $result;
}

/**
* @throws RuntimeException
* @throws E
*
* @return T
*/
abstract public function orFail(): mixed;
public function orFail(): mixed
{
if ($this->isOk()) {
return $this->value;
}

throw $this->exception;
}

/**
* @return T|null
*/
public function orNull(): mixed
{
$this->used = true;

if ($this->isOk()) {
return $this->value;
}
Expand All @@ -170,20 +196,18 @@ public function orNull(): mixed
}

/**
* @template TException of RuntimeException
* @template F of Throwable
*
* @param TException $exception
* @param F|Closure():F $exception
*
* @throws TException
* @throws F
*
* @return T
*/
public function orThrow(RuntimeException $exception): mixed
public function orThrow(Throwable $exception): mixed
{
$this->used = true;

if ($this->isOk()) {
return null;
return $this->value;
}

throw $exception;
Expand Down
Loading

0 comments on commit bf5b31e

Please sign in to comment.