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: /**
131: * @throws void
132: */
133: #[\Override]
134: public function unwrapErr(): mixed
135: {
136: return $this->err;
137: }
138:
139: /**
140: * @return self<E>
141: */
142: #[\Override]
143: public function and(Result $res): self
144: {
145: return $this;
146: }
147:
148: /**
149: * @return self<E>
150: */
151: #[\Override]
152: public function andThen(\Closure $op): self
153: {
154: return $this;
155: }
156:
157: /**
158: * @template T
159: * @template F
160: * @template R of Result<T, F>
161: *
162: * @param R $res
163: *
164: * @return R
165: */
166: #[\Override]
167: public function or(Result $res): Result
168: {
169: return $res;
170: }
171:
172: /**
173: * @template T
174: * @template F
175: * @template R of Result<T, F>
176: *
177: * @param (\Closure(E): R) $op
178: *
179: * @return R
180: */
181: #[\Override]
182: public function orElse(\Closure $op): Result
183: {
184: return $op($this->err);
185: }
186: }
187: