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