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: