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: