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