dencode/sink.rs
1/// An `IterSink` is a value into which other values can be sent.
2///
3/// Values are sent in two phases: first by internally buffering the value,
4/// and then actually writing the value upon flushing.
5pub trait IterSink<Item> {
6 /// The type of value produced by the sink when an error occurs.
7 type Error;
8
9 /// Attempts to prepare the `IterSink` to receive a value, adjusting the internal
10 /// buffer if necessary.
11 ///
12 /// This method must be called prior to each call to `start_send`.
13 fn ready(&mut self) -> Result<(), Self::Error>;
14
15 /// Write a value to the internal buffer.
16 /// Each call to this function must be preceded by a successful call to `ready`.
17 fn start_send(&mut self, item: Item) -> Result<(), Self::Error>;
18
19 /// Flush any remaining output from this sink's internal buffer.
20 fn flush(&mut self) -> Result<(), Self::Error>;
21}
22
23/// An extension trait for `IterSink`s that provides a few convenient functions.
24pub trait IterSinkExt<Item>: IterSink<Item> {
25 /// Fully processed an item into the sink, including flushing.
26 ///
27 /// Note that, because of the flushing requirement, it is usually better to batch
28 /// together items to send via send_all, rather than flushing between each item.
29 fn send(&mut self, item: Item) -> Result<(), Self::Error> {
30 self.send_all(std::iter::once(Ok(item)))
31 }
32
33 /// Fully process the iterator of items into the sink, including flushing.
34 ///
35 /// This will drive the iterator to keep producing items until it is exhausted, sending each item to the sink.
36 /// It will complete once both the input iterator is exhausted, and the sink has
37 /// received and flushed all items.
38 fn send_all<I>(&mut self, items: I) -> Result<(), Self::Error>
39 where
40 I: IntoIterator<Item = Result<Item, Self::Error>>,
41 {
42 for item in items {
43 let item = item?;
44 self.ready()?;
45 self.start_send(item)?;
46 }
47 self.flush()
48 }
49}
50
51impl<T: ?Sized, Item> IterSinkExt<Item> for T where T: IterSink<Item> {}