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