6
6
use RuntimeException ;
7
7
use Throwable ;
8
8
use Toolkit \Stdlib \Obj ;
9
+ use Toolkit \Stdlib \Util \Stream \DataStream ;
9
10
use UnexpectedValueException ;
10
11
use function gettype ;
11
12
12
13
/**
13
- * class Optional
14
+ * class Optional - like java: java.util.Optional
14
15
*
15
16
* @template T
16
17
*
@@ -22,7 +23,7 @@ final class Optional
22
23
/**
23
24
* @var self|null
24
25
*/
25
- private static ?Optional $ empty ;
26
+ private static ?Optional $ empty = null ;
26
27
27
28
/**
28
29
* Returns an Optional with the specified present non-null value.
@@ -136,7 +137,15 @@ public function get()
136
137
*/
137
138
public function isNull (): bool
138
139
{
139
- return $ this ->value !== null ;
140
+ return $ this ->value === null ;
141
+ }
142
+
143
+ /**
144
+ * @return bool
145
+ */
146
+ public function isEmpty (): bool
147
+ {
148
+ return $ this ->value === null ;
140
149
}
141
150
142
151
/**
@@ -179,7 +188,7 @@ public function filter(callable $checker): self
179
188
/**
180
189
* If a value is present, apply the provided mapping function to it,
181
190
* and if the result is non-null, return an Optional describing the result.
182
- * Otherwise return an empty Optional
191
+ * Otherwise, return an empty Optional
183
192
*
184
193
* ```php
185
194
* Optional::of("foo")->map('strtoupper')->get(); // "FOO"
@@ -227,12 +236,46 @@ public function flatMap(callable $flatMapper): self
227
236
return $ new ;
228
237
}
229
238
239
+ /**
240
+ * @param callable():Optional<T> $supplier
241
+ *
242
+ * @return $this
243
+ */
244
+ public function or (callable $ supplier ): self
245
+ {
246
+ if ($ this ->isPresent ()) {
247
+ return $ this ;
248
+ }
249
+
250
+ $ new = $ supplier ();
251
+ if (!$ new instanceof self) {
252
+ throw new UnexpectedValueException ('must return an object and instance of ' . self ::class);
253
+ }
254
+
255
+ return $ new ;
256
+ }
257
+
258
+ /**
259
+ * If a value is present, returns a sequential Stream containing only that value,
260
+ * otherwise returns an empty Stream.
261
+ *
262
+ * @return DataStream<T>
263
+ */
264
+ public function stream (): DataStream
265
+ {
266
+ if (!$ this ->isPresent ()) {
267
+ return DataStream::empty ();
268
+ }
269
+
270
+ return DataStream::of ($ this ->value );
271
+ }
272
+
230
273
/**
231
274
* @param T $other
232
275
*
233
276
* @return T
234
277
*/
235
- public function orElse ($ other )
278
+ public function orElse (mixed $ other )
236
279
{
237
280
return $ this ->value ?? $ other ;
238
281
}
@@ -248,17 +291,21 @@ public function orElseGet(callable $valCreator)
248
291
}
249
292
250
293
/**
251
- * @param callable(): Throwable $errCreator
294
+ * @param null| callable():Throwable $errCreator
252
295
*
253
296
* @return T
254
297
*/
255
- public function orElseThrow (callable $ errCreator )
298
+ public function orElseThrow (callable $ errCreator = null )
256
299
{
257
300
if ($ this ->value !== null ) {
258
301
return $ this ->value ;
259
302
}
260
303
261
- throw $ errCreator ();
304
+ if ($ errCreator ) {
305
+ throw $ errCreator ();
306
+ }
307
+
308
+ throw new UnexpectedValueException ('No value present ' );
262
309
}
263
310
264
311
/**
0 commit comments