@@ -5,7 +5,6 @@ import ox.*
5
5
import java .util .concurrent .{CountDownLatch , Semaphore }
6
6
import scala .collection .{IterableOnce , mutable }
7
7
import scala .concurrent .duration .FiniteDuration
8
- import scala .util .Try
9
8
10
9
trait SourceOps [+ T ] { this : Source [T ] =>
11
10
// view ops (lazy)
@@ -515,11 +514,13 @@ trait SourceOps[+T] { this: Source[T] =>
515
514
}
516
515
c
517
516
518
- /** Returns the first element from this source wrapped in `Some` or `None` when the source is empty or fails during the receive operation.
519
- * Note that `headOption` is not an idempotent operation on source as it receives elements from it.
517
+ /** Returns the first element from this source wrapped in `Some` or `None` when the source is empty. Note that `headOption` is not an
518
+ * idempotent operation on source as it receives elements from it.
520
519
*
521
520
* @return
522
- * A `Some(first element)` if source is not empty or None` otherwise.
521
+ * A `Some(first element)` if source is not empty or `None` otherwise.
522
+ * @throws ChannelClosedException.Error
523
+ * When `receive()` fails.
523
524
* @example
524
525
* {{{
525
526
* import ox.*
@@ -533,7 +534,13 @@ trait SourceOps[+T] { this: Source[T] =>
533
534
* }
534
535
* }}}
535
536
*/
536
- def headOption (): Option [T ] = Try (head()).toOption
537
+ def headOption (): Option [T ] =
538
+ supervised {
539
+ receive() match
540
+ case ChannelClosed .Done => None
541
+ case e : ChannelClosed .Error => throw e.toThrowable
542
+ case t : T @ unchecked => Some (t)
543
+ }
537
544
538
545
/** Returns the first element from this source or throws `NoSuchElementException` when the source is empty. In case when the `receive()`
539
546
* operation fails with exception then `ChannelClosedException.Error`` thrown. Note that `headOption` is not an idempotent operation on
@@ -544,7 +551,7 @@ trait SourceOps[+T] { this: Source[T] =>
544
551
* @throws NoSuchElementException
545
552
* When source is empty or `receive()` failed without error.
546
553
* @throws ChannelClosedException.Error
547
- * When `receive()` fails then this exception is thrown .
554
+ * When `receive()` fails.
548
555
* @example
549
556
* {{{
550
557
* import ox.*
@@ -558,13 +565,7 @@ trait SourceOps[+T] { this: Source[T] =>
558
565
* }
559
566
* }}}
560
567
*/
561
- def head (): T =
562
- supervised {
563
- receive() match
564
- case ChannelClosed .Done => throw new NoSuchElementException (" cannot obtain head from an empty source" )
565
- case e : ChannelClosed .Error => throw e.toThrowable
566
- case t : T @ unchecked => t
567
- }
568
+ def head (): T = headOption().getOrElse(throw new NoSuchElementException (" cannot obtain head from an empty source" ))
568
569
569
570
/** Returns the last element from this source wrapped in `Some` or `None` when the source is empty. Note that `lastOption` is a terminal
570
571
* operation leaving the source in `ChannelClosed.Done` state.
0 commit comments