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\Option; |
15: | |
16: | /** |
17: | * A PHP implementation of Rust's Option enum. |
18: | * |
19: | * @see https://doc.rust-lang.org/std/option/enum.Option.html |
20: | * |
21: | * @template T |
22: | * |
23: | * @extends \IteratorAggregate<int, T> |
24: | */ |
25: | interface Option extends \IteratorAggregate |
26: | { |
27: | /** |
28: | * Returns `true` if the option is a **Some** value. |
29: | * |
30: | * @phpstan-assert-if-true Some<T> $this |
31: | * @phpstan-assert-if-true false $this->isNone() |
32: | * @phpstan-assert-if-false None $this |
33: | * @phpstan-assert-if-false true $this->isNone() |
34: | */ |
35: | public function isSome(): bool; |
36: | |
37: | /** |
38: | * Returns `true` if the option is a **Some** and the value inside of it matches a predicate. |
39: | * |
40: | * @param (\Closure(T): bool) $predicate |
41: | */ |
42: | public function isSomeAnd(\Closure $predicate): bool; |
43: | |
44: | /** |
45: | * Returns `true` if the option is a **None** value. |
46: | * |
47: | * @phpstan-assert-if-true None $this |
48: | * @phpstan-assert-if-true false $this->isSome() |
49: | * @phpstan-assert-if-false Some<T> $this |
50: | * @phpstan-assert-if-false true $this->isSome() |
51: | */ |
52: | public function isNone(): bool; |
53: | |
54: | /** |
55: | * Returns the contained **Some** value, consuming the `self` value. |
56: | * |
57: | * Because this method may throw, its use is generally discouraged. |
58: | * Instead, prefer to call `Option::unwrapOr()` or `Option::unwrapOrElse()`. |
59: | * |
60: | * @return T |
61: | * |
62: | * @throws NoneException |
63: | */ |
64: | public function unwrap(): mixed; |
65: | |
66: | /** |
67: | * Returns the contained **Some** value or a provided default. |
68: | * |
69: | * Arguments passed to `Option::unwrapOr()` are eagerly evaluated; if you are |
70: | * passing the result of a function call, it is recommended to use `Option::unwrapOrElse()`, |
71: | * which is lazily evaluated. |
72: | * |
73: | * @template S |
74: | * |
75: | * @param S $default |
76: | * |
77: | * @return S|T |
78: | */ |
79: | public function unwrapOr(mixed $default): mixed; |
80: | |
81: | /** |
82: | * Returns the contained **Some** value or computes it from a closure. |
83: | * |
84: | * @template S |
85: | * |
86: | * @param (\Closure(): S) $default |
87: | * |
88: | * @return S|T |
89: | */ |
90: | public function unwrapOrElse(\Closure $default): mixed; |
91: | |
92: | /** |
93: | * Maps an `Option<T>` to `Option<U>` by applying a function to a |
94: | * contained value (if **Some**) or returns `None` (if **None**). |
95: | * |
96: | * @template U |
97: | * |
98: | * @param (\Closure(T): U) $predicate |
99: | * |
100: | * @return self<U> |
101: | */ |
102: | public function map(\Closure $predicate): self; |
103: | |
104: | /** |
105: | * Returns the provided default result (if none), or applies a function |
106: | * to the contained value (if any). |
107: | * |
108: | * Arguments passed to `Option::mapOr()` are eagerly evaluated; if you are |
109: | * passing the result of a function call, it is recommended to use `Option::mapOrElse()`, |
110: | * which is lazily evaluated. |
111: | * |
112: | * @template U |
113: | * @template V |
114: | * |
115: | * @param V $default |
116: | * @param (\Closure(T): U) $predicate |
117: | * |
118: | * @return U|V |
119: | */ |
120: | public function mapOr(mixed $default, \Closure $predicate): mixed; |
121: | |
122: | /** |
123: | * Computes a default function result (if none), or applies a different function |
124: | * to the contained value (if any). |
125: | * |
126: | * @template U |
127: | * @template V |
128: | * |
129: | * @param (\Closure(): V) $default |
130: | * @param (\Closure(T): U) $predicate |
131: | * |
132: | * @return U|V |
133: | */ |
134: | public function mapOrElse(\Closure $default, \Closure $predicate): mixed; |
135: | |
136: | /** |
137: | * Returns **None** if the option is **None**, otherwise returns `$other`. |
138: | * |
139: | * Arguments passed to `Option::and()` are eagerly evaluated; if you are |
140: | * passing the result of a function call, it is recommended to use `Option::andThen()`, |
141: | * which is lazily evaluated. |
142: | * |
143: | * @template U of Option |
144: | * |
145: | * @param U $other |
146: | * |
147: | * @return U |
148: | */ |
149: | public function and(self $other): self; |
150: | |
151: | /** |
152: | * Returns **None** if the option is **None**, otherwise calls `$other` with the wrapped |
153: | * value and returns the result. |
154: | * |
155: | * @template U of Option |
156: | * |
157: | * @param (\Closure(T): U) $predicate |
158: | * |
159: | * @return U |
160: | */ |
161: | public function andThen(\Closure $predicate): self; |
162: | |
163: | /** |
164: | * Returns **None** if the option is **None**, otherwise calls `$predicate` |
165: | * with the wrapped value and returns: |
166: | * - `Some(t)` if predicate returns true (where `t` is the wrapped value), and |
167: | * - `None` if predicate returns false. |
168: | * |
169: | * @param (\Closure(T): bool) $predicate |
170: | * |
171: | * @return self<T> |
172: | */ |
173: | public function filter(\Closure $predicate): self; |
174: | |
175: | /** |
176: | * Returns the option if it contains a value, otherwise returns `$other`. |
177: | * |
178: | * Arguments passed to `Option::or()` are eagerly evaluated; if you are |
179: | * passing the result of a function call, it is recommended to use `Option::orElse()`, |
180: | * which is lazily evaluated. |
181: | * |
182: | * @template S of Option |
183: | * |
184: | * @param S $other |
185: | * |
186: | * @return S |
187: | */ |
188: | public function or(self $other): self; |
189: | |
190: | /** |
191: | * Returns the option if it contains a value, otherwise calls |
192: | * `$other` and returns the result. |
193: | * |
194: | * @template S of Option |
195: | * |
196: | * @param (\Closure(): S) $other |
197: | * |
198: | * @return S |
199: | */ |
200: | public function orElse(\Closure $other): self; |
201: | |
202: | /** |
203: | * Returns **Some** if exactly one of `self`, `$other` is **Some**, otherwise returns **None**. |
204: | * |
205: | * @template S |
206: | * |
207: | * @param self<S> $other |
208: | * |
209: | * @return self<S> |
210: | */ |
211: | public function xor(self $other): self; |
212: | } |
213: |