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