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: