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: | #[\Override] |
31: | public function isOk(): bool |
32: | { |
33: | return false; |
34: | } |
35: | |
36: | #[\Override] |
37: | public function isOkAnd(\Closure $predicate): bool |
38: | { |
39: | return false; |
40: | } |
41: | |
42: | #[\Override] |
43: | public function isErr(): bool |
44: | { |
45: | return true; |
46: | } |
47: | |
48: | #[\Override] |
49: | public function isErrAnd(\Closure $predicate): bool |
50: | { |
51: | return $predicate($this->err); |
52: | } |
53: | |
54: | /** |
55: | * @return self<E> |
56: | */ |
57: | #[\Override] |
58: | public function map(\Closure $predicate): self |
59: | { |
60: | return $this; |
61: | } |
62: | |
63: | #[\Override] |
64: | public function mapOr(mixed $default, \Closure $predicate): mixed |
65: | { |
66: | return $default; |
67: | } |
68: | |
69: | #[\Override] |
70: | public function mapOrElse(\Closure $default, \Closure $predicate): mixed |
71: | { |
72: | return $default($this->err); |
73: | } |
74: | |
75: | /** |
76: | * @template F |
77: | * |
78: | * @param (\Closure(E): F) $predicate |
79: | * |
80: | * @return self<F> |
81: | */ |
82: | #[\Override] |
83: | public function mapErr(\Closure $predicate): self |
84: | { |
85: | return new self($predicate($this->err)); |
86: | } |
87: | |
88: | #[\Override] |
89: | public function unwrap(): never |
90: | { |
91: | $message = static fn(string $arg): string => \sprintf('Unwrapped an Err result: %s', $arg); |
92: | |
93: | if ($this->err instanceof \Throwable) { |
94: | throw new UnwrappedResultException($message($this->err->getMessage()), 0, $this->err); |
95: | } |
96: | |
97: | if (\is_scalar($this->err)) { |
98: | throw new UnwrappedResultException($message(var_export($this->err, true))); |
99: | } |
100: | |
101: | throw new UnwrappedResultException('Unwrapped an Err result.'); |
102: | } |
103: | |
104: | /** |
105: | * @template U |
106: | * |
107: | * @param U $default |
108: | * |
109: | * @return U |
110: | */ |
111: | #[\Override] |
112: | public function unwrapOr(mixed $default): mixed |
113: | { |
114: | return $default; |
115: | } |
116: | |
117: | /** |
118: | * @template U |
119: | * |
120: | * @param (\Closure(E): U) $op |
121: | * |
122: | * @return U |
123: | */ |
124: | #[\Override] |
125: | public function unwrapOrElse(\Closure $op): mixed |
126: | { |
127: | return $op($this->err); |
128: | } |
129: | |
130: | #[\Override] |
131: | public function unwrapErr(): mixed |
132: | { |
133: | return $this->err; |
134: | } |
135: | |
136: | /** |
137: | * @return self<E> |
138: | */ |
139: | #[\Override] |
140: | public function and(Result $res): self |
141: | { |
142: | return $this; |
143: | } |
144: | |
145: | /** |
146: | * @return self<E> |
147: | */ |
148: | #[\Override] |
149: | public function andThen(\Closure $op): self |
150: | { |
151: | return $this; |
152: | } |
153: | |
154: | /** |
155: | * @template T |
156: | * @template F |
157: | * @template R of Result<T, F> |
158: | * |
159: | * @param R $res |
160: | * |
161: | * @return R |
162: | */ |
163: | #[\Override] |
164: | public function or(Result $res): Result |
165: | { |
166: | return $res; |
167: | } |
168: | |
169: | /** |
170: | * @template T |
171: | * @template F |
172: | * @template R of Result<T, F> |
173: | * |
174: | * @param (\Closure(E): R) $op |
175: | * |
176: | * @return R |
177: | */ |
178: | #[\Override] |
179: | public function orElse(\Closure $op): Result |
180: | { |
181: | return $op($this->err); |
182: | } |
183: | } |
184: |