futures_sink/
lib.rs

1//! Asynchronous sinks
2//!
3//! This crate contains the `Sink` trait which allows values to be sent
4//! asynchronously.
5
6#![no_std]
7#![deny(missing_docs, missing_debug_implementations)]
8#![doc(html_root_url = "https://docs.rs/futures-sink/0.2.2")]
9
10#[cfg(feature = "std")]
11extern crate std;
12
13extern crate futures_core;
14#[cfg(feature = "std")]
15extern crate futures_channel;
16
17macro_rules! if_std {
18    ($($i:item)*) => ($(
19        #[cfg(feature = "std")]
20        $i
21    )*)
22}
23
24use futures_core::{Poll, task};
25
26#[cfg(feature = "either")]
27extern crate either;
28#[cfg(feature = "either")]
29use either::Either;
30#[cfg(feature = "either")]
31impl<A, B> Sink for Either<A, B>
32    where A: Sink,
33          B: Sink<SinkItem=<A as Sink>::SinkItem,
34                  SinkError=<A as Sink>::SinkError>
35{
36    type SinkItem = <A as Sink>::SinkItem;
37    type SinkError = <A as Sink>::SinkError;
38
39    fn poll_ready(&mut self, cx: &mut task::Context) -> Poll<(), Self::SinkError> {
40        match *self {
41            Either::Left(ref mut x) => x.poll_ready(cx),
42            Either::Right(ref mut x) => x.poll_ready(cx),
43        }
44    }
45
46    fn start_send(&mut self, item: Self::SinkItem) -> Result<(), Self::SinkError> {
47        match *self {
48            Either::Left(ref mut x) => x.start_send(item),
49            Either::Right(ref mut x) => x.start_send(item),
50        }
51    }
52
53    fn poll_flush(&mut self, cx: &mut task::Context) -> Poll<(), Self::SinkError> {
54        match *self {
55            Either::Left(ref mut x) => x.poll_flush(cx),
56            Either::Right(ref mut x) => x.poll_flush(cx),
57        }
58    }
59
60    fn poll_close(&mut self, cx: &mut task::Context) -> Poll<(), Self::SinkError> {
61        match *self {
62            Either::Left(ref mut x) => x.poll_close(cx),
63            Either::Right(ref mut x) => x.poll_close(cx),
64        }
65    }
66}
67
68if_std! {
69    mod channel_impls;
70
71    use futures_core::Async;
72    use futures_core::never::Never;
73
74    impl<T> Sink for ::std::vec::Vec<T> {
75        type SinkItem = T;
76        type SinkError = Never;
77
78        fn poll_ready(&mut self, _: &mut task::Context) -> Poll<(), Self::SinkError> {
79            Ok(Async::Ready(()))
80        }
81
82        fn start_send(&mut self, item: Self::SinkItem) -> Result<(), Self::SinkError> {
83            self.push(item);
84            Ok(())
85        }
86
87        fn poll_flush(&mut self, _: &mut task::Context) -> Poll<(), Self::SinkError> {
88            Ok(Async::Ready(()))
89        }
90
91        fn poll_close(&mut self, _: &mut task::Context) -> Poll<(), Self::SinkError> {
92            Ok(Async::Ready(()))
93        }
94    }
95
96    impl<T> Sink for ::std::collections::VecDeque<T> {
97        type SinkItem = T;
98        type SinkError = Never;
99
100        fn poll_ready(&mut self, _: &mut task::Context) -> Poll<(), Self::SinkError> {
101            Ok(Async::Ready(()))
102        }
103
104        fn start_send(&mut self, item: Self::SinkItem) -> Result<(), Self::SinkError> {
105            self.push_back(item);
106            Ok(())
107        }
108
109        fn poll_flush(&mut self, _: &mut task::Context) -> Poll<(), Self::SinkError> {
110            Ok(Async::Ready(()))
111        }
112
113        fn poll_close(&mut self, _: &mut task::Context) -> Poll<(), Self::SinkError> {
114            Ok(Async::Ready(()))
115        }
116    }
117
118    impl<S: ?Sized + Sink> Sink for ::std::boxed::Box<S> {
119        type SinkItem = S::SinkItem;
120        type SinkError = S::SinkError;
121
122        fn poll_ready(&mut self, cx: &mut task::Context) -> Poll<(), Self::SinkError> {
123            (**self).poll_ready(cx)
124        }
125
126        fn start_send(&mut self, item: Self::SinkItem) -> Result<(), Self::SinkError> {
127            (**self).start_send(item)
128        }
129
130        fn poll_flush(&mut self, cx: &mut task::Context) -> Poll<(), Self::SinkError> {
131            (**self).poll_flush(cx)
132        }
133
134        fn poll_close(&mut self, cx: &mut task::Context) -> Poll<(), Self::SinkError> {
135            (**self).poll_close(cx)
136        }
137    }
138}
139
140/// A `Sink` is a value into which other values can be sent, asynchronously.
141///
142/// Basic examples of sinks include the sending side of:
143///
144/// - Channels
145/// - Sockets
146/// - Pipes
147///
148/// In addition to such "primitive" sinks, it's typical to layer additional
149/// functionality, such as buffering, on top of an existing sink.
150///
151/// Sending to a sink is "asynchronous" in the sense that the value may not be
152/// sent in its entirety immediately. Instead, values are sent in a two-phase
153/// way: first by initiating a send, and then by polling for completion. This
154/// two-phase setup is analogous to buffered writing in synchronous code, where
155/// writes often succeed immediately, but internally are buffered and are
156/// *actually* written only upon flushing.
157///
158/// In addition, the `Sink` may be *full*, in which case it is not even possible
159/// to start the sending process.
160///
161/// As with `Future` and `Stream`, the `Sink` trait is built from a few core
162/// required methods, and a host of default methods for working in a
163/// higher-level way. The `Sink::send_all` combinator is of particular
164/// importance: you can use it to send an entire stream to a sink, which is
165/// the simplest way to ultimately consume a stream.
166pub trait Sink {
167    /// The type of value that the sink accepts.
168    type SinkItem;
169
170    /// The type of value produced by the sink when an error occurs.
171    type SinkError;
172
173    /// Attempts to prepare the `Sink` to receive a value.
174    ///
175    /// This method must be called and return `Ok(Async::Ready(()))` prior to
176    /// each call to `start_send`.
177    ///
178    /// This method returns `Async::Ready` once the underlying sink is ready to
179    /// receive data. If this method returns `Async::Pending`, the current task
180    /// is registered to be notified (via `cx.waker()`) when `poll_ready`
181    /// should be called again.
182    ///
183    /// In most cases, if the sink encounters an error, the sink will
184    /// permanently be unable to receive items.
185    fn poll_ready(&mut self, cx: &mut task::Context) -> Poll<(), Self::SinkError>;
186
187    /// Begin the process of sending a value to the sink.
188    /// Each call to this function must be preceded by a successful call to
189    /// `poll_ready` which returned `Ok(Async::Ready(()))`.
190    ///
191    /// As the name suggests, this method only *begins* the process of sending
192    /// the item. If the sink employs buffering, the item isn't fully processed
193    /// until the buffer is fully flushed. Since sinks are designed to work with
194    /// asynchronous I/O, the process of actually writing out the data to an
195    /// underlying object takes place asynchronously. **You *must* use
196    /// `poll_flush` or `poll_close` in order to guarantee completion of a
197    /// send**.
198    ///
199    /// Implementations of `poll_ready` and `start_send` will usually involve
200    /// flushing behind the scenes in order to make room for new messages.
201    /// It is only necessary to call `poll_flush` if you need to guarantee that
202    /// *all* of the items placed into the `Sink` have been sent.
203    ///
204    /// In most cases, if the sink encounters an error, the sink will
205    /// permanently be unable to receive items.
206    fn start_send(&mut self, item: Self::SinkItem)
207                  -> Result<(), Self::SinkError>;
208
209    /// Flush any remaining output from this sink.
210    ///
211    /// Returns `Ok(Async::Ready(()))` when no buffered items remain. If this
212    /// value is returned then it is guaranteed that all previous values sent
213    /// via `start_send` have been flushed.
214    ///
215    /// Returns `Ok(Async::Pending)` if there is more work left to do, in which
216    /// case the current task is scheduled (via `cx.waker()`) to wake up when
217    /// `poll_flush` should be called again.
218    ///
219    /// In most cases, if the sink encounters an error, the sink will
220    /// permanently be unable to receive items.
221    fn poll_flush(&mut self, cx: &mut task::Context) -> Poll<(), Self::SinkError>;
222
223    /// Flush any remaining output and close this sink, if necessary.
224    ///
225    /// Returns `Ok(Async::Ready(()))` when no buffered items remain and the sink
226    /// has been successfully closed.
227    ///
228    /// Returns `Ok(Async::Pending)` if there is more work left to do, in which
229    /// case the current task is scheduled (via `cx.waker()`) to wake up when
230    /// `poll_close` should be called again.
231    ///
232    /// If this function encounters an error, the sink should be considered to
233    /// have failed permanently, and no more `Sink` methods should be called.
234    fn poll_close(&mut self, cx: &mut task::Context) -> Poll<(), Self::SinkError>;
235}
236
237impl<'a, S: ?Sized + Sink> Sink for &'a mut S {
238    type SinkItem = S::SinkItem;
239    type SinkError = S::SinkError;
240
241    fn poll_ready(&mut self, cx: &mut task::Context) -> Poll<(), Self::SinkError> {
242        (**self).poll_ready(cx)
243    }
244
245    fn start_send(&mut self, item: Self::SinkItem) -> Result<(), Self::SinkError> {
246        (**self).start_send(item)
247    }
248
249    fn poll_flush(&mut self, cx: &mut task::Context) -> Poll<(), Self::SinkError> {
250        (**self).poll_flush(cx)
251    }
252
253    fn poll_close(&mut self, cx: &mut task::Context) -> Poll<(), Self::SinkError> {
254        (**self).poll_close(cx)
255    }
256}