| 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: |