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