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: | * @template T |
18: | * |
19: | * @implements Option<T> |
20: | */ |
21: | final readonly class Some implements Option |
22: | { |
23: | /** |
24: | * @param T $value |
25: | */ |
26: | public function __construct( |
27: | private mixed $value, |
28: | ) {} |
29: | |
30: | public function isSome(): bool |
31: | { |
32: | return true; |
33: | } |
34: | |
35: | public function isSomeAnd(\Closure $predicate): bool |
36: | { |
37: | return $predicate($this->value); |
38: | } |
39: | |
40: | public function isNone(): bool |
41: | { |
42: | return false; |
43: | } |
44: | |
45: | public function unwrap(): mixed |
46: | { |
47: | return $this->value; |
48: | } |
49: | |
50: | /** |
51: | * @return T |
52: | */ |
53: | public function unwrapOr(mixed $default): mixed |
54: | { |
55: | return $this->value; |
56: | } |
57: | |
58: | /** |
59: | * @return T |
60: | */ |
61: | public function unwrapOrElse(\Closure $default): mixed |
62: | { |
63: | return $this->value; |
64: | } |
65: | |
66: | /** |
67: | * @template U |
68: | * |
69: | * @param (\Closure(T): U) $predicate |
70: | * |
71: | * @return self<U> |
72: | */ |
73: | public function map(\Closure $predicate): self |
74: | { |
75: | return new self($predicate($this->value)); |
76: | } |
77: | |
78: | /** |
79: | * @template U |
80: | * @template V |
81: | * |
82: | * @param V $default |
83: | * @param (\Closure(T): U) $predicate |
84: | * |
85: | * @return U |
86: | */ |
87: | public function mapOr(mixed $default, \Closure $predicate): mixed |
88: | { |
89: | return $predicate($this->value); |
90: | } |
91: | |
92: | public function mapOrElse(\Closure $default, \Closure $predicate): mixed |
93: | { |
94: | return $predicate($this->value); |
95: | } |
96: | |
97: | public function and(Option $other): Option |
98: | { |
99: | return $other; |
100: | } |
101: | |
102: | public function andThen(\Closure $predicate): Option |
103: | { |
104: | return $predicate($this->value); |
105: | } |
106: | |
107: | public function filter(\Closure $predicate): Option |
108: | { |
109: | return $predicate($this->value) ? $this : new None(); |
110: | } |
111: | |
112: | /** |
113: | * @template S of Option |
114: | * |
115: | * @param S $other |
116: | * |
117: | * @return self<T> |
118: | */ |
119: | public function or(Option $other): self |
120: | { |
121: | return $this; |
122: | } |
123: | |
124: | /** |
125: | * @template S of Option |
126: | * |
127: | * @param (\Closure(): S) $other |
128: | * |
129: | * @return self<T> |
130: | */ |
131: | public function orElse(\Closure $other): self |
132: | { |
133: | return $this; |
134: | } |
135: | |
136: | /** |
137: | * @template S |
138: | * |
139: | * @param Option<S> $other |
140: | * |
141: | * @return ($other is Some<S> ? None : self<T>) |
142: | */ |
143: | public function xor(Option $other): Option |
144: | { |
145: | return $other->isSome() ? new None() : $this; |
146: | } |
147: | |
148: | /** |
149: | * @return \ArrayIterator<int, T> |
150: | */ |
151: | public function getIterator(): \Traversable |
152: | { |
153: | return new \ArrayIterator([$this->value]); |
154: | } |
155: | } |
156: |