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