Sipper
A sipper is a Future that can notify progress.
Effectively, a Sipper combines a Future and a Sink
together to represent an asynchronous task that produces some Output
and notifies of some Progress, without both types being necessarily the
same.
Sipper should be chosen over Stream when the final value produced—the
end of the task—is important and inherently different from the other values.
An example
An example of this could be a file download. When downloading a file, the progress that must be notified is normally a bunch of statistics related to the download; but when the download finishes, the contents of the file need to also be provided.
The Uncomfy Stream
With a Stream, you must create some kind of type that unifies both states of the
download:
use Stream;
;
;
If we now wanted to notify progress and—at the same time—do something with
the final File, we'd need to juggle with the Stream:
use mpsc;
use ;
async
While we could rewrite the previous snippet using loop, expect, and break to get the
final file out of the Stream. We would still be introducing runtime errors and, simply put,
working around the fact that a Stream does not encode the idea of a final value.
The Chad Sipper
A Sipper can precisely describe this dichotomy in a type-safe way:
use Sipper;
;
;
Which can then be easily used with any Sink:
use mpsc;
async