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