1: <?php
2:
3: declare(strict_types=1);
4:
5: /**
6: * This file is part of the Nexus framework.
7: *
8: * (c) John Paul E. Balandan, CPA <paulbalandan@gmail.com>
9: *
10: * For the full copyright and license information, please view
11: * the LICENSE file that was distributed with this source code.
12: */
13:
14: namespace Nexus\Result;
15:
16: /**
17: * @template E
18: *
19: * @implements Result<never, E>
20: */
21: final readonly class Err implements Result
22: {
23: /**
24: * @param E $err
25: */
26: public function __construct(
27: private mixed $err,
28: ) {}
29:
30: public function isOk(): bool
31: {
32: return false;
33: }
34:
35: public function isOkAnd(\Closure $predicate): bool
36: {
37: return false;
38: }
39:
40: public function isErr(): bool
41: {
42: return true;
43: }
44:
45: public function isErrAnd(\Closure $predicate): bool
46: {
47: return $predicate($this->err);
48: }
49:
50: /**
51: * @return self<E>
52: */
53: public function map(\Closure $predicate): self
54: {
55: return $this;
56: }
57:
58: public function mapOr(mixed $default, \Closure $predicate): mixed
59: {
60: return $default;
61: }
62:
63: public function mapOrElse(\Closure $default, \Closure $predicate): mixed
64: {
65: return $default($this->err);
66: }
67:
68: /**
69: * @template F
70: *
71: * @param (\Closure(E): F) $predicate
72: *
73: * @return self<F>
74: */
75: public function mapErr(\Closure $predicate): self
76: {
77: return new self($predicate($this->err));
78: }
79:
80: public function unwrap(): never
81: {
82: $message = static fn(string $arg): string => \sprintf('Unwrapped an Err result: %s', $arg);
83:
84: if ($this->err instanceof \Throwable) {
85: throw new UnwrappedResultException($message($this->err->getMessage()), 0, $this->err);
86: }
87:
88: if (\is_scalar($this->err)) {
89: throw new UnwrappedResultException($message(var_export($this->err, true)));
90: }
91:
92: throw new UnwrappedResultException('Unwrapped an Err result.');
93: }
94:
95: /**
96: * @template U
97: *
98: * @param U $default
99: *
100: * @return U
101: */
102: public function unwrapOr(mixed $default): mixed
103: {
104: return $default;
105: }
106:
107: /**
108: * @template U
109: *
110: * @param (\Closure(E): U) $op
111: *
112: * @return U
113: */
114: public function unwrapOrElse(\Closure $op): mixed
115: {
116: return $op($this->err);
117: }
118:
119: public function unwrapErr(): mixed
120: {
121: return $this->err;
122: }
123:
124: /**
125: * @return self<E>
126: */
127: public function and(Result $res): self
128: {
129: return $this;
130: }
131:
132: /**
133: * @return self<E>
134: */
135: public function andThen(\Closure $op): self
136: {
137: return $this;
138: }
139:
140: /**
141: * @template T
142: * @template F
143: * @template R of Result<T, F>
144: *
145: * @param R $res
146: *
147: * @return R
148: */
149: public function or(Result $res): Result
150: {
151: return $res;
152: }
153:
154: /**
155: * @template T
156: * @template F
157: * @template R of Result<T, F>
158: *
159: * @param (\Closure(E): R) $op
160: *
161: * @return R
162: */
163: public function orElse(\Closure $op): Result
164: {
165: return $op($this->err);
166: }
167: }
168: