Enumerator
Similar to the Iteratee, an Enumerator is also defined through a trait and backed by an object of the same name:
trait Enumerator[E] {
parent =>
def apply[A](i: Iteratee[E, A]): Future[Iteratee[E, A]]
...
}
object Enumerator{
def apply[E](in: E*): Enumerator[E] = in.length match {
case 0 => Enumerator.empty
case 1 => new Enumerator[E] {
def apply[A](i: Iteratee[E, A]): Future[Iteratee[E, A]] = i.pureFoldNoEC {
case Step.Cont(k) => k(Input.El(in.head))
case _ => i
}
}
case _ => new Enumerator[E] {
def apply[A](i: Iteratee[E, A]): Future[Iteratee[E, A]] = enumerateSeq(in, i)
}
}
...
}Observe that the apply method of the trait and its companion object are different. The apply method of the trait accepts Iteratee[E, A] and returns Future[Iteratee[E, A]], while that of the companion object accepts a sequence of type E and returns an Enumerator[E].
Now, let's define a simple data flow using the companion object...