futures-util-0.3.30/.cargo_vcs_info.json0000644000000001520000000000100135650ustar { "git": { "sha1": "de1a0fd64a1bcae9a1534ed4da1699632993cc26" }, "path_in_vcs": "futures-util" }futures-util-0.3.30/Cargo.toml0000644000000047710000000000100115760ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" rust-version = "1.56" name = "futures-util" version = "0.3.30" description = """ Common utilities and extension traits for the futures-rs library. """ homepage = "https://rust-lang.github.io/futures-rs" readme = "README.md" license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/futures-rs" [package.metadata.docs.rs] all-features = true rustdoc-args = [ "--cfg", "docsrs", ] [dependencies.futures-channel] version = "0.3.30" features = ["std"] optional = true default-features = false [dependencies.futures-core] version = "0.3.30" default-features = false [dependencies.futures-io] version = "0.3.30" features = ["std"] optional = true default-features = false [dependencies.futures-macro] version = "=0.3.30" optional = true default-features = false [dependencies.futures-sink] version = "0.3.30" optional = true default-features = false [dependencies.futures-task] version = "0.3.30" default-features = false [dependencies.futures_01] version = "0.1.25" optional = true package = "futures" [dependencies.memchr] version = "2.2" optional = true [dependencies.pin-project-lite] version = "0.2.6" [dependencies.pin-utils] version = "0.1.0" [dependencies.slab] version = "0.4.2" optional = true [dependencies.tokio-io] version = "0.1.9" optional = true [dev-dependencies.tokio] version = "0.1.11" [features] alloc = [ "futures-core/alloc", "futures-task/alloc", ] async-await = [] async-await-macro = [ "async-await", "futures-macro", ] bilock = [] cfg-target-has-atomic = [] channel = [ "std", "futures-channel", ] compat = [ "std", "futures_01", ] default = [ "std", "async-await", "async-await-macro", ] io = [ "std", "futures-io", "memchr", ] io-compat = [ "io", "compat", "tokio-io", ] portable-atomic = ["futures-core/portable-atomic"] sink = ["futures-sink"] std = [ "alloc", "futures-core/std", "futures-task/std", "slab", ] unstable = [ "futures-core/unstable", "futures-task/unstable", ] write-all-vectored = ["io"] futures-util-0.3.30/Cargo.toml.orig000064400000000000000000000044311046102023000152500ustar 00000000000000[package] name = "futures-util" version = "0.3.30" edition = "2018" rust-version = "1.56" license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/futures-rs" homepage = "https://rust-lang.github.io/futures-rs" description = """ Common utilities and extension traits for the futures-rs library. """ [features] default = ["std", "async-await", "async-await-macro"] std = ["alloc", "futures-core/std", "futures-task/std", "slab"] alloc = ["futures-core/alloc", "futures-task/alloc"] async-await = [] async-await-macro = ["async-await", "futures-macro"] compat = ["std", "futures_01"] io-compat = ["io", "compat", "tokio-io"] sink = ["futures-sink"] io = ["std", "futures-io", "memchr"] channel = ["std", "futures-channel"] portable-atomic = ["futures-core/portable-atomic"] # Unstable features # These features are outside of the normal semver guarantees and require the # `unstable` feature as an explicit opt-in to unstable API. unstable = ["futures-core/unstable", "futures-task/unstable"] bilock = [] write-all-vectored = ["io"] # These features are no longer used. # TODO: remove in the next major version. cfg-target-has-atomic = [] [dependencies] futures-core = { path = "../futures-core", version = "0.3.30", default-features = false } futures-task = { path = "../futures-task", version = "0.3.30", default-features = false } futures-channel = { path = "../futures-channel", version = "0.3.30", default-features = false, features = ["std"], optional = true } futures-io = { path = "../futures-io", version = "0.3.30", default-features = false, features = ["std"], optional = true } futures-sink = { path = "../futures-sink", version = "0.3.30", default-features = false, optional = true } futures-macro = { path = "../futures-macro", version = "=0.3.30", default-features = false, optional = true } slab = { version = "0.4.2", optional = true } memchr = { version = "2.2", optional = true } futures_01 = { version = "0.1.25", optional = true, package = "futures" } tokio-io = { version = "0.1.9", optional = true } pin-utils = "0.1.0" pin-project-lite = "0.2.6" [dev-dependencies] futures = { path = "../futures", features = ["async-await", "thread-pool"] } futures-test = { path = "../futures-test" } tokio = "0.1.11" [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] futures-util-0.3.30/LICENSE-APACHE000064400000000000000000000251721046102023000143120ustar 00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright (c) 2016 Alex Crichton Copyright (c) 2017 The Tokio Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. futures-util-0.3.30/LICENSE-MIT000064400000000000000000000021061046102023000140120ustar 00000000000000Copyright (c) 2016 Alex Crichton Copyright (c) 2017 The Tokio Authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. futures-util-0.3.30/README.md000064400000000000000000000011161046102023000136350ustar 00000000000000# futures-util Common utilities and extension traits for the futures-rs library. ## Usage Add this to your `Cargo.toml`: ```toml [dependencies] futures-util = "0.3" ``` The current `futures-util` requires Rust 1.56 or later. ## License Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or [MIT license](LICENSE-MIT) at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. futures-util-0.3.30/benches/bilock.rs000064400000000000000000000027421046102023000156040ustar 00000000000000#![feature(test)] #![cfg(feature = "bilock")] extern crate test; use futures::task::Poll; use futures_test::task::noop_context; use futures_util::lock::BiLock; use crate::test::Bencher; #[bench] fn contended(b: &mut Bencher) { let mut context = noop_context(); b.iter(|| { let (x, y) = BiLock::new(1); for _ in 0..1000 { let x_guard = match x.poll_lock(&mut context) { Poll::Ready(guard) => guard, _ => panic!(), }; // Try poll second lock while first lock still holds the lock match y.poll_lock(&mut context) { Poll::Pending => (), _ => panic!(), }; drop(x_guard); let y_guard = match y.poll_lock(&mut context) { Poll::Ready(guard) => guard, _ => panic!(), }; drop(y_guard); } (x, y) }); } #[bench] fn lock_unlock(b: &mut Bencher) { let mut context = noop_context(); b.iter(|| { let (x, y) = BiLock::new(1); for _ in 0..1000 { let x_guard = match x.poll_lock(&mut context) { Poll::Ready(guard) => guard, _ => panic!(), }; drop(x_guard); let y_guard = match y.poll_lock(&mut context) { Poll::Ready(guard) => guard, _ => panic!(), }; drop(y_guard); } (x, y) }) } futures-util-0.3.30/benches/flatten_unordered.rs000064400000000000000000000030561046102023000200440ustar 00000000000000#![feature(test)] extern crate test; use crate::test::Bencher; use futures::channel::oneshot; use futures::executor::block_on; use futures::future; use futures::stream::{self, StreamExt}; use futures::task::Poll; use futures_util::FutureExt; use std::collections::VecDeque; use std::thread; #[bench] fn oneshot_streams(b: &mut Bencher) { const STREAM_COUNT: usize = 10_000; const STREAM_ITEM_COUNT: usize = 1; b.iter(|| { let mut txs = VecDeque::with_capacity(STREAM_COUNT); let mut rxs = Vec::new(); for _ in 0..STREAM_COUNT { let (tx, rx) = oneshot::channel(); txs.push_back(tx); rxs.push(rx); } thread::spawn(move || { let mut last = 1; while let Some(tx) = txs.pop_front() { let _ = tx.send(stream::iter(last..last + STREAM_ITEM_COUNT)); last += STREAM_ITEM_COUNT; } }); let mut flatten = stream::iter(rxs) .map(|recv| recv.into_stream().map(|val| val.unwrap()).flatten()) .flatten_unordered(None); block_on(future::poll_fn(move |cx| { let mut count = 0; loop { match flatten.poll_next_unpin(cx) { Poll::Ready(None) => break, Poll::Ready(Some(_)) => { count += 1; } _ => {} } } assert_eq!(count, STREAM_COUNT * STREAM_ITEM_COUNT); Poll::Ready(()) })) }); } futures-util-0.3.30/benches/futures_unordered.rs000064400000000000000000000017501046102023000201030ustar 00000000000000#![feature(test)] extern crate test; use crate::test::Bencher; use futures::channel::oneshot; use futures::executor::block_on; use futures::future; use futures::stream::{FuturesUnordered, StreamExt}; use futures::task::Poll; use std::collections::VecDeque; use std::thread; #[bench] fn oneshots(b: &mut Bencher) { const NUM: usize = 10_000; b.iter(|| { let mut txs = VecDeque::with_capacity(NUM); let mut rxs = FuturesUnordered::new(); for _ in 0..NUM { let (tx, rx) = oneshot::channel(); txs.push_back(tx); rxs.push(rx); } thread::spawn(move || { while let Some(tx) = txs.pop_front() { let _ = tx.send("hello"); } }); block_on(future::poll_fn(move |cx| { loop { if let Poll::Ready(None) = rxs.poll_next_unpin(cx) { break; } } Poll::Ready(()) })) }); } futures-util-0.3.30/benches/select.rs000064400000000000000000000017731046102023000156230ustar 00000000000000#![feature(test)] extern crate test; use crate::test::Bencher; use futures::executor::block_on; use futures::stream::{repeat, select, StreamExt}; #[bench] fn select_streams(b: &mut Bencher) { const STREAM_COUNT: usize = 10_000; b.iter(|| { let stream1 = repeat(1).take(STREAM_COUNT); let stream2 = repeat(2).take(STREAM_COUNT); let stream3 = repeat(3).take(STREAM_COUNT); let stream4 = repeat(4).take(STREAM_COUNT); let stream5 = repeat(5).take(STREAM_COUNT); let stream6 = repeat(6).take(STREAM_COUNT); let stream7 = repeat(7).take(STREAM_COUNT); let count = block_on(async { let count = select( stream1, select( stream2, select(stream3, select(stream4, select(stream5, select(stream6, stream7)))), ), ) .count() .await; count }); assert_eq!(count, STREAM_COUNT * 7); }); } futures-util-0.3.30/src/abortable.rs000064400000000000000000000154541046102023000154600ustar 00000000000000use crate::task::AtomicWaker; use alloc::sync::Arc; use core::fmt; use core::pin::Pin; use core::sync::atomic::{AtomicBool, Ordering}; use futures_core::future::Future; use futures_core::task::{Context, Poll}; use futures_core::Stream; use pin_project_lite::pin_project; pin_project! { /// A future/stream which can be remotely short-circuited using an `AbortHandle`. #[derive(Debug, Clone)] #[must_use = "futures/streams do nothing unless you poll them"] pub struct Abortable { #[pin] task: T, inner: Arc, } } impl Abortable { /// Creates a new `Abortable` future/stream using an existing `AbortRegistration`. /// `AbortRegistration`s can be acquired through `AbortHandle::new`. /// /// When `abort` is called on the handle tied to `reg` or if `abort` has /// already been called, the future/stream will complete immediately without making /// any further progress. /// /// # Examples: /// /// Usage with futures: /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::{Abortable, AbortHandle, Aborted}; /// /// let (abort_handle, abort_registration) = AbortHandle::new_pair(); /// let future = Abortable::new(async { 2 }, abort_registration); /// abort_handle.abort(); /// assert_eq!(future.await, Err(Aborted)); /// # }); /// ``` /// /// Usage with streams: /// /// ``` /// # futures::executor::block_on(async { /// # use futures::future::{Abortable, AbortHandle}; /// # use futures::stream::{self, StreamExt}; /// /// let (abort_handle, abort_registration) = AbortHandle::new_pair(); /// let mut stream = Abortable::new(stream::iter(vec![1, 2, 3]), abort_registration); /// abort_handle.abort(); /// assert_eq!(stream.next().await, None); /// # }); /// ``` pub fn new(task: T, reg: AbortRegistration) -> Self { Self { task, inner: reg.inner } } /// Checks whether the task has been aborted. Note that all this /// method indicates is whether [`AbortHandle::abort`] was *called*. /// This means that it will return `true` even if: /// * `abort` was called after the task had completed. /// * `abort` was called while the task was being polled - the task may still be running and /// will not be stopped until `poll` returns. pub fn is_aborted(&self) -> bool { self.inner.aborted.load(Ordering::Relaxed) } } /// A registration handle for an `Abortable` task. /// Values of this type can be acquired from `AbortHandle::new` and are used /// in calls to `Abortable::new`. #[derive(Debug)] pub struct AbortRegistration { pub(crate) inner: Arc, } impl AbortRegistration { /// Create an [`AbortHandle`] from the given [`AbortRegistration`]. /// /// The created [`AbortHandle`] is functionally the same as any other /// [`AbortHandle`]s that are associated with the same [`AbortRegistration`], /// such as the one created by [`AbortHandle::new_pair`]. pub fn handle(&self) -> AbortHandle { AbortHandle { inner: self.inner.clone() } } } /// A handle to an `Abortable` task. #[derive(Debug, Clone)] pub struct AbortHandle { inner: Arc, } impl AbortHandle { /// Creates an (`AbortHandle`, `AbortRegistration`) pair which can be used /// to abort a running future or stream. /// /// This function is usually paired with a call to [`Abortable::new`]. pub fn new_pair() -> (Self, AbortRegistration) { let inner = Arc::new(AbortInner { waker: AtomicWaker::new(), aborted: AtomicBool::new(false) }); (Self { inner: inner.clone() }, AbortRegistration { inner }) } } // Inner type storing the waker to awaken and a bool indicating that it // should be aborted. #[derive(Debug)] pub(crate) struct AbortInner { pub(crate) waker: AtomicWaker, pub(crate) aborted: AtomicBool, } /// Indicator that the `Abortable` task was aborted. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct Aborted; impl fmt::Display for Aborted { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "`Abortable` future has been aborted") } } #[cfg(feature = "std")] impl std::error::Error for Aborted {} impl Abortable { fn try_poll( mut self: Pin<&mut Self>, cx: &mut Context<'_>, poll: impl Fn(Pin<&mut T>, &mut Context<'_>) -> Poll, ) -> Poll> { // Check if the task has been aborted if self.is_aborted() { return Poll::Ready(Err(Aborted)); } // attempt to complete the task if let Poll::Ready(x) = poll(self.as_mut().project().task, cx) { return Poll::Ready(Ok(x)); } // Register to receive a wakeup if the task is aborted in the future self.inner.waker.register(cx.waker()); // Check to see if the task was aborted between the first check and // registration. // Checking with `is_aborted` which uses `Relaxed` is sufficient because // `register` introduces an `AcqRel` barrier. if self.is_aborted() { return Poll::Ready(Err(Aborted)); } Poll::Pending } } impl Future for Abortable where Fut: Future, { type Output = Result; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { self.try_poll(cx, |fut, cx| fut.poll(cx)) } } impl Stream for Abortable where St: Stream, { type Item = St::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.try_poll(cx, |stream, cx| stream.poll_next(cx)).map(Result::ok).map(Option::flatten) } } impl AbortHandle { /// Abort the `Abortable` stream/future associated with this handle. /// /// Notifies the Abortable task associated with this handle that it /// should abort. Note that if the task is currently being polled on /// another thread, it will not immediately stop running. Instead, it will /// continue to run until its poll method returns. pub fn abort(&self) { self.inner.aborted.store(true, Ordering::Relaxed); self.inner.waker.wake(); } /// Checks whether [`AbortHandle::abort`] was *called* on any associated /// [`AbortHandle`]s, which includes all the [`AbortHandle`]s linked with /// the same [`AbortRegistration`]. This means that it will return `true` /// even if: /// * `abort` was called after the task had completed. /// * `abort` was called while the task was being polled - the task may still be running and /// will not be stopped until `poll` returns. /// /// This operation has a Relaxed ordering. pub fn is_aborted(&self) -> bool { self.inner.aborted.load(Ordering::Relaxed) } } futures-util-0.3.30/src/async_await/join_mod.rs000064400000000000000000000067371046102023000176310ustar 00000000000000//! The `join` macro. macro_rules! document_join_macro { ($join:item $try_join:item) => { /// Polls multiple futures simultaneously, returning a tuple /// of all results once complete. /// /// While `join!(a, b)` is similar to `(a.await, b.await)`, /// `join!` polls both futures concurrently and therefore is more efficient. /// /// This macro is only usable inside of async functions, closures, and blocks. /// It is also gated behind the `async-await` feature of this library, which is /// activated by default. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::join; /// /// let a = async { 1 }; /// let b = async { 2 }; /// assert_eq!(join!(a, b), (1, 2)); /// /// // `join!` is variadic, so you can pass any number of futures /// let c = async { 3 }; /// let d = async { 4 }; /// let e = async { 5 }; /// assert_eq!(join!(c, d, e), (3, 4, 5)); /// # }); /// ``` $join /// Polls multiple futures simultaneously, resolving to a [`Result`] containing /// either a tuple of the successful outputs or an error. /// /// `try_join!` is similar to [`join!`], but completes immediately if any of /// the futures return an error. /// /// This macro is only usable inside of async functions, closures, and blocks. /// It is also gated behind the `async-await` feature of this library, which is /// activated by default. /// /// # Examples /// /// When used on multiple futures that return `Ok`, `try_join!` will return /// `Ok` of a tuple of the values: /// /// ``` /// # futures::executor::block_on(async { /// use futures::try_join; /// /// let a = async { Ok::(1) }; /// let b = async { Ok::(2) }; /// assert_eq!(try_join!(a, b), Ok((1, 2))); /// /// // `try_join!` is variadic, so you can pass any number of futures /// let c = async { Ok::(3) }; /// let d = async { Ok::(4) }; /// let e = async { Ok::(5) }; /// assert_eq!(try_join!(c, d, e), Ok((3, 4, 5))); /// # }); /// ``` /// /// If one of the futures resolves to an error, `try_join!` will return /// that error: /// /// ``` /// # futures::executor::block_on(async { /// use futures::try_join; /// /// let a = async { Ok::(1) }; /// let b = async { Err::(2) }; /// /// assert_eq!(try_join!(a, b), Err(2)); /// # }); /// ``` $try_join } } #[allow(unreachable_pub)] #[doc(hidden)] pub use futures_macro::join_internal; #[allow(unreachable_pub)] #[doc(hidden)] pub use futures_macro::try_join_internal; document_join_macro! { #[macro_export] macro_rules! join { ($($tokens:tt)*) => {{ use $crate::__private as __futures_crate; $crate::join_internal! { $( $tokens )* } }} } #[macro_export] macro_rules! try_join { ($($tokens:tt)*) => {{ use $crate::__private as __futures_crate; $crate::try_join_internal! { $( $tokens )* } }} } } futures-util-0.3.30/src/async_await/mod.rs000064400000000000000000000032621046102023000166000ustar 00000000000000//! Await //! //! This module contains a number of functions and combinators for working //! with `async`/`await` code. use futures_core::future::{FusedFuture, Future}; use futures_core::stream::{FusedStream, Stream}; #[macro_use] mod poll; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762 pub use self::poll::*; #[macro_use] mod pending; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762 pub use self::pending::*; // Primary export is a macro #[cfg(feature = "async-await-macro")] mod join_mod; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762 #[cfg(feature = "async-await-macro")] pub use self::join_mod::*; // Primary export is a macro #[cfg(feature = "async-await-macro")] mod select_mod; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762 #[cfg(feature = "async-await-macro")] pub use self::select_mod::*; // Primary export is a macro #[cfg(feature = "std")] #[cfg(feature = "async-await-macro")] mod stream_select_mod; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762 #[cfg(feature = "std")] #[cfg(feature = "async-await-macro")] pub use self::stream_select_mod::*; #[cfg(feature = "std")] #[cfg(feature = "async-await-macro")] mod random; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762 #[cfg(feature = "std")] #[cfg(feature = "async-await-macro")] pub use self::random::*; #[doc(hidden)] #[inline(always)] pub fn assert_unpin(_: &T) {} #[doc(hidden)] #[inline(always)] pub fn assert_fused_future(_: &T) {} #[doc(hidden)] #[inline(always)] pub fn assert_fused_stream(_: &T) {} futures-util-0.3.30/src/async_await/pending.rs000064400000000000000000000023471046102023000174500ustar 00000000000000use core::pin::Pin; use futures_core::future::Future; use futures_core::task::{Context, Poll}; /// A macro which yields to the event loop once. /// /// This is equivalent to returning [`Poll::Pending`](futures_core::task::Poll) /// from a [`Future::poll`](futures_core::future::Future::poll) implementation. /// Similarly, when using this macro, it must be ensured that [`wake`](std::task::Waker::wake) /// is called somewhere when further progress can be made. /// /// This macro is only usable inside of async functions, closures, and blocks. /// It is also gated behind the `async-await` feature of this library, which is /// activated by default. #[macro_export] macro_rules! pending { () => { $crate::__private::async_await::pending_once().await }; } #[doc(hidden)] pub fn pending_once() -> PendingOnce { PendingOnce { is_ready: false } } #[allow(missing_debug_implementations)] #[doc(hidden)] pub struct PendingOnce { is_ready: bool, } impl Future for PendingOnce { type Output = (); fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll { if self.is_ready { Poll::Ready(()) } else { self.is_ready = true; Poll::Pending } } } futures-util-0.3.30/src/async_await/poll.rs000064400000000000000000000022301046102023000167610ustar 00000000000000use crate::future::FutureExt; use core::pin::Pin; use futures_core::future::Future; use futures_core::task::{Context, Poll}; /// A macro which returns the result of polling a future once within the /// current `async` context. /// /// This macro is only usable inside of `async` functions, closures, and blocks. /// It is also gated behind the `async-await` feature of this library, which is /// activated by default. /// /// If you need the result of polling a [`Stream`](crate::stream::Stream), /// you can use this macro with the [`next`](crate::stream::StreamExt::next) method: /// `poll!(stream.next())`. #[macro_export] macro_rules! poll { ($x:expr $(,)?) => { $crate::__private::async_await::poll($x).await }; } #[doc(hidden)] pub fn poll(future: F) -> PollOnce { PollOnce { future } } #[allow(missing_debug_implementations)] #[doc(hidden)] pub struct PollOnce { future: F, } impl Future for PollOnce { type Output = Poll; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Poll::Ready(self.future.poll_unpin(cx)) } } futures-util-0.3.30/src/async_await/random.rs000064400000000000000000000025261046102023000173030ustar 00000000000000use std::{ cell::Cell, collections::hash_map::DefaultHasher, hash::Hasher, num::Wrapping, sync::atomic::{AtomicUsize, Ordering}, }; // Based on [Fisher–Yates shuffle]. // // [Fisher–Yates shuffle]: https://en.wikipedia.org/wiki/Fisher–Yates_shuffle #[doc(hidden)] pub fn shuffle(slice: &mut [T]) { for i in (1..slice.len()).rev() { slice.swap(i, gen_index(i + 1)); } } /// Return a value from `0..n`. fn gen_index(n: usize) -> usize { (random() % n as u64) as usize } /// Pseudorandom number generator based on [xorshift*]. /// /// [xorshift*]: https://en.wikipedia.org/wiki/Xorshift#xorshift* fn random() -> u64 { thread_local! { static RNG: Cell> = Cell::new(Wrapping(prng_seed())); } fn prng_seed() -> u64 { static COUNTER: AtomicUsize = AtomicUsize::new(0); // Any non-zero seed will do let mut seed = 0; while seed == 0 { let mut hasher = DefaultHasher::new(); hasher.write_usize(COUNTER.fetch_add(1, Ordering::Relaxed)); seed = hasher.finish(); } seed } RNG.with(|rng| { let mut x = rng.get(); debug_assert_ne!(x.0, 0); x ^= x >> 12; x ^= x << 25; x ^= x >> 27; rng.set(x); x.0.wrapping_mul(0x2545_f491_4f6c_dd1d) }) } futures-util-0.3.30/src/async_await/select_mod.rs000064400000000000000000000321441046102023000201400ustar 00000000000000//! The `select` macro. macro_rules! document_select_macro { // This branch is required for `futures 0.3.1`, from before select_biased was introduced ($select:item) => { /// Polls multiple futures and streams simultaneously, executing the branch /// for the future that finishes first. If multiple futures are ready, /// one will be pseudo-randomly selected at runtime. Futures directly /// passed to `select!` must be `Unpin` and implement `FusedFuture`. /// /// If an expression which yields a `Future` is passed to `select!` /// (e.g. an `async fn` call) instead of a `Future` by name the `Unpin` /// requirement is relaxed, since the macro will pin the resulting `Future` /// on the stack. However the `Future` returned by the expression must /// still implement `FusedFuture`. /// /// Futures and streams which are not already fused can be fused using the /// `.fuse()` method. Note, though, that fusing a future or stream directly /// in the call to `select!` will not be enough to prevent it from being /// polled after completion if the `select!` call is in a loop, so when /// `select!`ing in a loop, users should take care to `fuse()` outside of /// the loop. /// /// `select!` can be used as an expression and will return the return /// value of the selected branch. For this reason the return type of every /// branch in a `select!` must be the same. /// /// This macro is only usable inside of async functions, closures, and blocks. /// It is also gated behind the `async-await` feature of this library, which is /// activated by default. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// use futures::select; /// let mut a = future::ready(4); /// let mut b = future::pending::<()>(); /// /// let res = select! { /// a_res = a => a_res + 1, /// _ = b => 0, /// }; /// assert_eq!(res, 5); /// # }); /// ``` /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// use futures::stream::{self, StreamExt}; /// use futures::select; /// let mut st = stream::iter(vec![2]).fuse(); /// let mut fut = future::pending::<()>(); /// /// select! { /// x = st.next() => assert_eq!(Some(2), x), /// _ = fut => panic!(), /// }; /// # }); /// ``` /// /// As described earlier, `select` can directly select on expressions /// which return `Future`s - even if those do not implement `Unpin`: /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::FutureExt; /// use futures::select; /// /// // Calling the following async fn returns a Future which does not /// // implement Unpin /// async fn async_identity_fn(arg: usize) -> usize { /// arg /// } /// /// let res = select! { /// a_res = async_identity_fn(62).fuse() => a_res + 1, /// b_res = async_identity_fn(13).fuse() => b_res, /// }; /// assert!(res == 63 || res == 13); /// # }); /// ``` /// /// If a similar async function is called outside of `select` to produce /// a `Future`, the `Future` must be pinned in order to be able to pass /// it to `select`. This can be achieved via `Box::pin` for pinning a /// `Future` on the heap or the `pin_mut!` macro for pinning a `Future` /// on the stack. /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::FutureExt; /// use futures::select; /// use futures::pin_mut; /// /// // Calling the following async fn returns a Future which does not /// // implement Unpin /// async fn async_identity_fn(arg: usize) -> usize { /// arg /// } /// /// let fut_1 = async_identity_fn(1).fuse(); /// let fut_2 = async_identity_fn(2).fuse(); /// let mut fut_1 = Box::pin(fut_1); // Pins the Future on the heap /// pin_mut!(fut_2); // Pins the Future on the stack /// /// let res = select! { /// a_res = fut_1 => a_res, /// b_res = fut_2 => b_res, /// }; /// assert!(res == 1 || res == 2); /// # }); /// ``` /// /// `select` also accepts a `complete` branch and a `default` branch. /// `complete` will run if all futures and streams have already been /// exhausted. `default` will run if no futures or streams are /// immediately ready. `complete` takes priority over `default` in /// the case where all futures have completed. /// A motivating use-case for passing `Future`s by name as well as for /// `complete` blocks is to call `select!` in a loop, which is /// demonstrated in the following example: /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// use futures::select; /// let mut a_fut = future::ready(4); /// let mut b_fut = future::ready(6); /// let mut total = 0; /// /// loop { /// select! { /// a = a_fut => total += a, /// b = b_fut => total += b, /// complete => break, /// default => panic!(), // never runs (futures run first, then complete) /// }; /// } /// assert_eq!(total, 10); /// # }); /// ``` /// /// Note that the futures that have been matched over can still be mutated /// from inside the `select!` block's branches. This can be used to implement /// more complex behavior such as timer resets or writing into the head of /// a stream. $select }; ($select:item $select_biased:item) => { document_select_macro!($select); /// Polls multiple futures and streams simultaneously, executing the branch /// for the future that finishes first. Unlike [`select!`], if multiple futures are ready, /// one will be selected in order of declaration. Futures directly /// passed to `select_biased!` must be `Unpin` and implement `FusedFuture`. /// /// If an expression which yields a `Future` is passed to `select_biased!` /// (e.g. an `async fn` call) instead of a `Future` by name the `Unpin` /// requirement is relaxed, since the macro will pin the resulting `Future` /// on the stack. However the `Future` returned by the expression must /// still implement `FusedFuture`. /// /// Futures and streams which are not already fused can be fused using the /// `.fuse()` method. Note, though, that fusing a future or stream directly /// in the call to `select_biased!` will not be enough to prevent it from being /// polled after completion if the `select_biased!` call is in a loop, so when /// `select_biased!`ing in a loop, users should take care to `fuse()` outside of /// the loop. /// /// `select_biased!` can be used as an expression and will return the return /// value of the selected branch. For this reason the return type of every /// branch in a `select_biased!` must be the same. /// /// This macro is only usable inside of async functions, closures, and blocks. /// It is also gated behind the `async-await` feature of this library, which is /// activated by default. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// use futures::select_biased; /// let mut a = future::ready(4); /// let mut b = future::pending::<()>(); /// /// let res = select_biased! { /// a_res = a => a_res + 1, /// _ = b => 0, /// }; /// assert_eq!(res, 5); /// # }); /// ``` /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// use futures::stream::{self, StreamExt}; /// use futures::select_biased; /// let mut st = stream::iter(vec![2]).fuse(); /// let mut fut = future::pending::<()>(); /// /// select_biased! { /// x = st.next() => assert_eq!(Some(2), x), /// _ = fut => panic!(), /// }; /// # }); /// ``` /// /// As described earlier, `select_biased` can directly select on expressions /// which return `Future`s - even if those do not implement `Unpin`: /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::FutureExt; /// use futures::select_biased; /// /// // Calling the following async fn returns a Future which does not /// // implement Unpin /// async fn async_identity_fn(arg: usize) -> usize { /// arg /// } /// /// let res = select_biased! { /// a_res = async_identity_fn(62).fuse() => a_res + 1, /// b_res = async_identity_fn(13).fuse() => b_res, /// }; /// assert!(res == 63 || res == 12); /// # }); /// ``` /// /// If a similar async function is called outside of `select_biased` to produce /// a `Future`, the `Future` must be pinned in order to be able to pass /// it to `select_biased`. This can be achieved via `Box::pin` for pinning a /// `Future` on the heap or the `pin_mut!` macro for pinning a `Future` /// on the stack. /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::FutureExt; /// use futures::select_biased; /// use futures::pin_mut; /// /// // Calling the following async fn returns a Future which does not /// // implement Unpin /// async fn async_identity_fn(arg: usize) -> usize { /// arg /// } /// /// let fut_1 = async_identity_fn(1).fuse(); /// let fut_2 = async_identity_fn(2).fuse(); /// let mut fut_1 = Box::pin(fut_1); // Pins the Future on the heap /// pin_mut!(fut_2); // Pins the Future on the stack /// /// let res = select_biased! { /// a_res = fut_1 => a_res, /// b_res = fut_2 => b_res, /// }; /// assert!(res == 1 || res == 2); /// # }); /// ``` /// /// `select_biased` also accepts a `complete` branch and a `default` branch. /// `complete` will run if all futures and streams have already been /// exhausted. `default` will run if no futures or streams are /// immediately ready. `complete` takes priority over `default` in /// the case where all futures have completed. /// A motivating use-case for passing `Future`s by name as well as for /// `complete` blocks is to call `select_biased!` in a loop, which is /// demonstrated in the following example: /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// use futures::select_biased; /// let mut a_fut = future::ready(4); /// let mut b_fut = future::ready(6); /// let mut total = 0; /// /// loop { /// select_biased! { /// a = a_fut => total += a, /// b = b_fut => total += b, /// complete => break, /// default => panic!(), // never runs (futures run first, then complete) /// }; /// } /// assert_eq!(total, 10); /// # }); /// ``` /// /// Note that the futures that have been matched over can still be mutated /// from inside the `select_biased!` block's branches. This can be used to implement /// more complex behavior such as timer resets or writing into the head of /// a stream. /// /// [`select!`]: macro.select.html $select_biased }; } #[cfg(feature = "std")] #[allow(unreachable_pub)] #[doc(hidden)] pub use futures_macro::select_internal; #[allow(unreachable_pub)] #[doc(hidden)] pub use futures_macro::select_biased_internal; document_select_macro! { #[cfg(feature = "std")] #[macro_export] macro_rules! select { ($($tokens:tt)*) => {{ use $crate::__private as __futures_crate; $crate::select_internal! { $( $tokens )* } }} } #[macro_export] macro_rules! select_biased { ($($tokens:tt)*) => {{ use $crate::__private as __futures_crate; $crate::select_biased_internal! { $( $tokens )* } }} } } futures-util-0.3.30/src/async_await/stream_select_mod.rs000064400000000000000000000023551046102023000215140ustar 00000000000000//! The `stream_select` macro. #[allow(unreachable_pub)] #[doc(hidden)] pub use futures_macro::stream_select_internal; /// Combines several streams, all producing the same `Item` type, into one stream. /// This is similar to `select_all` but does not require the streams to all be the same type. /// It also keeps the streams inline, and does not require `Box`s to be allocated. /// Streams passed to this macro must be `Unpin`. /// /// If multiple streams are ready, one will be pseudo randomly selected at runtime. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::{stream, StreamExt, stream_select}; /// let endless_ints = |i| stream::iter(vec![i].into_iter().cycle()).fuse(); /// /// let mut endless_numbers = stream_select!(endless_ints(1i32), endless_ints(2), endless_ints(3)); /// match endless_numbers.next().await { /// Some(1) => println!("Got a 1"), /// Some(2) => println!("Got a 2"), /// Some(3) => println!("Got a 3"), /// _ => unreachable!(), /// } /// # }); /// ``` #[macro_export] macro_rules! stream_select { ($($tokens:tt)*) => {{ use $crate::__private as __futures_crate; $crate::stream_select_internal! { $( $tokens )* } }} } futures-util-0.3.30/src/compat/compat01as03.rs000064400000000000000000000355271046102023000171260ustar 00000000000000use futures_01::executor::{ spawn as spawn01, Notify as Notify01, NotifyHandle as NotifyHandle01, Spawn as Spawn01, UnsafeNotify as UnsafeNotify01, }; use futures_01::{Async as Async01, Future as Future01, Stream as Stream01}; #[cfg(feature = "sink")] use futures_01::{AsyncSink as AsyncSink01, Sink as Sink01}; use futures_core::{future::Future as Future03, stream::Stream as Stream03, task as task03}; #[cfg(feature = "sink")] use futures_sink::Sink as Sink03; use std::pin::Pin; use std::task::Context; #[cfg(feature = "io-compat")] #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use io::{AsyncRead01CompatExt, AsyncWrite01CompatExt}; /// Converts a futures 0.1 Future, Stream, AsyncRead, or AsyncWrite /// object to a futures 0.3-compatible version, #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Compat01As03 { pub(crate) inner: Spawn01, } impl Unpin for Compat01As03 {} impl Compat01As03 { /// Wraps a futures 0.1 Future, Stream, AsyncRead, or AsyncWrite /// object in a futures 0.3-compatible wrapper. pub fn new(object: T) -> Self { Self { inner: spawn01(object) } } fn in_notify(&mut self, cx: &mut Context<'_>, f: impl FnOnce(&mut T) -> R) -> R { let notify = &WakerToHandle(cx.waker()); self.inner.poll_fn_notify(notify, 0, f) } /// Get a reference to 0.1 Future, Stream, AsyncRead, or AsyncWrite object contained within. pub fn get_ref(&self) -> &T { self.inner.get_ref() } /// Get a mutable reference to 0.1 Future, Stream, AsyncRead or AsyncWrite object contained /// within. pub fn get_mut(&mut self) -> &mut T { self.inner.get_mut() } /// Consume this wrapper to return the underlying 0.1 Future, Stream, AsyncRead, or /// AsyncWrite object. pub fn into_inner(self) -> T { self.inner.into_inner() } } /// Extension trait for futures 0.1 [`Future`](futures_01::future::Future) pub trait Future01CompatExt: Future01 { /// Converts a futures 0.1 /// [`Future`](futures_01::future::Future) /// into a futures 0.3 /// [`Future>`](futures_core::future::Future). /// /// ``` /// # if cfg!(miri) { return; } // https://github.com/rust-lang/futures-rs/issues/2514 /// # futures::executor::block_on(async { /// # // TODO: These should be all using `futures::compat`, but that runs up against Cargo /// # // feature issues /// use futures_util::compat::Future01CompatExt; /// /// let future = futures_01::future::ok::(1); /// assert_eq!(future.compat().await, Ok(1)); /// # }); /// ``` fn compat(self) -> Compat01As03 where Self: Sized, { Compat01As03::new(self) } } impl Future01CompatExt for Fut {} /// Extension trait for futures 0.1 [`Stream`](futures_01::stream::Stream) pub trait Stream01CompatExt: Stream01 { /// Converts a futures 0.1 /// [`Stream`](futures_01::stream::Stream) /// into a futures 0.3 /// [`Stream>`](futures_core::stream::Stream). /// /// ``` /// # if cfg!(miri) { return; } // https://github.com/rust-lang/futures-rs/issues/2514 /// # futures::executor::block_on(async { /// use futures::stream::StreamExt; /// use futures_util::compat::Stream01CompatExt; /// /// let stream = futures_01::stream::once::(Ok(1)); /// let mut stream = stream.compat(); /// assert_eq!(stream.next().await, Some(Ok(1))); /// assert_eq!(stream.next().await, None); /// # }); /// ``` fn compat(self) -> Compat01As03 where Self: Sized, { Compat01As03::new(self) } } impl Stream01CompatExt for St {} /// Extension trait for futures 0.1 [`Sink`](futures_01::sink::Sink) #[cfg(feature = "sink")] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] pub trait Sink01CompatExt: Sink01 { /// Converts a futures 0.1 /// [`Sink`](futures_01::sink::Sink) /// into a futures 0.3 /// [`Sink`](futures_sink::Sink). /// /// ``` /// # if cfg!(miri) { return; } // https://github.com/rust-lang/futures-rs/issues/2514 /// # futures::executor::block_on(async { /// use futures::{sink::SinkExt, stream::StreamExt}; /// use futures_util::compat::{Stream01CompatExt, Sink01CompatExt}; /// /// let (tx, rx) = futures_01::unsync::mpsc::channel(1); /// let (mut tx, mut rx) = (tx.sink_compat(), rx.compat()); /// /// tx.send(1).await.unwrap(); /// drop(tx); /// assert_eq!(rx.next().await, Some(Ok(1))); /// assert_eq!(rx.next().await, None); /// # }); /// ``` fn sink_compat(self) -> Compat01As03Sink where Self: Sized, { Compat01As03Sink::new(self) } } #[cfg(feature = "sink")] impl Sink01CompatExt for Si {} fn poll_01_to_03(x: Result, E>) -> task03::Poll> { match x? { Async01::Ready(t) => task03::Poll::Ready(Ok(t)), Async01::NotReady => task03::Poll::Pending, } } impl Future03 for Compat01As03 { type Output = Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> task03::Poll { poll_01_to_03(self.in_notify(cx, Future01::poll)) } } impl Stream03 for Compat01As03 { type Item = Result; fn poll_next( mut self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> task03::Poll> { match self.in_notify(cx, Stream01::poll)? { Async01::Ready(Some(t)) => task03::Poll::Ready(Some(Ok(t))), Async01::Ready(None) => task03::Poll::Ready(None), Async01::NotReady => task03::Poll::Pending, } } } /// Converts a futures 0.1 Sink object to a futures 0.3-compatible version #[cfg(feature = "sink")] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] #[derive(Debug)] #[must_use = "sinks do nothing unless polled"] pub struct Compat01As03Sink { pub(crate) inner: Spawn01, pub(crate) buffer: Option, pub(crate) close_started: bool, } #[cfg(feature = "sink")] impl Unpin for Compat01As03Sink {} #[cfg(feature = "sink")] impl Compat01As03Sink { /// Wraps a futures 0.1 Sink object in a futures 0.3-compatible wrapper. pub fn new(inner: S) -> Self { Self { inner: spawn01(inner), buffer: None, close_started: false } } fn in_notify(&mut self, cx: &mut Context<'_>, f: impl FnOnce(&mut S) -> R) -> R { let notify = &WakerToHandle(cx.waker()); self.inner.poll_fn_notify(notify, 0, f) } /// Get a reference to 0.1 Sink object contained within. pub fn get_ref(&self) -> &S { self.inner.get_ref() } /// Get a mutable reference to 0.1 Sink contained within. pub fn get_mut(&mut self) -> &mut S { self.inner.get_mut() } /// Consume this wrapper to return the underlying 0.1 Sink. pub fn into_inner(self) -> S { self.inner.into_inner() } } #[cfg(feature = "sink")] impl Stream03 for Compat01As03Sink where S: Stream01, { type Item = Result; fn poll_next( mut self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> task03::Poll> { match self.in_notify(cx, Stream01::poll)? { Async01::Ready(Some(t)) => task03::Poll::Ready(Some(Ok(t))), Async01::Ready(None) => task03::Poll::Ready(None), Async01::NotReady => task03::Poll::Pending, } } } #[cfg(feature = "sink")] impl Sink03 for Compat01As03Sink where S: Sink01, { type Error = S::SinkError; fn start_send(mut self: Pin<&mut Self>, item: SinkItem) -> Result<(), Self::Error> { debug_assert!(self.buffer.is_none()); self.buffer = Some(item); Ok(()) } fn poll_ready( mut self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> task03::Poll> { match self.buffer.take() { Some(item) => match self.in_notify(cx, |f| f.start_send(item))? { AsyncSink01::Ready => task03::Poll::Ready(Ok(())), AsyncSink01::NotReady(i) => { self.buffer = Some(i); task03::Poll::Pending } }, None => task03::Poll::Ready(Ok(())), } } fn poll_flush( mut self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> task03::Poll> { let item = self.buffer.take(); match self.in_notify(cx, |f| match item { Some(i) => match f.start_send(i)? { AsyncSink01::Ready => f.poll_complete().map(|i| (i, None)), AsyncSink01::NotReady(t) => Ok((Async01::NotReady, Some(t))), }, None => f.poll_complete().map(|i| (i, None)), })? { (Async01::Ready(_), _) => task03::Poll::Ready(Ok(())), (Async01::NotReady, item) => { self.buffer = item; task03::Poll::Pending } } } fn poll_close( mut self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> task03::Poll> { let item = self.buffer.take(); let close_started = self.close_started; let result = self.in_notify(cx, |f| { if !close_started { if let Some(item) = item { if let AsyncSink01::NotReady(item) = f.start_send(item)? { return Ok((Async01::NotReady, Some(item), false)); } } if let Async01::NotReady = f.poll_complete()? { return Ok((Async01::NotReady, None, false)); } } Ok((::close(f)?, None, true)) }); match result? { (Async01::Ready(_), _, _) => task03::Poll::Ready(Ok(())), (Async01::NotReady, item, close_started) => { self.buffer = item; self.close_started = close_started; task03::Poll::Pending } } } } struct NotifyWaker(task03::Waker); #[allow(missing_debug_implementations)] // false positive: this is private type #[derive(Clone)] struct WakerToHandle<'a>(&'a task03::Waker); impl From> for NotifyHandle01 { fn from(handle: WakerToHandle<'_>) -> Self { let ptr = Box::new(NotifyWaker(handle.0.clone())); unsafe { Self::new(Box::into_raw(ptr)) } } } impl Notify01 for NotifyWaker { fn notify(&self, _: usize) { self.0.wake_by_ref(); } } unsafe impl UnsafeNotify01 for NotifyWaker { unsafe fn clone_raw(&self) -> NotifyHandle01 { WakerToHandle(&self.0).into() } unsafe fn drop_raw(&self) { let ptr: *const dyn UnsafeNotify01 = self; drop(Box::from_raw(ptr as *mut dyn UnsafeNotify01)); } } #[cfg(feature = "io-compat")] #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] mod io { use super::*; use futures_io::{AsyncRead as AsyncRead03, AsyncWrite as AsyncWrite03}; use std::io::Error; use tokio_io::{AsyncRead as AsyncRead01, AsyncWrite as AsyncWrite01}; /// Extension trait for tokio-io [`AsyncRead`](tokio_io::AsyncRead) #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] pub trait AsyncRead01CompatExt: AsyncRead01 { /// Converts a tokio-io [`AsyncRead`](tokio_io::AsyncRead) into a futures-io 0.3 /// [`AsyncRead`](futures_io::AsyncRead). /// /// ``` /// # if cfg!(miri) { return; } // https://github.com/rust-lang/futures-rs/issues/2514 /// # futures::executor::block_on(async { /// use futures::io::AsyncReadExt; /// use futures_util::compat::AsyncRead01CompatExt; /// /// let input = b"Hello World!"; /// let reader /* : impl tokio_io::AsyncRead */ = std::io::Cursor::new(input); /// let mut reader /* : impl futures::io::AsyncRead + Unpin */ = reader.compat(); /// /// let mut output = Vec::with_capacity(12); /// reader.read_to_end(&mut output).await.unwrap(); /// assert_eq!(output, input); /// # }); /// ``` fn compat(self) -> Compat01As03 where Self: Sized, { Compat01As03::new(self) } } impl AsyncRead01CompatExt for R {} /// Extension trait for tokio-io [`AsyncWrite`](tokio_io::AsyncWrite) #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] pub trait AsyncWrite01CompatExt: AsyncWrite01 { /// Converts a tokio-io [`AsyncWrite`](tokio_io::AsyncWrite) into a futures-io 0.3 /// [`AsyncWrite`](futures_io::AsyncWrite). /// /// ``` /// # if cfg!(miri) { return; } // https://github.com/rust-lang/futures-rs/issues/2514 /// # futures::executor::block_on(async { /// use futures::io::AsyncWriteExt; /// use futures_util::compat::AsyncWrite01CompatExt; /// /// let input = b"Hello World!"; /// let mut cursor = std::io::Cursor::new(Vec::with_capacity(12)); /// /// let mut writer = (&mut cursor).compat(); /// writer.write_all(input).await.unwrap(); /// /// assert_eq!(cursor.into_inner(), input); /// # }); /// ``` fn compat(self) -> Compat01As03 where Self: Sized, { Compat01As03::new(self) } } impl AsyncWrite01CompatExt for W {} impl AsyncRead03 for Compat01As03 { fn poll_read( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], ) -> task03::Poll> { poll_01_to_03(self.in_notify(cx, |x| x.poll_read(buf))) } } impl AsyncWrite03 for Compat01As03 { fn poll_write( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> task03::Poll> { poll_01_to_03(self.in_notify(cx, |x| x.poll_write(buf))) } fn poll_flush( mut self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> task03::Poll> { poll_01_to_03(self.in_notify(cx, AsyncWrite01::poll_flush)) } fn poll_close( mut self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> task03::Poll> { poll_01_to_03(self.in_notify(cx, AsyncWrite01::shutdown)) } } } futures-util-0.3.30/src/compat/compat03as01.rs000064400000000000000000000202521046102023000171130ustar 00000000000000use crate::task::{self as task03, ArcWake as ArcWake03, WakerRef}; use futures_01::{ task as task01, Async as Async01, Future as Future01, Poll as Poll01, Stream as Stream01, }; #[cfg(feature = "sink")] use futures_01::{AsyncSink as AsyncSink01, Sink as Sink01, StartSend as StartSend01}; use futures_core::{ future::TryFuture as TryFuture03, stream::TryStream as TryStream03, task::{RawWaker, RawWakerVTable}, }; #[cfg(feature = "sink")] use futures_sink::Sink as Sink03; #[cfg(feature = "sink")] use std::marker::PhantomData; use std::{mem, pin::Pin, sync::Arc, task::Context}; /// Converts a futures 0.3 [`TryFuture`](futures_core::future::TryFuture) or /// [`TryStream`](futures_core::stream::TryStream) into a futures 0.1 /// [`Future`](futures_01::future::Future) or /// [`Stream`](futures_01::stream::Stream). #[derive(Debug, Clone, Copy)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Compat { pub(crate) inner: T, } /// Converts a futures 0.3 [`Sink`](futures_sink::Sink) into a futures 0.1 /// [`Sink`](futures_01::sink::Sink). #[cfg(feature = "sink")] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] #[derive(Debug)] #[must_use = "sinks do nothing unless polled"] pub struct CompatSink { inner: T, _phantom: PhantomData, } impl Compat { /// Creates a new [`Compat`]. /// /// For types which implement appropriate futures `0.3` /// traits, the result will be a type which implements /// the corresponding futures 0.1 type. pub fn new(inner: T) -> Self { Self { inner } } /// Get a reference to 0.3 Future, Stream, AsyncRead, or AsyncWrite object /// contained within. pub fn get_ref(&self) -> &T { &self.inner } /// Get a mutable reference to 0.3 Future, Stream, AsyncRead, or AsyncWrite object /// contained within. pub fn get_mut(&mut self) -> &mut T { &mut self.inner } /// Returns the inner item. pub fn into_inner(self) -> T { self.inner } } #[cfg(feature = "sink")] impl CompatSink { /// Creates a new [`CompatSink`]. pub fn new(inner: T) -> Self { Self { inner, _phantom: PhantomData } } /// Get a reference to 0.3 Sink contained within. pub fn get_ref(&self) -> &T { &self.inner } /// Get a mutable reference to 0.3 Sink contained within. pub fn get_mut(&mut self) -> &mut T { &mut self.inner } /// Returns the inner item. pub fn into_inner(self) -> T { self.inner } } fn poll_03_to_01(x: task03::Poll>) -> Result, E> { match x? { task03::Poll::Ready(t) => Ok(Async01::Ready(t)), task03::Poll::Pending => Ok(Async01::NotReady), } } impl Future01 for Compat where Fut: TryFuture03 + Unpin, { type Item = Fut::Ok; type Error = Fut::Error; fn poll(&mut self) -> Poll01 { with_context(self, |inner, cx| poll_03_to_01(inner.try_poll(cx))) } } impl Stream01 for Compat where St: TryStream03 + Unpin, { type Item = St::Ok; type Error = St::Error; fn poll(&mut self) -> Poll01, Self::Error> { with_context(self, |inner, cx| match inner.try_poll_next(cx)? { task03::Poll::Ready(None) => Ok(Async01::Ready(None)), task03::Poll::Ready(Some(t)) => Ok(Async01::Ready(Some(t))), task03::Poll::Pending => Ok(Async01::NotReady), }) } } #[cfg(feature = "sink")] impl Sink01 for CompatSink where T: Sink03 + Unpin, { type SinkItem = Item; type SinkError = T::Error; fn start_send(&mut self, item: Self::SinkItem) -> StartSend01 { with_sink_context(self, |mut inner, cx| match inner.as_mut().poll_ready(cx)? { task03::Poll::Ready(()) => inner.start_send(item).map(|()| AsyncSink01::Ready), task03::Poll::Pending => Ok(AsyncSink01::NotReady(item)), }) } fn poll_complete(&mut self) -> Poll01<(), Self::SinkError> { with_sink_context(self, |inner, cx| poll_03_to_01(inner.poll_flush(cx))) } fn close(&mut self) -> Poll01<(), Self::SinkError> { with_sink_context(self, |inner, cx| poll_03_to_01(inner.poll_close(cx))) } } #[derive(Clone)] struct Current(task01::Task); impl Current { fn new() -> Self { Self(task01::current()) } fn as_waker(&self) -> WakerRef<'_> { unsafe fn ptr_to_current<'a>(ptr: *const ()) -> &'a Current { &*(ptr as *const Current) } fn current_to_ptr(current: &Current) -> *const () { current as *const Current as *const () } unsafe fn clone(ptr: *const ()) -> RawWaker { // Lazily create the `Arc` only when the waker is actually cloned. // FIXME: remove `transmute` when a `Waker` -> `RawWaker` conversion // function is landed in `core`. mem::transmute::(task03::waker(Arc::new( ptr_to_current(ptr).clone(), ))) } unsafe fn drop(_: *const ()) {} unsafe fn wake(ptr: *const ()) { ptr_to_current(ptr).0.notify() } let ptr = current_to_ptr(self); let vtable = &RawWakerVTable::new(clone, wake, wake, drop); WakerRef::new_unowned(std::mem::ManuallyDrop::new(unsafe { task03::Waker::from_raw(RawWaker::new(ptr, vtable)) })) } } impl ArcWake03 for Current { fn wake_by_ref(arc_self: &Arc) { arc_self.0.notify(); } } fn with_context(compat: &mut Compat, f: F) -> R where T: Unpin, F: FnOnce(Pin<&mut T>, &mut Context<'_>) -> R, { let current = Current::new(); let waker = current.as_waker(); let mut cx = Context::from_waker(&waker); f(Pin::new(&mut compat.inner), &mut cx) } #[cfg(feature = "sink")] fn with_sink_context(compat: &mut CompatSink, f: F) -> R where T: Unpin, F: FnOnce(Pin<&mut T>, &mut Context<'_>) -> R, { let current = Current::new(); let waker = current.as_waker(); let mut cx = Context::from_waker(&waker); f(Pin::new(&mut compat.inner), &mut cx) } #[cfg(feature = "io-compat")] #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] mod io { use super::*; use futures_io::{AsyncRead as AsyncRead03, AsyncWrite as AsyncWrite03}; use tokio_io::{AsyncRead as AsyncRead01, AsyncWrite as AsyncWrite01}; fn poll_03_to_io(x: task03::Poll>) -> Result { match x { task03::Poll::Ready(Ok(t)) => Ok(t), task03::Poll::Pending => Err(std::io::ErrorKind::WouldBlock.into()), task03::Poll::Ready(Err(e)) => Err(e), } } impl std::io::Read for Compat { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { let current = Current::new(); let waker = current.as_waker(); let mut cx = Context::from_waker(&waker); poll_03_to_io(Pin::new(&mut self.inner).poll_read(&mut cx, buf)) } } impl AsyncRead01 for Compat {} impl std::io::Write for Compat { fn write(&mut self, buf: &[u8]) -> std::io::Result { let current = Current::new(); let waker = current.as_waker(); let mut cx = Context::from_waker(&waker); poll_03_to_io(Pin::new(&mut self.inner).poll_write(&mut cx, buf)) } fn flush(&mut self) -> std::io::Result<()> { let current = Current::new(); let waker = current.as_waker(); let mut cx = Context::from_waker(&waker); poll_03_to_io(Pin::new(&mut self.inner).poll_flush(&mut cx)) } } impl AsyncWrite01 for Compat { fn shutdown(&mut self) -> std::io::Result> { let current = Current::new(); let waker = current.as_waker(); let mut cx = Context::from_waker(&waker); poll_03_to_01(Pin::new(&mut self.inner).poll_close(&mut cx)) } } } futures-util-0.3.30/src/compat/executor.rs000064400000000000000000000055051046102023000166420ustar 00000000000000use super::{Compat, Future01CompatExt}; use crate::{ future::{FutureExt, TryFutureExt, UnitError}, task::SpawnExt, }; use futures_01::future::{ExecuteError as ExecuteError01, Executor as Executor01}; use futures_01::Future as Future01; use futures_task::{FutureObj, Spawn as Spawn03, SpawnError as SpawnError03}; /// A future that can run on a futures 0.1 /// [`Executor`](futures_01::future::Executor). pub type Executor01Future = Compat>>; /// Extension trait for futures 0.1 [`Executor`](futures_01::future::Executor). pub trait Executor01CompatExt: Executor01 + Clone + Send + 'static { /// Converts a futures 0.1 [`Executor`](futures_01::future::Executor) into a /// futures 0.3 [`Spawn`](futures_task::Spawn). /// /// ``` /// # if cfg!(miri) { return; } // Miri does not support epoll /// use futures::task::SpawnExt; /// use futures::future::{FutureExt, TryFutureExt}; /// use futures_util::compat::Executor01CompatExt; /// use tokio::executor::DefaultExecutor; /// /// # let (tx, rx) = futures::channel::oneshot::channel(); /// /// let spawner = DefaultExecutor::current().compat(); /// let future03 = async move { /// println!("Running on the pool"); /// spawner.spawn(async { /// println!("Spawned!"); /// # tx.send(42).unwrap(); /// }).unwrap(); /// }; /// /// let future01 = future03.unit_error().boxed().compat(); /// /// tokio::run(future01); /// # futures::executor::block_on(rx).unwrap(); /// ``` fn compat(self) -> Executor01As03 where Self: Sized; } impl Executor01CompatExt for Ex where Ex: Executor01 + Clone + Send + 'static, { fn compat(self) -> Executor01As03 { Executor01As03 { executor01: self } } } /// Converts a futures 0.1 [`Executor`](futures_01::future::Executor) into a /// futures 0.3 [`Spawn`](futures_task::Spawn). #[derive(Debug, Clone)] pub struct Executor01As03 { executor01: Ex, } impl Spawn03 for Executor01As03 where Ex: Executor01 + Clone + Send + 'static, { fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError03> { let future = future.unit_error().compat(); self.executor01.execute(future).map_err(|_| SpawnError03::shutdown()) } } #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 impl Executor01 for Compat where for<'a> &'a Sp: Spawn03, Fut: Future01 + Send + 'static, { fn execute(&self, future: Fut) -> Result<(), ExecuteError01> { (&self.inner) .spawn(future.compat().map(|_| ())) .expect("unable to spawn future from Compat executor"); Ok(()) } } futures-util-0.3.30/src/compat/mod.rs000064400000000000000000000014421046102023000155570ustar 00000000000000//! Interop between `futures` 0.1 and 0.3. //! //! This module is only available when the `compat` feature of this //! library is activated. mod executor; pub use self::executor::{Executor01As03, Executor01CompatExt, Executor01Future}; mod compat01as03; #[cfg(feature = "io-compat")] #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] pub use self::compat01as03::{AsyncRead01CompatExt, AsyncWrite01CompatExt}; pub use self::compat01as03::{Compat01As03, Future01CompatExt, Stream01CompatExt}; #[cfg(feature = "sink")] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] pub use self::compat01as03::{Compat01As03Sink, Sink01CompatExt}; mod compat03as01; pub use self::compat03as01::Compat; #[cfg(feature = "sink")] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] pub use self::compat03as01::CompatSink; futures-util-0.3.30/src/fns.rs000064400000000000000000000207751046102023000143150ustar 00000000000000use core::fmt::{self, Debug}; use core::marker::PhantomData; pub trait FnOnce1 { type Output; fn call_once(self, arg: A) -> Self::Output; } impl FnOnce1 for T where T: FnOnce(A) -> R, { type Output = R; fn call_once(self, arg: A) -> R { self(arg) } } pub trait FnMut1: FnOnce1 { fn call_mut(&mut self, arg: A) -> Self::Output; } impl FnMut1 for T where T: FnMut(A) -> R, { fn call_mut(&mut self, arg: A) -> R { self(arg) } } // Not used, but present for completeness #[allow(unreachable_pub)] pub trait Fn1: FnMut1 { fn call(&self, arg: A) -> Self::Output; } impl Fn1 for T where T: Fn(A) -> R, { fn call(&self, arg: A) -> R { self(arg) } } macro_rules! trivial_fn_impls { ($name:ident <$($arg:ident),*> $t:ty = $debug:literal) => { impl<$($arg),*> Copy for $t {} impl<$($arg),*> Clone for $t { fn clone(&self) -> Self { *self } } impl<$($arg),*> Debug for $t { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str($debug) } } impl<$($arg,)* A> FnMut1 for $t where Self: FnOnce1 { fn call_mut(&mut self, arg: A) -> Self::Output { self.call_once(arg) } } impl<$($arg,)* A> Fn1 for $t where Self: FnOnce1 { fn call(&self, arg: A) -> Self::Output { self.call_once(arg) } } pub(crate) fn $name<$($arg),*>() -> $t { Default::default() } } } pub struct OkFn(PhantomData); impl Default for OkFn { fn default() -> Self { Self(PhantomData) } } impl FnOnce1 for OkFn { type Output = Result; fn call_once(self, arg: A) -> Self::Output { Ok(arg) } } trivial_fn_impls!(ok_fn OkFn = "Ok"); #[derive(Debug, Copy, Clone, Default)] pub struct ChainFn(F, G); impl FnOnce1 for ChainFn where F: FnOnce1, G: FnOnce1, { type Output = G::Output; fn call_once(self, arg: A) -> Self::Output { self.1.call_once(self.0.call_once(arg)) } } impl FnMut1 for ChainFn where F: FnMut1, G: FnMut1, { fn call_mut(&mut self, arg: A) -> Self::Output { self.1.call_mut(self.0.call_mut(arg)) } } impl Fn1 for ChainFn where F: Fn1, G: Fn1, { fn call(&self, arg: A) -> Self::Output { self.1.call(self.0.call(arg)) } } pub(crate) fn chain_fn(f: F, g: G) -> ChainFn { ChainFn(f, g) } #[derive(Default)] pub struct MergeResultFn; impl FnOnce1> for MergeResultFn { type Output = T; fn call_once(self, arg: Result) -> Self::Output { match arg { Ok(x) => x, Err(x) => x, } } } trivial_fn_impls!(merge_result_fn <> MergeResultFn = "merge_result"); #[derive(Debug, Copy, Clone, Default)] pub struct InspectFn(F); #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 impl FnOnce1 for InspectFn where F: for<'a> FnOnce1<&'a A, Output = ()>, { type Output = A; fn call_once(self, arg: A) -> Self::Output { self.0.call_once(&arg); arg } } #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 impl FnMut1 for InspectFn where F: for<'a> FnMut1<&'a A, Output = ()>, { fn call_mut(&mut self, arg: A) -> Self::Output { self.0.call_mut(&arg); arg } } #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 impl Fn1 for InspectFn where F: for<'a> Fn1<&'a A, Output = ()>, { fn call(&self, arg: A) -> Self::Output { self.0.call(&arg); arg } } pub(crate) fn inspect_fn(f: F) -> InspectFn { InspectFn(f) } #[derive(Debug, Copy, Clone, Default)] pub struct MapOkFn(F); impl FnOnce1> for MapOkFn where F: FnOnce1, { type Output = Result; fn call_once(self, arg: Result) -> Self::Output { arg.map(|x| self.0.call_once(x)) } } impl FnMut1> for MapOkFn where F: FnMut1, { fn call_mut(&mut self, arg: Result) -> Self::Output { arg.map(|x| self.0.call_mut(x)) } } impl Fn1> for MapOkFn where F: Fn1, { fn call(&self, arg: Result) -> Self::Output { arg.map(|x| self.0.call(x)) } } pub(crate) fn map_ok_fn(f: F) -> MapOkFn { MapOkFn(f) } #[derive(Debug, Copy, Clone, Default)] pub struct MapErrFn(F); impl FnOnce1> for MapErrFn where F: FnOnce1, { type Output = Result; fn call_once(self, arg: Result) -> Self::Output { arg.map_err(|x| self.0.call_once(x)) } } impl FnMut1> for MapErrFn where F: FnMut1, { fn call_mut(&mut self, arg: Result) -> Self::Output { arg.map_err(|x| self.0.call_mut(x)) } } impl Fn1> for MapErrFn where F: Fn1, { fn call(&self, arg: Result) -> Self::Output { arg.map_err(|x| self.0.call(x)) } } pub(crate) fn map_err_fn(f: F) -> MapErrFn { MapErrFn(f) } #[derive(Debug, Copy, Clone)] pub struct InspectOkFn(F); impl<'a, F, T, E> FnOnce1<&'a Result> for InspectOkFn where F: FnOnce1<&'a T, Output = ()>, { type Output = (); fn call_once(self, arg: &'a Result) -> Self::Output { if let Ok(x) = arg { self.0.call_once(x) } } } impl<'a, F, T, E> FnMut1<&'a Result> for InspectOkFn where F: FnMut1<&'a T, Output = ()>, { fn call_mut(&mut self, arg: &'a Result) -> Self::Output { if let Ok(x) = arg { self.0.call_mut(x) } } } impl<'a, F, T, E> Fn1<&'a Result> for InspectOkFn where F: Fn1<&'a T, Output = ()>, { fn call(&self, arg: &'a Result) -> Self::Output { if let Ok(x) = arg { self.0.call(x) } } } pub(crate) fn inspect_ok_fn(f: F) -> InspectOkFn { InspectOkFn(f) } #[derive(Debug, Copy, Clone)] pub struct InspectErrFn(F); impl<'a, F, T, E> FnOnce1<&'a Result> for InspectErrFn where F: FnOnce1<&'a E, Output = ()>, { type Output = (); fn call_once(self, arg: &'a Result) -> Self::Output { if let Err(x) = arg { self.0.call_once(x) } } } impl<'a, F, T, E> FnMut1<&'a Result> for InspectErrFn where F: FnMut1<&'a E, Output = ()>, { fn call_mut(&mut self, arg: &'a Result) -> Self::Output { if let Err(x) = arg { self.0.call_mut(x) } } } impl<'a, F, T, E> Fn1<&'a Result> for InspectErrFn where F: Fn1<&'a E, Output = ()>, { fn call(&self, arg: &'a Result) -> Self::Output { if let Err(x) = arg { self.0.call(x) } } } pub(crate) fn inspect_err_fn(f: F) -> InspectErrFn { InspectErrFn(f) } pub(crate) type MapOkOrElseFn = ChainFn, ChainFn, MergeResultFn>>; pub(crate) fn map_ok_or_else_fn(f: F, g: G) -> MapOkOrElseFn { chain_fn(map_ok_fn(f), chain_fn(map_err_fn(g), merge_result_fn())) } #[derive(Debug, Copy, Clone, Default)] pub struct UnwrapOrElseFn(F); impl FnOnce1> for UnwrapOrElseFn where F: FnOnce1, { type Output = T; fn call_once(self, arg: Result) -> Self::Output { arg.unwrap_or_else(|x| self.0.call_once(x)) } } impl FnMut1> for UnwrapOrElseFn where F: FnMut1, { fn call_mut(&mut self, arg: Result) -> Self::Output { arg.unwrap_or_else(|x| self.0.call_mut(x)) } } impl Fn1> for UnwrapOrElseFn where F: Fn1, { fn call(&self, arg: Result) -> Self::Output { arg.unwrap_or_else(|x| self.0.call(x)) } } pub(crate) fn unwrap_or_else_fn(f: F) -> UnwrapOrElseFn { UnwrapOrElseFn(f) } pub struct IntoFn(PhantomData T>); impl Default for IntoFn { fn default() -> Self { Self(PhantomData) } } impl FnOnce1 for IntoFn where A: Into, { type Output = T; fn call_once(self, arg: A) -> Self::Output { arg.into() } } trivial_fn_impls!(into_fn IntoFn = "Into::into"); futures-util-0.3.30/src/future/abortable.rs000064400000000000000000000013511046102023000167610ustar 00000000000000use super::assert_future; use crate::future::{AbortHandle, Abortable, Aborted}; use futures_core::future::Future; /// Creates a new `Abortable` future and an `AbortHandle` which can be used to stop it. /// /// This function is a convenient (but less flexible) alternative to calling /// `AbortHandle::new` and `Abortable::new` manually. /// /// This function is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. pub fn abortable(future: Fut) -> (Abortable, AbortHandle) where Fut: Future, { let (handle, reg) = AbortHandle::new_pair(); let abortable = assert_future::, _>(Abortable::new(future, reg)); (abortable, handle) } futures-util-0.3.30/src/future/either.rs000064400000000000000000000223241046102023000163110ustar 00000000000000use core::pin::Pin; use core::task::{Context, Poll}; use futures_core::future::{FusedFuture, Future}; use futures_core::stream::{FusedStream, Stream}; #[cfg(feature = "sink")] use futures_sink::Sink; /// Combines two different futures, streams, or sinks having the same associated types into a single type. /// /// This is useful when conditionally choosing between two distinct future types: /// /// ```rust /// use futures::future::Either; /// /// # futures::executor::block_on(async { /// let cond = true; /// /// let fut = if cond { /// Either::Left(async move { 12 }) /// } else { /// Either::Right(async move { 44 }) /// }; /// /// assert_eq!(fut.await, 12); /// # }) /// ``` #[derive(Debug, Clone)] pub enum Either { /// First branch of the type Left(/* #[pin] */ A), /// Second branch of the type Right(/* #[pin] */ B), } impl Either { /// Convert `Pin<&Either>` to `Either, Pin<&B>>`, /// pinned projections of the inner variants. pub fn as_pin_ref(self: Pin<&Self>) -> Either, Pin<&B>> { // SAFETY: We can use `new_unchecked` because the `inner` parts are // guaranteed to be pinned, as they come from `self` which is pinned. unsafe { match *Pin::get_ref(self) { Either::Left(ref inner) => Either::Left(Pin::new_unchecked(inner)), Either::Right(ref inner) => Either::Right(Pin::new_unchecked(inner)), } } } /// Convert `Pin<&mut Either>` to `Either, Pin<&mut B>>`, /// pinned projections of the inner variants. pub fn as_pin_mut(self: Pin<&mut Self>) -> Either, Pin<&mut B>> { // SAFETY: `get_unchecked_mut` is fine because we don't move anything. // We can use `new_unchecked` because the `inner` parts are guaranteed // to be pinned, as they come from `self` which is pinned, and we never // offer an unpinned `&mut A` or `&mut B` through `Pin<&mut Self>`. We // also don't have an implementation of `Drop`, nor manual `Unpin`. unsafe { match *Pin::get_unchecked_mut(self) { Either::Left(ref mut inner) => Either::Left(Pin::new_unchecked(inner)), Either::Right(ref mut inner) => Either::Right(Pin::new_unchecked(inner)), } } } } impl Either<(T, A), (T, B)> { /// Factor out a homogeneous type from an either of pairs. /// /// Here, the homogeneous type is the first element of the pairs. pub fn factor_first(self) -> (T, Either) { match self { Either::Left((x, a)) => (x, Either::Left(a)), Either::Right((x, b)) => (x, Either::Right(b)), } } } impl Either<(A, T), (B, T)> { /// Factor out a homogeneous type from an either of pairs. /// /// Here, the homogeneous type is the second element of the pairs. pub fn factor_second(self) -> (Either, T) { match self { Either::Left((a, x)) => (Either::Left(a), x), Either::Right((b, x)) => (Either::Right(b), x), } } } impl Either { /// Extract the value of an either over two equivalent types. pub fn into_inner(self) -> T { match self { Either::Left(x) => x, Either::Right(x) => x, } } } impl Future for Either where A: Future, B: Future, { type Output = A::Output; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { match self.as_pin_mut() { Either::Left(x) => x.poll(cx), Either::Right(x) => x.poll(cx), } } } impl FusedFuture for Either where A: FusedFuture, B: FusedFuture, { fn is_terminated(&self) -> bool { match self { Either::Left(x) => x.is_terminated(), Either::Right(x) => x.is_terminated(), } } } impl Stream for Either where A: Stream, B: Stream, { type Item = A::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match self.as_pin_mut() { Either::Left(x) => x.poll_next(cx), Either::Right(x) => x.poll_next(cx), } } fn size_hint(&self) -> (usize, Option) { match self { Either::Left(x) => x.size_hint(), Either::Right(x) => x.size_hint(), } } } impl FusedStream for Either where A: FusedStream, B: FusedStream, { fn is_terminated(&self) -> bool { match self { Either::Left(x) => x.is_terminated(), Either::Right(x) => x.is_terminated(), } } } #[cfg(feature = "sink")] impl Sink for Either where A: Sink, B: Sink, { type Error = A::Error; fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match self.as_pin_mut() { Either::Left(x) => x.poll_ready(cx), Either::Right(x) => x.poll_ready(cx), } } fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { match self.as_pin_mut() { Either::Left(x) => x.start_send(item), Either::Right(x) => x.start_send(item), } } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match self.as_pin_mut() { Either::Left(x) => x.poll_flush(cx), Either::Right(x) => x.poll_flush(cx), } } fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match self.as_pin_mut() { Either::Left(x) => x.poll_close(cx), Either::Right(x) => x.poll_close(cx), } } } #[cfg(feature = "io")] #[cfg(feature = "std")] mod if_std { use super::*; use core::pin::Pin; use core::task::{Context, Poll}; use futures_io::{ AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, Result, SeekFrom, }; impl AsyncRead for Either where A: AsyncRead, B: AsyncRead, { fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll> { match self.as_pin_mut() { Either::Left(x) => x.poll_read(cx, buf), Either::Right(x) => x.poll_read(cx, buf), } } fn poll_read_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>], ) -> Poll> { match self.as_pin_mut() { Either::Left(x) => x.poll_read_vectored(cx, bufs), Either::Right(x) => x.poll_read_vectored(cx, bufs), } } } impl AsyncWrite for Either where A: AsyncWrite, B: AsyncWrite, { fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll> { match self.as_pin_mut() { Either::Left(x) => x.poll_write(cx, buf), Either::Right(x) => x.poll_write(cx, buf), } } fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll> { match self.as_pin_mut() { Either::Left(x) => x.poll_write_vectored(cx, bufs), Either::Right(x) => x.poll_write_vectored(cx, bufs), } } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match self.as_pin_mut() { Either::Left(x) => x.poll_flush(cx), Either::Right(x) => x.poll_flush(cx), } } fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match self.as_pin_mut() { Either::Left(x) => x.poll_close(cx), Either::Right(x) => x.poll_close(cx), } } } impl AsyncSeek for Either where A: AsyncSeek, B: AsyncSeek, { fn poll_seek( self: Pin<&mut Self>, cx: &mut Context<'_>, pos: SeekFrom, ) -> Poll> { match self.as_pin_mut() { Either::Left(x) => x.poll_seek(cx, pos), Either::Right(x) => x.poll_seek(cx, pos), } } } impl AsyncBufRead for Either where A: AsyncBufRead, B: AsyncBufRead, { fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match self.as_pin_mut() { Either::Left(x) => x.poll_fill_buf(cx), Either::Right(x) => x.poll_fill_buf(cx), } } fn consume(self: Pin<&mut Self>, amt: usize) { match self.as_pin_mut() { Either::Left(x) => x.consume(amt), Either::Right(x) => x.consume(amt), } } } } futures-util-0.3.30/src/future/future/catch_unwind.rs000064400000000000000000000016671046102023000210200ustar 00000000000000use core::any::Any; use core::pin::Pin; use std::panic::{catch_unwind, AssertUnwindSafe, UnwindSafe}; use futures_core::future::Future; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`catch_unwind`](super::FutureExt::catch_unwind) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct CatchUnwind { #[pin] future: Fut, } } impl CatchUnwind where Fut: Future + UnwindSafe, { pub(super) fn new(future: Fut) -> Self { Self { future } } } impl Future for CatchUnwind where Fut: Future + UnwindSafe, { type Output = Result>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let f = self.project().future; catch_unwind(AssertUnwindSafe(|| f.poll(cx)))?.map(Ok) } } futures-util-0.3.30/src/future/future/flatten.rs000064400000000000000000000105411046102023000177760ustar 00000000000000use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { #[project = FlattenProj] #[derive(Debug)] pub enum Flatten { First { #[pin] f: Fut1 }, Second { #[pin] f: Fut2 }, Empty, } } impl Flatten { pub(crate) fn new(future: Fut1) -> Self { Self::First { f: future } } } impl FusedFuture for Flatten where Fut: Future, Fut::Output: Future, { fn is_terminated(&self) -> bool { match self { Self::Empty => true, _ => false, } } } impl Future for Flatten where Fut: Future, Fut::Output: Future, { type Output = ::Output; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Poll::Ready(loop { match self.as_mut().project() { FlattenProj::First { f } => { let f = ready!(f.poll(cx)); self.set(Self::Second { f }); } FlattenProj::Second { f } => { let output = ready!(f.poll(cx)); self.set(Self::Empty); break output; } FlattenProj::Empty => panic!("Flatten polled after completion"), } }) } } impl FusedStream for Flatten where Fut: Future, Fut::Output: Stream, { fn is_terminated(&self) -> bool { match self { Self::Empty => true, _ => false, } } } impl Stream for Flatten where Fut: Future, Fut::Output: Stream, { type Item = ::Item; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Poll::Ready(loop { match self.as_mut().project() { FlattenProj::First { f } => { let f = ready!(f.poll(cx)); self.set(Self::Second { f }); } FlattenProj::Second { f } => { let output = ready!(f.poll_next(cx)); if output.is_none() { self.set(Self::Empty); } break output; } FlattenProj::Empty => break None, } }) } } #[cfg(feature = "sink")] impl Sink for Flatten where Fut: Future, Fut::Output: Sink, { type Error = >::Error; fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Poll::Ready(loop { match self.as_mut().project() { FlattenProj::First { f } => { let f = ready!(f.poll(cx)); self.set(Self::Second { f }); } FlattenProj::Second { f } => { break ready!(f.poll_ready(cx)); } FlattenProj::Empty => panic!("poll_ready called after eof"), } }) } fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { match self.project() { FlattenProj::First { .. } => panic!("poll_ready not called first"), FlattenProj::Second { f } => f.start_send(item), FlattenProj::Empty => panic!("start_send called after eof"), } } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match self.project() { FlattenProj::First { .. } => Poll::Ready(Ok(())), FlattenProj::Second { f } => f.poll_flush(cx), FlattenProj::Empty => panic!("poll_flush called after eof"), } } fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let res = match self.as_mut().project() { FlattenProj::Second { f } => f.poll_close(cx), _ => Poll::Ready(Ok(())), }; if res.is_ready() { self.set(Self::Empty); } res } } futures-util-0.3.30/src/future/future/fuse.rs000064400000000000000000000052731046102023000173110ustar 00000000000000use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`fuse`](super::FutureExt::fuse) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Fuse { #[pin] inner: Option, } } impl Fuse { pub(super) fn new(f: Fut) -> Self { Self { inner: Some(f) } } } impl Fuse { /// Creates a new `Fuse`-wrapped future which is already terminated. /// /// This can be useful in combination with looping and the `select!` /// macro, which bypasses terminated futures. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::channel::mpsc; /// use futures::future::{Fuse, FusedFuture, FutureExt}; /// use futures::select; /// use futures::stream::StreamExt; /// use futures::pin_mut; /// /// let (sender, mut stream) = mpsc::unbounded(); /// /// // Send a few messages into the stream /// sender.unbounded_send(()).unwrap(); /// sender.unbounded_send(()).unwrap(); /// drop(sender); /// /// // Use `Fuse::terminated()` to create an already-terminated future /// // which may be instantiated later. /// let foo_printer = Fuse::terminated(); /// pin_mut!(foo_printer); /// /// loop { /// select! { /// _ = foo_printer => {}, /// () = stream.select_next_some() => { /// if !foo_printer.is_terminated() { /// println!("Foo is already being printed!"); /// } else { /// foo_printer.set(async { /// // do some other async operations /// println!("Printing foo from `foo_printer` future"); /// }.fuse()); /// } /// }, /// complete => break, // `foo_printer` is terminated and the stream is done /// } /// } /// # }); /// ``` pub fn terminated() -> Self { Self { inner: None } } } impl FusedFuture for Fuse { fn is_terminated(&self) -> bool { self.inner.is_none() } } impl Future for Fuse { type Output = Fut::Output; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { match self.as_mut().project().inner.as_pin_mut() { Some(fut) => fut.poll(cx).map(|output| { self.project().inner.set(None); output }), None => Poll::Pending, } } } futures-util-0.3.30/src/future/future/map.rs000064400000000000000000000032611046102023000171170ustar 00000000000000use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; use crate::fns::FnOnce1; pin_project! { /// Internal Map future #[project = MapProj] #[project_replace = MapProjReplace] #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub enum Map { Incomplete { #[pin] future: Fut, f: F, }, Complete, } } impl Map { /// Creates a new Map. pub(crate) fn new(future: Fut, f: F) -> Self { Self::Incomplete { future, f } } } impl FusedFuture for Map where Fut: Future, F: FnOnce1, { fn is_terminated(&self) -> bool { match self { Self::Incomplete { .. } => false, Self::Complete => true, } } } impl Future for Map where Fut: Future, F: FnOnce1, { type Output = T; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { match self.as_mut().project() { MapProj::Incomplete { future, .. } => { let output = ready!(future.poll(cx)); match self.project_replace(Map::Complete) { MapProjReplace::Incomplete { f, .. } => Poll::Ready(f.call_once(output)), MapProjReplace::Complete => unreachable!(), } } MapProj::Complete => { panic!("Map must not be polled after it returned `Poll::Ready`") } } } } futures-util-0.3.30/src/future/future/mod.rs000064400000000000000000000464361046102023000171340ustar 00000000000000//! Futures //! //! This module contains a number of functions for working with `Future`s, //! including the `FutureExt` trait which adds methods to `Future` types. #[cfg(feature = "alloc")] use alloc::boxed::Box; use core::pin::Pin; use crate::fns::{inspect_fn, into_fn, ok_fn, InspectFn, IntoFn, OkFn}; use crate::future::{assert_future, Either}; use crate::never::Never; use crate::stream::assert_stream; #[cfg(feature = "alloc")] use futures_core::future::{BoxFuture, LocalBoxFuture}; use futures_core::{ future::Future, stream::Stream, task::{Context, Poll}, }; use pin_utils::pin_mut; // Combinators mod flatten; mod fuse; mod map; delegate_all!( /// Future for the [`flatten`](super::FutureExt::flatten) method. Flatten( flatten::Flatten::Output> ): Debug + Future + FusedFuture + New[|x: F| flatten::Flatten::new(x)] where F: Future ); delegate_all!( /// Stream for the [`flatten_stream`](FutureExt::flatten_stream) method. FlattenStream( flatten::Flatten::Output> ): Debug + Sink + Stream + FusedStream + New[|x: F| flatten::Flatten::new(x)] where F: Future ); #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use fuse::Fuse; delegate_all!( /// Future for the [`map`](super::FutureExt::map) method. Map( map::Map ): Debug + Future + FusedFuture + New[|x: Fut, f: F| map::Map::new(x, f)] ); delegate_all!( /// Stream for the [`into_stream`](FutureExt::into_stream) method. IntoStream( crate::stream::Once ): Debug + Stream + FusedStream + New[|x: F| crate::stream::Once::new(x)] ); delegate_all!( /// Future for the [`map_into`](FutureExt::map_into) combinator. MapInto( Map> ): Debug + Future + FusedFuture + New[|x: Fut| Map::new(x, into_fn())] ); delegate_all!( /// Future for the [`then`](FutureExt::then) method. Then( flatten::Flatten, Fut2> ): Debug + Future + FusedFuture + New[|x: Fut1, y: F| flatten::Flatten::new(Map::new(x, y))] ); delegate_all!( /// Future for the [`inspect`](FutureExt::inspect) method. Inspect( map::Map> ): Debug + Future + FusedFuture + New[|x: Fut, f: F| map::Map::new(x, inspect_fn(f))] ); delegate_all!( /// Future for the [`never_error`](super::FutureExt::never_error) combinator. NeverError( Map> ): Debug + Future + FusedFuture + New[|x: Fut| Map::new(x, ok_fn())] ); delegate_all!( /// Future for the [`unit_error`](super::FutureExt::unit_error) combinator. UnitError( Map> ): Debug + Future + FusedFuture + New[|x: Fut| Map::new(x, ok_fn())] ); #[cfg(feature = "std")] mod catch_unwind; #[cfg(feature = "std")] #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::catch_unwind::CatchUnwind; #[cfg(feature = "channel")] #[cfg_attr(docsrs, doc(cfg(feature = "channel")))] #[cfg(feature = "std")] mod remote_handle; #[cfg(feature = "channel")] #[cfg_attr(docsrs, doc(cfg(feature = "channel")))] #[cfg(feature = "std")] #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::remote_handle::{Remote, RemoteHandle}; #[cfg(feature = "std")] mod shared; #[cfg(feature = "std")] #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::shared::{Shared, WeakShared}; impl FutureExt for T where T: Future {} /// An extension trait for `Future`s that provides a variety of convenient /// adapters. pub trait FutureExt: Future { /// Map this future's output to a different type, returning a new future of /// the resulting type. /// /// This function is similar to the `Option::map` or `Iterator::map` where /// it will change the type of the underlying future. This is useful to /// chain along a computation once a future has been resolved. /// /// Note that this function consumes the receiving future and returns a /// wrapped version of it, similar to the existing `map` methods in the /// standard library. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::FutureExt; /// /// let future = async { 1 }; /// let new_future = future.map(|x| x + 3); /// assert_eq!(new_future.await, 4); /// # }); /// ``` fn map(self, f: F) -> Map where F: FnOnce(Self::Output) -> U, Self: Sized, { assert_future::(Map::new(self, f)) } /// Map this future's output to a different type, returning a new future of /// the resulting type. /// /// This function is equivalent to calling `map(Into::into)` but allows naming /// the return type. fn map_into(self) -> MapInto where Self::Output: Into, Self: Sized, { assert_future::(MapInto::new(self)) } /// Chain on a computation for when a future finished, passing the result of /// the future to the provided closure `f`. /// /// The returned value of the closure must implement the `Future` trait /// and can represent some more work to be done before the composed future /// is finished. /// /// The closure `f` is only run *after* successful completion of the `self` /// future. /// /// Note that this function consumes the receiving future and returns a /// wrapped version of it. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::FutureExt; /// /// let future_of_1 = async { 1 }; /// let future_of_4 = future_of_1.then(|x| async move { x + 3 }); /// assert_eq!(future_of_4.await, 4); /// # }); /// ``` fn then(self, f: F) -> Then where F: FnOnce(Self::Output) -> Fut, Fut: Future, Self: Sized, { assert_future::(Then::new(self, f)) } /// Wrap this future in an `Either` future, making it the left-hand variant /// of that `Either`. /// /// This can be used in combination with the `right_future` method to write `if` /// statements that evaluate to different futures in different branches. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::FutureExt; /// /// let x = 6; /// let future = if x < 10 { /// async { true }.left_future() /// } else { /// async { false }.right_future() /// }; /// /// assert_eq!(future.await, true); /// # }); /// ``` fn left_future(self) -> Either where B: Future, Self: Sized, { assert_future::(Either::Left(self)) } /// Wrap this future in an `Either` future, making it the right-hand variant /// of that `Either`. /// /// This can be used in combination with the `left_future` method to write `if` /// statements that evaluate to different futures in different branches. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::FutureExt; /// /// let x = 6; /// let future = if x > 10 { /// async { true }.left_future() /// } else { /// async { false }.right_future() /// }; /// /// assert_eq!(future.await, false); /// # }); /// ``` fn right_future(self) -> Either where A: Future, Self: Sized, { assert_future::(Either::Right(self)) } /// Convert this future into a single element stream. /// /// The returned stream contains single success if this future resolves to /// success or single error if this future resolves into error. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::FutureExt; /// use futures::stream::StreamExt; /// /// let future = async { 17 }; /// let stream = future.into_stream(); /// let collected: Vec<_> = stream.collect().await; /// assert_eq!(collected, vec![17]); /// # }); /// ``` fn into_stream(self) -> IntoStream where Self: Sized, { assert_stream::(IntoStream::new(self)) } /// Flatten the execution of this future when the output of this /// future is itself another future. /// /// This can be useful when combining futures together to flatten the /// computation out the final result. /// /// This method is roughly equivalent to `self.then(|x| x)`. /// /// Note that this function consumes the receiving future and returns a /// wrapped version of it. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::FutureExt; /// /// let nested_future = async { async { 1 } }; /// let future = nested_future.flatten(); /// assert_eq!(future.await, 1); /// # }); /// ``` fn flatten(self) -> Flatten where Self::Output: Future, Self: Sized, { let f = Flatten::new(self); assert_future::<<::Output as Future>::Output, _>(f) } /// Flatten the execution of this future when the successful result of this /// future is a stream. /// /// This can be useful when stream initialization is deferred, and it is /// convenient to work with that stream as if stream was available at the /// call site. /// /// Note that this function consumes this future and returns a wrapped /// version of it. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::FutureExt; /// use futures::stream::{self, StreamExt}; /// /// let stream_items = vec![17, 18, 19]; /// let future_of_a_stream = async { stream::iter(stream_items) }; /// /// let stream = future_of_a_stream.flatten_stream(); /// let list: Vec<_> = stream.collect().await; /// assert_eq!(list, vec![17, 18, 19]); /// # }); /// ``` fn flatten_stream(self) -> FlattenStream where Self::Output: Stream, Self: Sized, { assert_stream::<::Item, _>(FlattenStream::new(self)) } /// Fuse a future such that `poll` will never again be called once it has /// completed. This method can be used to turn any `Future` into a /// `FusedFuture`. /// /// Normally, once a future has returned `Poll::Ready` from `poll`, /// any further calls could exhibit bad behavior such as blocking /// forever, panicking, never returning, etc. If it is known that `poll` /// may be called too often then this method can be used to ensure that it /// has defined semantics. /// /// If a `fuse`d future is `poll`ed after having returned `Poll::Ready` /// previously, it will return `Poll::Pending`, from `poll` again (and will /// continue to do so for all future calls to `poll`). /// /// This combinator will drop the underlying future as soon as it has been /// completed to ensure resources are reclaimed as soon as possible. fn fuse(self) -> Fuse where Self: Sized, { let f = Fuse::new(self); assert_future::(f) } /// Do something with the output of a future before passing it on. /// /// When using futures, you'll often chain several of them together. While /// working on such code, you might want to check out what's happening at /// various parts in the pipeline, without consuming the intermediate /// value. To do that, insert a call to `inspect`. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::FutureExt; /// /// let future = async { 1 }; /// let new_future = future.inspect(|&x| println!("about to resolve: {}", x)); /// assert_eq!(new_future.await, 1); /// # }); /// ``` fn inspect(self, f: F) -> Inspect where F: FnOnce(&Self::Output), Self: Sized, { assert_future::(Inspect::new(self, f)) } /// Catches unwinding panics while polling the future. /// /// In general, panics within a future can propagate all the way out to the /// task level. This combinator makes it possible to halt unwinding within /// the future itself. It's most commonly used within task executors. It's /// not recommended to use this for error handling. /// /// Note that this method requires the `UnwindSafe` bound from the standard /// library. This isn't always applied automatically, and the standard /// library provides an `AssertUnwindSafe` wrapper type to apply it /// after-the fact. To assist using this method, the `Future` trait is also /// implemented for `AssertUnwindSafe` where `F` implements `Future`. /// /// This method is only available when the `std` feature of this /// library is activated, and it is activated by default. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::{self, FutureExt, Ready}; /// /// let future = future::ready(2); /// assert!(future.catch_unwind().await.is_ok()); /// /// let future = future::lazy(|_| -> Ready { /// unimplemented!() /// }); /// assert!(future.catch_unwind().await.is_err()); /// # }); /// ``` #[cfg(feature = "std")] fn catch_unwind(self) -> CatchUnwind where Self: Sized + ::std::panic::UnwindSafe, { assert_future::>, _>(CatchUnwind::new( self, )) } /// Create a cloneable handle to this future where all handles will resolve /// to the same result. /// /// The `shared` combinator method provides a method to convert any future /// into a cloneable future. It enables a future to be polled by multiple /// threads. /// /// This method is only available when the `std` feature of this /// library is activated, and it is activated by default. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::FutureExt; /// /// let future = async { 6 }; /// let shared1 = future.shared(); /// let shared2 = shared1.clone(); /// /// assert_eq!(6, shared1.await); /// assert_eq!(6, shared2.await); /// # }); /// ``` /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::FutureExt; /// use futures::executor::block_on; /// use std::thread; /// /// let future = async { 6 }; /// let shared1 = future.shared(); /// let shared2 = shared1.clone(); /// let join_handle = thread::spawn(move || { /// assert_eq!(6, block_on(shared2)); /// }); /// assert_eq!(6, shared1.await); /// join_handle.join().unwrap(); /// # }); /// ``` #[cfg(feature = "std")] fn shared(self) -> Shared where Self: Sized, Self::Output: Clone, { assert_future::(Shared::new(self)) } /// Turn this future into a future that yields `()` on completion and sends /// its output to another future on a separate task. /// /// This can be used with spawning executors to easily retrieve the result /// of a future executing on a separate task or thread. /// /// This method is only available when the `std` feature of this /// library is activated, and it is activated by default. #[cfg(feature = "channel")] #[cfg_attr(docsrs, doc(cfg(feature = "channel")))] #[cfg(feature = "std")] fn remote_handle(self) -> (Remote, RemoteHandle) where Self: Sized, { let (wrapped, handle) = remote_handle::remote_handle(self); (assert_future::<(), _>(wrapped), handle) } /// Wrap the future in a Box, pinning it. /// /// This method is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. #[cfg(feature = "alloc")] fn boxed<'a>(self) -> BoxFuture<'a, Self::Output> where Self: Sized + Send + 'a, { assert_future::(Box::pin(self)) } /// Wrap the future in a Box, pinning it. /// /// Similar to `boxed`, but without the `Send` requirement. /// /// This method is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. #[cfg(feature = "alloc")] fn boxed_local<'a>(self) -> LocalBoxFuture<'a, Self::Output> where Self: Sized + 'a, { assert_future::(Box::pin(self)) } /// Turns a [`Future`](Future) into a /// [`TryFuture](futures_core::future::TryFuture). fn unit_error(self) -> UnitError where Self: Sized, { assert_future::, _>(UnitError::new(self)) } /// Turns a [`Future`](Future) into a /// [`TryFuture](futures_core::future::TryFuture). fn never_error(self) -> NeverError where Self: Sized, { assert_future::, _>(NeverError::new(self)) } /// A convenience for calling `Future::poll` on `Unpin` future types. fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll where Self: Unpin, { Pin::new(self).poll(cx) } /// Evaluates and consumes the future, returning the resulting output if /// the future is ready after the first call to `Future::poll`. /// /// If `poll` instead returns `Poll::Pending`, `None` is returned. /// /// This method is useful in cases where immediacy is more important than /// waiting for a result. It is also convenient for quickly obtaining /// the value of a future that is known to always resolve immediately. /// /// # Examples /// /// ``` /// # use futures::prelude::*; /// use futures::{future::ready, future::pending}; /// let future_ready = ready("foobar"); /// let future_pending = pending::<&'static str>(); /// /// assert_eq!(future_ready.now_or_never(), Some("foobar")); /// assert_eq!(future_pending.now_or_never(), None); /// ``` /// /// In cases where it is absolutely known that a future should always /// resolve immediately and never return `Poll::Pending`, this method can /// be combined with `expect()`: /// /// ``` /// # use futures::{prelude::*, future::ready}; /// let future_ready = ready("foobar"); /// /// assert_eq!(future_ready.now_or_never().expect("Future not ready"), "foobar"); /// ``` fn now_or_never(self) -> Option where Self: Sized, { let noop_waker = crate::task::noop_waker(); let mut cx = Context::from_waker(&noop_waker); let this = self; pin_mut!(this); match this.poll(&mut cx) { Poll::Ready(x) => Some(x), _ => None, } } } futures-util-0.3.30/src/future/future/remote_handle.rs000064400000000000000000000102021046102023000211410ustar 00000000000000use { crate::future::{CatchUnwind, FutureExt}, futures_channel::oneshot::{self, Receiver, Sender}, futures_core::{ future::Future, ready, task::{Context, Poll}, }, pin_project_lite::pin_project, std::{ any::Any, fmt, panic::{self, AssertUnwindSafe}, pin::Pin, sync::{ atomic::{AtomicBool, Ordering}, Arc, }, thread, }, }; /// The handle to a remote future returned by /// [`remote_handle`](crate::future::FutureExt::remote_handle). When you drop this, /// the remote future will be woken up to be dropped by the executor. /// /// ## Unwind safety /// /// When the remote future panics, [Remote] will catch the unwind and transfer it to /// the thread where `RemoteHandle` is being awaited. This is good for the common /// case where [Remote] is spawned on a threadpool. It is unlikely that other code /// in the executor working thread shares mutable data with the spawned future and we /// preserve the executor from losing its working threads. /// /// If you run the future locally and send the handle of to be awaited elsewhere, you /// must be careful with regard to unwind safety because the thread in which the future /// is polled will keep running after the panic and the thread running the [RemoteHandle] /// will unwind. #[must_use = "dropping a remote handle cancels the underlying future"] #[derive(Debug)] #[cfg_attr(docsrs, doc(cfg(feature = "channel")))] pub struct RemoteHandle { rx: Receiver>, keep_running: Arc, } impl RemoteHandle { /// Drops this handle *without* canceling the underlying future. /// /// This method can be used if you want to drop the handle, but let the /// execution continue. pub fn forget(self) { self.keep_running.store(true, Ordering::SeqCst); } } impl Future for RemoteHandle { type Output = T; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { match ready!(self.rx.poll_unpin(cx)) { Ok(Ok(output)) => Poll::Ready(output), // the remote future panicked. Ok(Err(e)) => panic::resume_unwind(e), // The oneshot sender was dropped. Err(e) => panic::resume_unwind(Box::new(e)), } } } type SendMsg = Result<::Output, Box<(dyn Any + Send + 'static)>>; pin_project! { /// A future which sends its output to the corresponding `RemoteHandle`. /// Created by [`remote_handle`](crate::future::FutureExt::remote_handle). #[must_use = "futures do nothing unless you `.await` or poll them"] #[cfg_attr(docsrs, doc(cfg(feature = "channel")))] pub struct Remote { tx: Option>>, keep_running: Arc, #[pin] future: CatchUnwind>, } } impl fmt::Debug for Remote { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Remote").field(&self.future).finish() } } impl Future for Remote { type Output = (); fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { let this = self.project(); if this.tx.as_mut().unwrap().poll_canceled(cx).is_ready() && !this.keep_running.load(Ordering::SeqCst) { // Cancelled, bail out return Poll::Ready(()); } let output = ready!(this.future.poll(cx)); // if the receiving end has gone away then that's ok, we just ignore the // send error here. drop(this.tx.take().unwrap().send(output)); Poll::Ready(()) } } pub(super) fn remote_handle(future: Fut) -> (Remote, RemoteHandle) { let (tx, rx) = oneshot::channel(); let keep_running = Arc::new(AtomicBool::new(false)); // Unwind Safety: See the docs for RemoteHandle. let wrapped = Remote { future: AssertUnwindSafe(future).catch_unwind(), tx: Some(tx), keep_running: keep_running.clone(), }; (wrapped, RemoteHandle { rx, keep_running }) } futures-util-0.3.30/src/future/future/shared.rs000064400000000000000000000277341046102023000176230ustar 00000000000000use crate::task::{waker_ref, ArcWake}; use futures_core::future::{FusedFuture, Future}; use futures_core::task::{Context, Poll, Waker}; use slab::Slab; use std::cell::UnsafeCell; use std::fmt; use std::hash::Hasher; use std::pin::Pin; use std::ptr; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering::{Acquire, SeqCst}; use std::sync::{Arc, Mutex, Weak}; /// Future for the [`shared`](super::FutureExt::shared) method. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Shared { inner: Option>>, waker_key: usize, } struct Inner { future_or_output: UnsafeCell>, notifier: Arc, } struct Notifier { state: AtomicUsize, wakers: Mutex>>>, } /// A weak reference to a [`Shared`] that can be upgraded much like an `Arc`. pub struct WeakShared(Weak>); impl Clone for WeakShared { fn clone(&self) -> Self { Self(self.0.clone()) } } impl fmt::Debug for Shared { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Shared") .field("inner", &self.inner) .field("waker_key", &self.waker_key) .finish() } } impl fmt::Debug for Inner { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Inner").finish() } } impl fmt::Debug for WeakShared { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("WeakShared").finish() } } enum FutureOrOutput { Future(Fut), Output(Fut::Output), } unsafe impl Send for Inner where Fut: Future + Send, Fut::Output: Send + Sync, { } unsafe impl Sync for Inner where Fut: Future + Send, Fut::Output: Send + Sync, { } const IDLE: usize = 0; const POLLING: usize = 1; const COMPLETE: usize = 2; const POISONED: usize = 3; const NULL_WAKER_KEY: usize = usize::max_value(); impl Shared { pub(super) fn new(future: Fut) -> Self { let inner = Inner { future_or_output: UnsafeCell::new(FutureOrOutput::Future(future)), notifier: Arc::new(Notifier { state: AtomicUsize::new(IDLE), wakers: Mutex::new(Some(Slab::new())), }), }; Self { inner: Some(Arc::new(inner)), waker_key: NULL_WAKER_KEY } } } impl Shared where Fut: Future, { /// Returns [`Some`] containing a reference to this [`Shared`]'s output if /// it has already been computed by a clone or [`None`] if it hasn't been /// computed yet or this [`Shared`] already returned its output from /// [`poll`](Future::poll). pub fn peek(&self) -> Option<&Fut::Output> { if let Some(inner) = self.inner.as_ref() { match inner.notifier.state.load(SeqCst) { COMPLETE => unsafe { return Some(inner.output()) }, POISONED => panic!("inner future panicked during poll"), _ => {} } } None } /// Creates a new [`WeakShared`] for this [`Shared`]. /// /// Returns [`None`] if it has already been polled to completion. pub fn downgrade(&self) -> Option> { if let Some(inner) = self.inner.as_ref() { return Some(WeakShared(Arc::downgrade(inner))); } None } /// Gets the number of strong pointers to this allocation. /// /// Returns [`None`] if it has already been polled to completion. /// /// # Safety /// /// This method by itself is safe, but using it correctly requires extra care. Another thread /// can change the strong count at any time, including potentially between calling this method /// and acting on the result. #[allow(clippy::unnecessary_safety_doc)] pub fn strong_count(&self) -> Option { self.inner.as_ref().map(|arc| Arc::strong_count(arc)) } /// Gets the number of weak pointers to this allocation. /// /// Returns [`None`] if it has already been polled to completion. /// /// # Safety /// /// This method by itself is safe, but using it correctly requires extra care. Another thread /// can change the weak count at any time, including potentially between calling this method /// and acting on the result. #[allow(clippy::unnecessary_safety_doc)] pub fn weak_count(&self) -> Option { self.inner.as_ref().map(|arc| Arc::weak_count(arc)) } /// Hashes the internal state of this `Shared` in a way that's compatible with `ptr_eq`. pub fn ptr_hash(&self, state: &mut H) { match self.inner.as_ref() { Some(arc) => { state.write_u8(1); ptr::hash(Arc::as_ptr(arc), state); } None => { state.write_u8(0); } } } /// Returns `true` if the two `Shared`s point to the same future (in a vein similar to /// `Arc::ptr_eq`). /// /// Returns `false` if either `Shared` has terminated. pub fn ptr_eq(&self, rhs: &Self) -> bool { let lhs = match self.inner.as_ref() { Some(lhs) => lhs, None => return false, }; let rhs = match rhs.inner.as_ref() { Some(rhs) => rhs, None => return false, }; Arc::ptr_eq(lhs, rhs) } } impl Inner where Fut: Future, { /// Safety: callers must first ensure that `self.inner.state` /// is `COMPLETE` unsafe fn output(&self) -> &Fut::Output { match &*self.future_or_output.get() { FutureOrOutput::Output(ref item) => item, FutureOrOutput::Future(_) => unreachable!(), } } } impl Inner where Fut: Future, Fut::Output: Clone, { /// Registers the current task to receive a wakeup when we are awoken. fn record_waker(&self, waker_key: &mut usize, cx: &mut Context<'_>) { let mut wakers_guard = self.notifier.wakers.lock().unwrap(); let wakers = match wakers_guard.as_mut() { Some(wakers) => wakers, None => return, }; let new_waker = cx.waker(); if *waker_key == NULL_WAKER_KEY { *waker_key = wakers.insert(Some(new_waker.clone())); } else { match wakers[*waker_key] { Some(ref old_waker) if new_waker.will_wake(old_waker) => {} // Could use clone_from here, but Waker doesn't specialize it. ref mut slot => *slot = Some(new_waker.clone()), } } debug_assert!(*waker_key != NULL_WAKER_KEY); } /// Safety: callers must first ensure that `inner.state` /// is `COMPLETE` unsafe fn take_or_clone_output(self: Arc) -> Fut::Output { match Arc::try_unwrap(self) { Ok(inner) => match inner.future_or_output.into_inner() { FutureOrOutput::Output(item) => item, FutureOrOutput::Future(_) => unreachable!(), }, Err(inner) => inner.output().clone(), } } } impl FusedFuture for Shared where Fut: Future, Fut::Output: Clone, { fn is_terminated(&self) -> bool { self.inner.is_none() } } impl Future for Shared where Fut: Future, Fut::Output: Clone, { type Output = Fut::Output; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = &mut *self; let inner = this.inner.take().expect("Shared future polled again after completion"); // Fast path for when the wrapped future has already completed if inner.notifier.state.load(Acquire) == COMPLETE { // Safety: We're in the COMPLETE state return unsafe { Poll::Ready(inner.take_or_clone_output()) }; } inner.record_waker(&mut this.waker_key, cx); match inner .notifier .state .compare_exchange(IDLE, POLLING, SeqCst, SeqCst) .unwrap_or_else(|x| x) { IDLE => { // Lock acquired, fall through } POLLING => { // Another task is currently polling, at this point we just want // to ensure that the waker for this task is registered this.inner = Some(inner); return Poll::Pending; } COMPLETE => { // Safety: We're in the COMPLETE state return unsafe { Poll::Ready(inner.take_or_clone_output()) }; } POISONED => panic!("inner future panicked during poll"), _ => unreachable!(), } let waker = waker_ref(&inner.notifier); let mut cx = Context::from_waker(&waker); struct Reset<'a> { state: &'a AtomicUsize, did_not_panic: bool, } impl Drop for Reset<'_> { fn drop(&mut self) { if !self.did_not_panic { self.state.store(POISONED, SeqCst); } } } let mut reset = Reset { state: &inner.notifier.state, did_not_panic: false }; let output = { let future = unsafe { match &mut *inner.future_or_output.get() { FutureOrOutput::Future(fut) => Pin::new_unchecked(fut), _ => unreachable!(), } }; let poll_result = future.poll(&mut cx); reset.did_not_panic = true; match poll_result { Poll::Pending => { if inner.notifier.state.compare_exchange(POLLING, IDLE, SeqCst, SeqCst).is_ok() { // Success drop(reset); this.inner = Some(inner); return Poll::Pending; } else { unreachable!() } } Poll::Ready(output) => output, } }; unsafe { *inner.future_or_output.get() = FutureOrOutput::Output(output); } inner.notifier.state.store(COMPLETE, SeqCst); // Wake all tasks and drop the slab let mut wakers_guard = inner.notifier.wakers.lock().unwrap(); let mut wakers = wakers_guard.take().unwrap(); for waker in wakers.drain().flatten() { waker.wake(); } drop(reset); // Make borrow checker happy drop(wakers_guard); // Safety: We're in the COMPLETE state unsafe { Poll::Ready(inner.take_or_clone_output()) } } } impl Clone for Shared where Fut: Future, { fn clone(&self) -> Self { Self { inner: self.inner.clone(), waker_key: NULL_WAKER_KEY } } } impl Drop for Shared where Fut: Future, { fn drop(&mut self) { if self.waker_key != NULL_WAKER_KEY { if let Some(ref inner) = self.inner { if let Ok(mut wakers) = inner.notifier.wakers.lock() { if let Some(wakers) = wakers.as_mut() { wakers.remove(self.waker_key); } } } } } } impl ArcWake for Notifier { fn wake_by_ref(arc_self: &Arc) { let wakers = &mut *arc_self.wakers.lock().unwrap(); if let Some(wakers) = wakers.as_mut() { for (_key, opt_waker) in wakers { if let Some(waker) = opt_waker.take() { waker.wake(); } } } } } impl WeakShared { /// Attempts to upgrade this [`WeakShared`] into a [`Shared`]. /// /// Returns [`None`] if all clones of the [`Shared`] have been dropped or polled /// to completion. pub fn upgrade(&self) -> Option> { Some(Shared { inner: Some(self.0.upgrade()?), waker_key: NULL_WAKER_KEY }) } } futures-util-0.3.30/src/future/join.rs000064400000000000000000000125661046102023000157770ustar 00000000000000#![allow(non_snake_case)] use super::assert_future; use crate::future::{maybe_done, MaybeDone}; use core::fmt; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; macro_rules! generate { ($( $(#[$doc:meta])* ($Join:ident, <$($Fut:ident),*>), )*) => ($( pin_project! { $(#[$doc])* #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct $Join<$($Fut: Future),*> { $(#[pin] $Fut: MaybeDone<$Fut>,)* } } impl<$($Fut),*> fmt::Debug for $Join<$($Fut),*> where $( $Fut: Future + fmt::Debug, $Fut::Output: fmt::Debug, )* { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct(stringify!($Join)) $(.field(stringify!($Fut), &self.$Fut))* .finish() } } impl<$($Fut: Future),*> $Join<$($Fut),*> { fn new($($Fut: $Fut),*) -> Self { Self { $($Fut: maybe_done($Fut)),* } } } impl<$($Fut: Future),*> Future for $Join<$($Fut),*> { type Output = ($($Fut::Output),*); fn poll( self: Pin<&mut Self>, cx: &mut Context<'_> ) -> Poll { let mut all_done = true; let mut futures = self.project(); $( all_done &= futures.$Fut.as_mut().poll(cx).is_ready(); )* if all_done { Poll::Ready(($(futures.$Fut.take_output().unwrap()), *)) } else { Poll::Pending } } } impl<$($Fut: FusedFuture),*> FusedFuture for $Join<$($Fut),*> { fn is_terminated(&self) -> bool { $( self.$Fut.is_terminated() ) && * } } )*) } generate! { /// Future for the [`join`](join()) function. (Join, ), /// Future for the [`join3`] function. (Join3, ), /// Future for the [`join4`] function. (Join4, ), /// Future for the [`join5`] function. (Join5, ), } /// Joins the result of two futures, waiting for them both to complete. /// /// This function will return a new future which awaits both futures to /// complete. The returned future will finish with a tuple of both results. /// /// Note that this function consumes the passed futures and returns a /// wrapped version of it. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// /// let a = async { 1 }; /// let b = async { 2 }; /// let pair = future::join(a, b); /// /// assert_eq!(pair.await, (1, 2)); /// # }); /// ``` pub fn join(future1: Fut1, future2: Fut2) -> Join where Fut1: Future, Fut2: Future, { let f = Join::new(future1, future2); assert_future::<(Fut1::Output, Fut2::Output), _>(f) } /// Same as [`join`](join()), but with more futures. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// /// let a = async { 1 }; /// let b = async { 2 }; /// let c = async { 3 }; /// let tuple = future::join3(a, b, c); /// /// assert_eq!(tuple.await, (1, 2, 3)); /// # }); /// ``` pub fn join3( future1: Fut1, future2: Fut2, future3: Fut3, ) -> Join3 where Fut1: Future, Fut2: Future, Fut3: Future, { let f = Join3::new(future1, future2, future3); assert_future::<(Fut1::Output, Fut2::Output, Fut3::Output), _>(f) } /// Same as [`join`](join()), but with more futures. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// /// let a = async { 1 }; /// let b = async { 2 }; /// let c = async { 3 }; /// let d = async { 4 }; /// let tuple = future::join4(a, b, c, d); /// /// assert_eq!(tuple.await, (1, 2, 3, 4)); /// # }); /// ``` pub fn join4( future1: Fut1, future2: Fut2, future3: Fut3, future4: Fut4, ) -> Join4 where Fut1: Future, Fut2: Future, Fut3: Future, Fut4: Future, { let f = Join4::new(future1, future2, future3, future4); assert_future::<(Fut1::Output, Fut2::Output, Fut3::Output, Fut4::Output), _>(f) } /// Same as [`join`](join()), but with more futures. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// /// let a = async { 1 }; /// let b = async { 2 }; /// let c = async { 3 }; /// let d = async { 4 }; /// let e = async { 5 }; /// let tuple = future::join5(a, b, c, d, e); /// /// assert_eq!(tuple.await, (1, 2, 3, 4, 5)); /// # }); /// ``` pub fn join5( future1: Fut1, future2: Fut2, future3: Fut3, future4: Fut4, future5: Fut5, ) -> Join5 where Fut1: Future, Fut2: Future, Fut3: Future, Fut4: Future, Fut5: Future, { let f = Join5::new(future1, future2, future3, future4, future5); assert_future::<(Fut1::Output, Fut2::Output, Fut3::Output, Fut4::Output, Fut5::Output), _>(f) } futures-util-0.3.30/src/future/join_all.rs000064400000000000000000000121331046102023000166150ustar 00000000000000//! Definition of the `JoinAll` combinator, waiting for all of a list of futures //! to finish. use alloc::boxed::Box; use alloc::vec::Vec; use core::fmt; use core::future::Future; use core::iter::FromIterator; use core::mem; use core::pin::Pin; use core::task::{Context, Poll}; use super::{assert_future, MaybeDone}; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] use crate::stream::{Collect, FuturesOrdered, StreamExt}; pub(crate) fn iter_pin_mut(slice: Pin<&mut [T]>) -> impl Iterator> { // Safety: `std` _could_ make this unsound if it were to decide Pin's // invariants aren't required to transmit through slices. Otherwise this has // the same safety as a normal field pin projection. unsafe { slice.get_unchecked_mut() }.iter_mut().map(|t| unsafe { Pin::new_unchecked(t) }) } #[must_use = "futures do nothing unless you `.await` or poll them"] /// Future for the [`join_all`] function. pub struct JoinAll where F: Future, { kind: JoinAllKind, } #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] pub(crate) const SMALL: usize = 30; enum JoinAllKind where F: Future, { Small { elems: Pin]>>, }, #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] Big { fut: Collect, Vec>, }, } impl fmt::Debug for JoinAll where F: Future + fmt::Debug, F::Output: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { JoinAllKind::Small { ref elems } => { f.debug_struct("JoinAll").field("elems", elems).finish() } #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] JoinAllKind::Big { ref fut, .. } => fmt::Debug::fmt(fut, f), } } } /// Creates a future which represents a collection of the outputs of the futures /// given. /// /// The returned future will drive execution for all of its underlying futures, /// collecting the results into a destination `Vec` in the same order as they /// were provided. /// /// This function is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. /// /// # See Also /// /// `join_all` will switch to the more powerful [`FuturesOrdered`] for performance /// reasons if the number of futures is large. You may want to look into using it or /// its counterpart [`FuturesUnordered`][crate::stream::FuturesUnordered] directly. /// /// Some examples for additional functionality provided by these are: /// /// * Adding new futures to the set even after it has been started. /// /// * Only polling the specific futures that have been woken. In cases where /// you have a lot of futures this will result in much more efficient polling. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::join_all; /// /// async fn foo(i: u32) -> u32 { i } /// /// let futures = vec![foo(1), foo(2), foo(3)]; /// /// assert_eq!(join_all(futures).await, [1, 2, 3]); /// # }); /// ``` pub fn join_all(iter: I) -> JoinAll where I: IntoIterator, I::Item: Future, { let iter = iter.into_iter(); #[cfg(target_os = "none")] #[cfg_attr(target_os = "none", cfg(not(target_has_atomic = "ptr")))] { let kind = JoinAllKind::Small { elems: iter.map(MaybeDone::Future).collect::>().into() }; assert_future::::Output>, _>(JoinAll { kind }) } #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] { let kind = match iter.size_hint().1 { Some(max) if max <= SMALL => JoinAllKind::Small { elems: iter.map(MaybeDone::Future).collect::>().into(), }, _ => JoinAllKind::Big { fut: iter.collect::>().collect() }, }; assert_future::::Output>, _>(JoinAll { kind }) } } impl Future for JoinAll where F: Future, { type Output = Vec; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { match &mut self.kind { JoinAllKind::Small { elems } => { let mut all_done = true; for elem in iter_pin_mut(elems.as_mut()) { if elem.poll(cx).is_pending() { all_done = false; } } if all_done { let mut elems = mem::replace(elems, Box::pin([])); let result = iter_pin_mut(elems.as_mut()).map(|e| e.take_output().unwrap()).collect(); Poll::Ready(result) } else { Poll::Pending } } #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] JoinAllKind::Big { fut } => Pin::new(fut).poll(cx), } } } impl FromIterator for JoinAll { fn from_iter>(iter: T) -> Self { join_all(iter) } } futures-util-0.3.30/src/future/lazy.rs000064400000000000000000000025111046102023000160040ustar 00000000000000use super::assert_future; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::task::{Context, Poll}; /// Future for the [`lazy`] function. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Lazy { f: Option, } // safe because we never generate `Pin<&mut F>` impl Unpin for Lazy {} /// Creates a new future that allows delayed execution of a closure. /// /// The provided closure is only run once the future is polled. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// /// let a = future::lazy(|_| 1); /// assert_eq!(a.await, 1); /// /// let b = future::lazy(|_| -> i32 { /// panic!("oh no!") /// }); /// drop(b); // closure is never run /// # }); /// ``` pub fn lazy(f: F) -> Lazy where F: FnOnce(&mut Context<'_>) -> R, { assert_future::(Lazy { f: Some(f) }) } impl FusedFuture for Lazy where F: FnOnce(&mut Context<'_>) -> R, { fn is_terminated(&self) -> bool { self.f.is_none() } } impl Future for Lazy where F: FnOnce(&mut Context<'_>) -> R, { type Output = R; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Poll::Ready((self.f.take().expect("Lazy polled after completion"))(cx)) } } futures-util-0.3.30/src/future/maybe_done.rs000064400000000000000000000061421046102023000171330ustar 00000000000000//! Definition of the MaybeDone combinator use super::assert_future; use core::mem; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; use futures_core::task::{Context, Poll}; /// A future that may have completed. /// /// This is created by the [`maybe_done()`] function. #[derive(Debug)] pub enum MaybeDone { /// A not-yet-completed future Future(/* #[pin] */ Fut), /// The output of the completed future Done(Fut::Output), /// The empty variant after the result of a [`MaybeDone`] has been /// taken using the [`take_output`](MaybeDone::take_output) method. Gone, } impl Unpin for MaybeDone {} /// Wraps a future into a `MaybeDone` /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// use futures::pin_mut; /// /// let future = future::maybe_done(async { 5 }); /// pin_mut!(future); /// assert_eq!(future.as_mut().take_output(), None); /// let () = future.as_mut().await; /// assert_eq!(future.as_mut().take_output(), Some(5)); /// assert_eq!(future.as_mut().take_output(), None); /// # }); /// ``` pub fn maybe_done(future: Fut) -> MaybeDone { assert_future::<(), _>(MaybeDone::Future(future)) } impl MaybeDone { /// Returns an [`Option`] containing a mutable reference to the output of the future. /// The output of this method will be [`Some`] if and only if the inner /// future has been completed and [`take_output`](MaybeDone::take_output) /// has not yet been called. #[inline] pub fn output_mut(self: Pin<&mut Self>) -> Option<&mut Fut::Output> { unsafe { match self.get_unchecked_mut() { MaybeDone::Done(res) => Some(res), _ => None, } } } /// Attempt to take the output of a `MaybeDone` without driving it /// towards completion. #[inline] pub fn take_output(self: Pin<&mut Self>) -> Option { match &*self { Self::Done(_) => {} Self::Future(_) | Self::Gone => return None, } unsafe { match mem::replace(self.get_unchecked_mut(), Self::Gone) { MaybeDone::Done(output) => Some(output), _ => unreachable!(), } } } } impl FusedFuture for MaybeDone { fn is_terminated(&self) -> bool { match self { Self::Future(_) => false, Self::Done(_) | Self::Gone => true, } } } impl Future for MaybeDone { type Output = (); fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { unsafe { match self.as_mut().get_unchecked_mut() { MaybeDone::Future(f) => { let res = ready!(Pin::new_unchecked(f).poll(cx)); self.set(Self::Done(res)); } MaybeDone::Done(_) => {} MaybeDone::Gone => panic!("MaybeDone polled after value taken"), } } Poll::Ready(()) } } futures-util-0.3.30/src/future/mod.rs000064400000000000000000000067671046102023000156250ustar 00000000000000//! Asynchronous values. //! //! This module contains: //! //! - The [`Future`] trait. //! - The [`FutureExt`] and [`TryFutureExt`] trait, which provides adapters for //! chaining and composing futures. //! - Top-level future combinators like [`lazy`](lazy()) which creates a future //! from a closure that defines its return value, and [`ready`](ready()), //! which constructs a future with an immediate defined value. #[doc(no_inline)] pub use core::future::Future; #[cfg(feature = "alloc")] pub use futures_core::future::{BoxFuture, LocalBoxFuture}; pub use futures_core::future::{FusedFuture, TryFuture}; pub use futures_task::{FutureObj, LocalFutureObj, UnsafeFutureObj}; // Extension traits and combinators #[allow(clippy::module_inception)] mod future; pub use self::future::{ Flatten, Fuse, FutureExt, Inspect, IntoStream, Map, MapInto, NeverError, Then, UnitError, }; #[deprecated(note = "This is now an alias for [Flatten](Flatten)")] pub use self::future::FlattenStream; #[cfg(feature = "std")] pub use self::future::CatchUnwind; #[cfg(feature = "channel")] #[cfg_attr(docsrs, doc(cfg(feature = "channel")))] #[cfg(feature = "std")] pub use self::future::{Remote, RemoteHandle}; #[cfg(feature = "std")] pub use self::future::{Shared, WeakShared}; mod try_future; pub use self::try_future::{ AndThen, ErrInto, InspectErr, InspectOk, IntoFuture, MapErr, MapOk, MapOkOrElse, OkInto, OrElse, TryFlatten, TryFlattenStream, TryFutureExt, UnwrapOrElse, }; #[cfg(feature = "sink")] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] pub use self::try_future::FlattenSink; // Primitive futures mod lazy; pub use self::lazy::{lazy, Lazy}; mod pending; pub use self::pending::{pending, Pending}; mod maybe_done; pub use self::maybe_done::{maybe_done, MaybeDone}; mod try_maybe_done; pub use self::try_maybe_done::{try_maybe_done, TryMaybeDone}; mod option; pub use self::option::OptionFuture; mod poll_fn; pub use self::poll_fn::{poll_fn, PollFn}; mod poll_immediate; pub use self::poll_immediate::{poll_immediate, PollImmediate}; mod ready; pub use self::ready::{err, ok, ready, Ready}; mod join; pub use self::join::{join, join3, join4, join5, Join, Join3, Join4, Join5}; #[cfg(feature = "alloc")] mod join_all; #[cfg(feature = "alloc")] pub use self::join_all::{join_all, JoinAll}; mod select; pub use self::select::{select, Select}; #[cfg(feature = "alloc")] mod select_all; #[cfg(feature = "alloc")] pub use self::select_all::{select_all, SelectAll}; mod try_join; pub use self::try_join::{ try_join, try_join3, try_join4, try_join5, TryJoin, TryJoin3, TryJoin4, TryJoin5, }; #[cfg(feature = "alloc")] mod try_join_all; #[cfg(feature = "alloc")] pub use self::try_join_all::{try_join_all, TryJoinAll}; mod try_select; pub use self::try_select::{try_select, TrySelect}; #[cfg(feature = "alloc")] mod select_ok; #[cfg(feature = "alloc")] pub use self::select_ok::{select_ok, SelectOk}; mod either; pub use self::either::Either; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] mod abortable; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] pub use crate::abortable::{AbortHandle, AbortRegistration, Abortable, Aborted}; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] pub use abortable::abortable; // Just a helper function to ensure the futures we're returning all have the // right implementations. pub(crate) fn assert_future(future: F) -> F where F: Future, { future } futures-util-0.3.30/src/future/option.rs000064400000000000000000000031761046102023000163450ustar 00000000000000//! Definition of the `Option` (optional step) combinator use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// A future representing a value which may or may not be present. /// /// Created by the [`From`] implementation for [`Option`](std::option::Option). /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::OptionFuture; /// /// let mut a: OptionFuture<_> = Some(async { 123 }).into(); /// assert_eq!(a.await, Some(123)); /// /// a = None.into(); /// assert_eq!(a.await, None); /// # }); /// ``` #[derive(Debug, Clone)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct OptionFuture { #[pin] inner: Option, } } impl Default for OptionFuture { fn default() -> Self { Self { inner: None } } } impl Future for OptionFuture { type Output = Option; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { match self.project().inner.as_pin_mut() { Some(x) => x.poll(cx).map(Some), None => Poll::Ready(None), } } } impl FusedFuture for OptionFuture { fn is_terminated(&self) -> bool { match &self.inner { Some(x) => x.is_terminated(), None => true, } } } impl From> for OptionFuture { fn from(option: Option) -> Self { Self { inner: option } } } futures-util-0.3.30/src/future/pending.rs000064400000000000000000000023211046102023000164500ustar 00000000000000use super::assert_future; use core::marker; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::task::{Context, Poll}; /// Future for the [`pending()`] function. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Pending { _data: marker::PhantomData, } impl FusedFuture for Pending { fn is_terminated(&self) -> bool { true } } /// Creates a future which never resolves, representing a computation that never /// finishes. /// /// The returned future will forever return [`Poll::Pending`]. /// /// # Examples /// /// ```ignore /// # futures::executor::block_on(async { /// use futures::future; /// /// let future = future::pending(); /// let () = future.await; /// unreachable!(); /// # }); /// ``` #[cfg_attr(docsrs, doc(alias = "never"))] pub fn pending() -> Pending { assert_future::(Pending { _data: marker::PhantomData }) } impl Future for Pending { type Output = T; fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll { Poll::Pending } } impl Unpin for Pending {} impl Clone for Pending { fn clone(&self) -> Self { pending() } } futures-util-0.3.30/src/future/poll_fn.rs000064400000000000000000000025551046102023000164660ustar 00000000000000//! Definition of the `PollFn` adapter combinator use super::assert_future; use core::fmt; use core::pin::Pin; use futures_core::future::Future; use futures_core::task::{Context, Poll}; /// Future for the [`poll_fn`] function. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct PollFn { f: F, } impl Unpin for PollFn {} /// Creates a new future wrapping around a function returning [`Poll`]. /// /// Polling the returned future delegates to the wrapped function. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::poll_fn; /// use futures::task::{Context, Poll}; /// /// fn read_line(_cx: &mut Context<'_>) -> Poll { /// Poll::Ready("Hello, World!".into()) /// } /// /// let read_future = poll_fn(read_line); /// assert_eq!(read_future.await, "Hello, World!".to_owned()); /// # }); /// ``` pub fn poll_fn(f: F) -> PollFn where F: FnMut(&mut Context<'_>) -> Poll, { assert_future::(PollFn { f }) } impl fmt::Debug for PollFn { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("PollFn").finish() } } impl Future for PollFn where F: FnMut(&mut Context<'_>) -> Poll, { type Output = T; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { (&mut self.f)(cx) } } futures-util-0.3.30/src/future/poll_immediate.rs000064400000000000000000000076651046102023000200300ustar 00000000000000use super::assert_future; use core::pin::Pin; use futures_core::task::{Context, Poll}; use futures_core::{FusedFuture, Future, Stream}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`poll_immediate`](poll_immediate()) function. /// /// It will never return [Poll::Pending](core::task::Poll::Pending) #[derive(Debug, Clone)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct PollImmediate { #[pin] future: Option } } impl Future for PollImmediate where F: Future, { type Output = Option; #[inline] fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); let inner = this.future.as_mut().as_pin_mut().expect("PollImmediate polled after completion"); match inner.poll(cx) { Poll::Ready(t) => { this.future.set(None); Poll::Ready(Some(t)) } Poll::Pending => Poll::Ready(None), } } } impl FusedFuture for PollImmediate { fn is_terminated(&self) -> bool { self.future.is_none() } } /// A [Stream](crate::stream::Stream) implementation that can be polled repeatedly until the future is done. /// The stream will never return [Poll::Pending](core::task::Poll::Pending) /// so polling it in a tight loop is worse than using a blocking synchronous function. /// ``` /// # futures::executor::block_on(async { /// use futures::task::Poll; /// use futures::{StreamExt, future, pin_mut}; /// use future::FusedFuture; /// /// let f = async { 1_u32 }; /// pin_mut!(f); /// let mut r = future::poll_immediate(f); /// assert_eq!(r.next().await, Some(Poll::Ready(1))); /// /// let f = async {futures::pending!(); 42_u8}; /// pin_mut!(f); /// let mut p = future::poll_immediate(f); /// assert_eq!(p.next().await, Some(Poll::Pending)); /// assert!(!p.is_terminated()); /// assert_eq!(p.next().await, Some(Poll::Ready(42))); /// assert!(p.is_terminated()); /// assert_eq!(p.next().await, None); /// # }); /// ``` impl Stream for PollImmediate where F: Future, { type Item = Poll; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); match this.future.as_mut().as_pin_mut() { // inner is gone, so we can signal that the stream is closed. None => Poll::Ready(None), Some(fut) => Poll::Ready(Some(fut.poll(cx).map(|t| { this.future.set(None); t }))), } } } /// Creates a future that is immediately ready with an Option of a value. /// Specifically this means that [poll](core::future::Future::poll()) always returns [Poll::Ready](core::task::Poll::Ready). /// /// # Caution /// /// When consuming the future by this function, note the following: /// /// - This function does not guarantee that the future will run to completion, so it is generally incompatible with passing the non-cancellation-safe future by value. /// - Even if the future is cancellation-safe, creating and dropping new futures frequently may lead to performance problems. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// /// let r = future::poll_immediate(async { 1_u32 }); /// assert_eq!(r.await, Some(1)); /// /// let p = future::poll_immediate(future::pending::()); /// assert_eq!(p.await, None); /// # }); /// ``` /// /// ### Reusing a future /// /// ``` /// # futures::executor::block_on(async { /// use futures::{future, pin_mut}; /// let f = async {futures::pending!(); 42_u8}; /// pin_mut!(f); /// assert_eq!(None, future::poll_immediate(&mut f).await); /// assert_eq!(42, f.await); /// # }); /// ``` pub fn poll_immediate(f: F) -> PollImmediate { assert_future::, PollImmediate>(PollImmediate { future: Some(f) }) } futures-util-0.3.30/src/future/ready.rs000064400000000000000000000034541046102023000161400ustar 00000000000000use super::assert_future; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::task::{Context, Poll}; /// Future for the [`ready`](ready()) function. #[derive(Debug, Clone)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Ready(Option); impl Ready { /// Unwraps the value from this immediately ready future. #[inline] pub fn into_inner(mut self) -> T { self.0.take().unwrap() } } impl Unpin for Ready {} impl FusedFuture for Ready { fn is_terminated(&self) -> bool { self.0.is_none() } } impl Future for Ready { type Output = T; #[inline] fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll { Poll::Ready(self.0.take().expect("Ready polled after completion")) } } /// Creates a future that is immediately ready with a value. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// /// let a = future::ready(1); /// assert_eq!(a.await, 1); /// # }); /// ``` pub fn ready(t: T) -> Ready { assert_future::(Ready(Some(t))) } /// Create a future that is immediately ready with a success value. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// /// let a = future::ok::(1); /// assert_eq!(a.await, Ok(1)); /// # }); /// ``` pub fn ok(t: T) -> Ready> { Ready(Some(Ok(t))) } /// Create a future that is immediately ready with an error value. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// /// let a = future::err::(1); /// assert_eq!(a.await, Err(1)); /// # }); /// ``` pub fn err(err: E) -> Ready> { Ready(Some(Err(err))) } futures-util-0.3.30/src/future/select.rs000064400000000000000000000076401046102023000163140ustar 00000000000000use super::assert_future; use crate::future::{Either, FutureExt}; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::task::{Context, Poll}; /// Future for the [`select()`] function. #[must_use = "futures do nothing unless you `.await` or poll them"] #[derive(Debug)] pub struct Select { inner: Option<(A, B)>, } impl Unpin for Select {} /// Waits for either one of two differently-typed futures to complete. /// /// This function will return a new future which awaits for either one of both /// futures to complete. The returned future will finish with both the value /// resolved and a future representing the completion of the other work. /// /// Note that this function consumes the receiving futures and returns a /// wrapped version of them. /// /// Also note that if both this and the second future have the same /// output type you can use the `Either::factor_first` method to /// conveniently extract out the value at the end. /// /// # Examples /// /// A simple example /// /// ``` /// # futures::executor::block_on(async { /// use futures::{ /// pin_mut, /// future::Either, /// future::self, /// }; /// /// // These two futures have different types even though their outputs have the same type. /// let future1 = async { /// future::pending::<()>().await; // will never finish /// 1 /// }; /// let future2 = async { /// future::ready(2).await /// }; /// /// // 'select' requires Future + Unpin bounds /// pin_mut!(future1); /// pin_mut!(future2); /// /// let value = match future::select(future1, future2).await { /// Either::Left((value1, _)) => value1, // `value1` is resolved from `future1` /// // `_` represents `future2` /// Either::Right((value2, _)) => value2, // `value2` is resolved from `future2` /// // `_` represents `future1` /// }; /// /// assert!(value == 2); /// # }); /// ``` /// /// A more complex example /// /// ``` /// use futures::future::{self, Either, Future, FutureExt}; /// /// // A poor-man's join implemented on top of select /// /// fn join(a: A, b: B) -> impl Future /// where A: Future + Unpin, /// B: Future + Unpin, /// { /// future::select(a, b).then(|either| { /// match either { /// Either::Left((x, b)) => b.map(move |y| (x, y)).left_future(), /// Either::Right((y, a)) => a.map(move |x| (x, y)).right_future(), /// } /// }) /// } /// ``` pub fn select(future1: A, future2: B) -> Select where A: Future + Unpin, B: Future + Unpin, { assert_future::, _>(Select { inner: Some((future1, future2)), }) } impl Future for Select where A: Future + Unpin, B: Future + Unpin, { type Output = Either<(A::Output, B), (B::Output, A)>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { /// When compiled with `-C opt-level=z`, this function will help the compiler eliminate the `None` branch, where /// `Option::unwrap` does not. #[inline(always)] fn unwrap_option(value: Option) -> T { match value { None => unreachable!(), Some(value) => value, } } let (a, b) = self.inner.as_mut().expect("cannot poll Select twice"); if let Poll::Ready(val) = a.poll_unpin(cx) { return Poll::Ready(Either::Left((val, unwrap_option(self.inner.take()).1))); } if let Poll::Ready(val) = b.poll_unpin(cx) { return Poll::Ready(Either::Right((val, unwrap_option(self.inner.take()).0))); } Poll::Pending } } impl FusedFuture for Select where A: Future + Unpin, B: Future + Unpin, { fn is_terminated(&self) -> bool { self.inner.is_none() } } futures-util-0.3.30/src/future/select_all.rs000064400000000000000000000046451046102023000171460ustar 00000000000000use super::assert_future; use crate::future::FutureExt; use alloc::vec::Vec; use core::iter::FromIterator; use core::mem; use core::pin::Pin; use futures_core::future::Future; use futures_core::task::{Context, Poll}; /// Future for the [`select_all`] function. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct SelectAll { inner: Vec, } impl Unpin for SelectAll {} /// Creates a new future which will select over a list of futures. /// /// The returned future will wait for any future within `iter` to be ready. Upon /// completion the item resolved will be returned, along with the index of the /// future that was ready and the list of all the remaining futures. /// /// There are no guarantees provided on the order of the list with the remaining /// futures. They might be swapped around, reversed, or completely random. /// /// This function is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. /// /// # Panics /// /// This function will panic if the iterator specified contains no items. pub fn select_all(iter: I) -> SelectAll where I: IntoIterator, I::Item: Future + Unpin, { let ret = SelectAll { inner: iter.into_iter().collect() }; assert!(!ret.inner.is_empty()); assert_future::<(::Output, usize, Vec), _>(ret) } impl SelectAll { /// Consumes this combinator, returning the underlying futures. pub fn into_inner(self) -> Vec { self.inner } } impl Future for SelectAll { type Output = (Fut::Output, usize, Vec); fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let item = self.inner.iter_mut().enumerate().find_map(|(i, f)| match f.poll_unpin(cx) { Poll::Pending => None, Poll::Ready(e) => Some((i, e)), }); match item { Some((idx, res)) => { #[allow(clippy::let_underscore_future)] let _ = self.inner.swap_remove(idx); let rest = mem::take(&mut self.inner); Poll::Ready((res, idx, rest)) } None => Poll::Pending, } } } impl FromIterator for SelectAll { fn from_iter>(iter: T) -> Self { select_all(iter) } } futures-util-0.3.30/src/future/select_ok.rs000064400000000000000000000057671046102023000170150ustar 00000000000000use super::assert_future; use crate::future::TryFutureExt; use alloc::vec::Vec; use core::iter::FromIterator; use core::mem; use core::pin::Pin; use futures_core::future::{Future, TryFuture}; use futures_core::task::{Context, Poll}; /// Future for the [`select_ok`] function. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct SelectOk { inner: Vec, } impl Unpin for SelectOk {} /// Creates a new future which will select the first successful future over a list of futures. /// /// The returned future will wait for any future within `iter` to be ready and Ok. Unlike /// `select_all`, this will only return the first successful completion, or the last /// failure. This is useful in contexts where any success is desired and failures /// are ignored, unless all the futures fail. /// /// This function is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. /// /// # Panics /// /// This function will panic if the iterator specified contains no items. pub fn select_ok(iter: I) -> SelectOk where I: IntoIterator, I::Item: TryFuture + Unpin, { let ret = SelectOk { inner: iter.into_iter().collect() }; assert!(!ret.inner.is_empty(), "iterator provided to select_ok was empty"); assert_future::< Result<(::Ok, Vec), ::Error>, _, >(ret) } impl Future for SelectOk { type Output = Result<(Fut::Ok, Vec), Fut::Error>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { // loop until we've either exhausted all errors, a success was hit, or nothing is ready loop { let item = self.inner.iter_mut().enumerate().find_map(|(i, f)| match f.try_poll_unpin(cx) { Poll::Pending => None, Poll::Ready(e) => Some((i, e)), }); match item { Some((idx, res)) => { // always remove Ok or Err, if it's not the last Err continue looping drop(self.inner.remove(idx)); match res { Ok(e) => { let rest = mem::take(&mut self.inner); return Poll::Ready(Ok((e, rest))); } Err(e) => { if self.inner.is_empty() { return Poll::Ready(Err(e)); } } } } None => { // based on the filter above, nothing is ready, return return Poll::Pending; } } } } } impl FromIterator for SelectOk { fn from_iter>(iter: T) -> Self { select_ok(iter) } } futures-util-0.3.30/src/future/try_future/into_future.rs000064400000000000000000000016531046102023000216060ustar 00000000000000use core::pin::Pin; use futures_core::future::{FusedFuture, Future, TryFuture}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`into_future`](super::TryFutureExt::into_future) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct IntoFuture { #[pin] future: Fut, } } impl IntoFuture { #[inline] pub(crate) fn new(future: Fut) -> Self { Self { future } } } impl FusedFuture for IntoFuture { fn is_terminated(&self) -> bool { self.future.is_terminated() } } impl Future for IntoFuture { type Output = Result; #[inline] fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { self.project().future.try_poll(cx) } } futures-util-0.3.30/src/future/try_future/mod.rs000064400000000000000000000524551046102023000200300ustar 00000000000000//! Futures //! //! This module contains a number of functions for working with `Future`s, //! including the `FutureExt` trait which adds methods to `Future` types. #[cfg(feature = "compat")] use crate::compat::Compat; use core::pin::Pin; use futures_core::{ future::TryFuture, stream::TryStream, task::{Context, Poll}, }; #[cfg(feature = "sink")] use futures_sink::Sink; use crate::fns::{ inspect_err_fn, inspect_ok_fn, into_fn, map_err_fn, map_ok_fn, map_ok_or_else_fn, unwrap_or_else_fn, InspectErrFn, InspectOkFn, IntoFn, MapErrFn, MapOkFn, MapOkOrElseFn, UnwrapOrElseFn, }; use crate::future::{assert_future, Inspect, Map}; use crate::stream::assert_stream; // Combinators mod into_future; mod try_flatten; mod try_flatten_err; delegate_all!( /// Future for the [`try_flatten`](TryFutureExt::try_flatten) method. TryFlatten( try_flatten::TryFlatten ): Debug + Future + FusedFuture + New[|x: Fut1| try_flatten::TryFlatten::new(x)] ); delegate_all!( /// Future for the [`try_flatten_err`](TryFutureExt::try_flatten_err) method. TryFlattenErr( try_flatten_err::TryFlattenErr ): Debug + Future + FusedFuture + New[|x: Fut1| try_flatten_err::TryFlattenErr::new(x)] ); delegate_all!( /// Future for the [`try_flatten_stream`](TryFutureExt::try_flatten_stream) method. TryFlattenStream( try_flatten::TryFlatten ): Debug + Sink + Stream + FusedStream + New[|x: Fut| try_flatten::TryFlatten::new(x)] where Fut: TryFuture ); #[cfg(feature = "sink")] delegate_all!( /// Sink for the [`flatten_sink`](TryFutureExt::flatten_sink) method. #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] FlattenSink( try_flatten::TryFlatten ): Debug + Sink + Stream + FusedStream + New[|x: Fut| try_flatten::TryFlatten::new(x)] ); delegate_all!( /// Future for the [`and_then`](TryFutureExt::and_then) method. AndThen( TryFlatten, Fut2> ): Debug + Future + FusedFuture + New[|x: Fut1, f: F| TryFlatten::new(MapOk::new(x, f))] ); delegate_all!( /// Future for the [`or_else`](TryFutureExt::or_else) method. OrElse( TryFlattenErr, Fut2> ): Debug + Future + FusedFuture + New[|x: Fut1, f: F| TryFlattenErr::new(MapErr::new(x, f))] ); delegate_all!( /// Future for the [`err_into`](TryFutureExt::err_into) method. ErrInto( MapErr> ): Debug + Future + FusedFuture + New[|x: Fut| MapErr::new(x, into_fn())] ); delegate_all!( /// Future for the [`ok_into`](TryFutureExt::ok_into) method. OkInto( MapOk> ): Debug + Future + FusedFuture + New[|x: Fut| MapOk::new(x, into_fn())] ); delegate_all!( /// Future for the [`inspect_ok`](super::TryFutureExt::inspect_ok) method. InspectOk( Inspect, InspectOkFn> ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Inspect::new(IntoFuture::new(x), inspect_ok_fn(f))] ); delegate_all!( /// Future for the [`inspect_err`](super::TryFutureExt::inspect_err) method. InspectErr( Inspect, InspectErrFn> ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Inspect::new(IntoFuture::new(x), inspect_err_fn(f))] ); #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::into_future::IntoFuture; delegate_all!( /// Future for the [`map_ok`](TryFutureExt::map_ok) method. MapOk( Map, MapOkFn> ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(IntoFuture::new(x), map_ok_fn(f))] ); delegate_all!( /// Future for the [`map_err`](TryFutureExt::map_err) method. MapErr( Map, MapErrFn> ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(IntoFuture::new(x), map_err_fn(f))] ); delegate_all!( /// Future for the [`map_ok_or_else`](TryFutureExt::map_ok_or_else) method. MapOkOrElse( Map, MapOkOrElseFn> ): Debug + Future + FusedFuture + New[|x: Fut, f: F, g: G| Map::new(IntoFuture::new(x), map_ok_or_else_fn(f, g))] ); delegate_all!( /// Future for the [`unwrap_or_else`](TryFutureExt::unwrap_or_else) method. UnwrapOrElse( Map, UnwrapOrElseFn> ): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(IntoFuture::new(x), unwrap_or_else_fn(f))] ); impl TryFutureExt for Fut {} /// Adapters specific to [`Result`]-returning futures pub trait TryFutureExt: TryFuture { /// Flattens the execution of this future when the successful result of this /// future is a [`Sink`]. /// /// This can be useful when sink initialization is deferred, and it is /// convenient to work with that sink as if the sink was available at the /// call site. /// /// Note that this function consumes this future and returns a wrapped /// version of it. /// /// # Examples /// /// ``` /// use futures::future::{Future, TryFutureExt}; /// use futures::sink::Sink; /// # use futures::channel::mpsc::{self, SendError}; /// # type T = i32; /// # type E = SendError; /// /// fn make_sink_async() -> impl Future, /// E, /// >> { // ... } /// # let (tx, _rx) = mpsc::unbounded::(); /// # futures::future::ready(Ok(tx)) /// # } /// fn take_sink(sink: impl Sink) { /* ... */ } /// /// let fut = make_sink_async(); /// take_sink(fut.flatten_sink()) /// ``` #[cfg(feature = "sink")] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] fn flatten_sink(self) -> FlattenSink where Self::Ok: Sink, Self: Sized, { crate::sink::assert_sink::(FlattenSink::new(self)) } /// Maps this future's success value to a different value. /// /// This method can be used to change the [`Ok`](TryFuture::Ok) type of the /// future into a different type. It is similar to the [`Result::map`] /// method. You can use this method to chain along a computation once the /// future has been resolved. /// /// The provided closure `f` will only be called if this future is resolved /// to an [`Ok`]. If it resolves to an [`Err`], panics, or is dropped, then /// the provided closure will never be invoked. /// /// Note that this method consumes the future it is called on and returns a /// wrapped version of it. /// /// # Examples /// /// ``` /// use futures::future::TryFutureExt; /// /// # futures::executor::block_on(async { /// let future = async { Ok::(1) }; /// let future = future.map_ok(|x| x + 3); /// assert_eq!(future.await, Ok(4)); /// # }); /// ``` /// /// Calling [`map_ok`](TryFutureExt::map_ok) on an errored future has no /// effect: /// /// ``` /// use futures::future::TryFutureExt; /// /// # futures::executor::block_on(async { /// let future = async { Err::(1) }; /// let future = future.map_ok(|x| x + 3); /// assert_eq!(future.await, Err(1)); /// # }); /// ``` fn map_ok(self, f: F) -> MapOk where F: FnOnce(Self::Ok) -> T, Self: Sized, { assert_future::, _>(MapOk::new(self, f)) } /// Maps this future's success value to a different value, and permits for error handling resulting in the same type. /// /// This method can be used to coalesce your [`Ok`](TryFuture::Ok) type and [`Error`](TryFuture::Error) into another type, /// where that type is the same for both outcomes. /// /// The provided closure `f` will only be called if this future is resolved /// to an [`Ok`]. If it resolves to an [`Err`], panics, or is dropped, then /// the provided closure will never be invoked. /// /// The provided closure `e` will only be called if this future is resolved /// to an [`Err`]. If it resolves to an [`Ok`], panics, or is dropped, then /// the provided closure will never be invoked. /// /// Note that this method consumes the future it is called on and returns a /// wrapped version of it. /// /// # Examples /// /// ``` /// use futures::future::TryFutureExt; /// /// # futures::executor::block_on(async { /// let future = async { Ok::(5) }; /// let future = future.map_ok_or_else(|x| x * 2, |x| x + 3); /// assert_eq!(future.await, 8); /// /// let future = async { Err::(5) }; /// let future = future.map_ok_or_else(|x| x * 2, |x| x + 3); /// assert_eq!(future.await, 10); /// # }); /// ``` /// fn map_ok_or_else(self, e: E, f: F) -> MapOkOrElse where F: FnOnce(Self::Ok) -> T, E: FnOnce(Self::Error) -> T, Self: Sized, { assert_future::(MapOkOrElse::new(self, f, e)) } /// Maps this future's error value to a different value. /// /// This method can be used to change the [`Error`](TryFuture::Error) type /// of the future into a different type. It is similar to the /// [`Result::map_err`] method. You can use this method for example to /// ensure that futures have the same [`Error`](TryFuture::Error) type when /// using [`select!`] or [`join!`]. /// /// The provided closure `f` will only be called if this future is resolved /// to an [`Err`]. If it resolves to an [`Ok`], panics, or is dropped, then /// the provided closure will never be invoked. /// /// Note that this method consumes the future it is called on and returns a /// wrapped version of it. /// /// # Examples /// /// ``` /// use futures::future::TryFutureExt; /// /// # futures::executor::block_on(async { /// let future = async { Err::(1) }; /// let future = future.map_err(|x| x + 3); /// assert_eq!(future.await, Err(4)); /// # }); /// ``` /// /// Calling [`map_err`](TryFutureExt::map_err) on a successful future has /// no effect: /// /// ``` /// use futures::future::TryFutureExt; /// /// # futures::executor::block_on(async { /// let future = async { Ok::(1) }; /// let future = future.map_err(|x| x + 3); /// assert_eq!(future.await, Ok(1)); /// # }); /// ``` /// /// [`join!`]: crate::join /// [`select!`]: crate::select fn map_err(self, f: F) -> MapErr where F: FnOnce(Self::Error) -> E, Self: Sized, { assert_future::, _>(MapErr::new(self, f)) } /// Maps this future's [`Error`](TryFuture::Error) to a new error type /// using the [`Into`](std::convert::Into) trait. /// /// This method does for futures what the `?`-operator does for /// [`Result`]: It lets the compiler infer the type of the resulting /// error. Just as [`map_err`](TryFutureExt::map_err), this is useful for /// example to ensure that futures have the same [`Error`](TryFuture::Error) /// type when using [`select!`] or [`join!`]. /// /// Note that this method consumes the future it is called on and returns a /// wrapped version of it. /// /// # Examples /// /// ``` /// use futures::future::TryFutureExt; /// /// # futures::executor::block_on(async { /// let future_err_u8 = async { Err::<(), u8>(1) }; /// let future_err_i32 = future_err_u8.err_into::(); /// # }); /// ``` /// /// [`join!`]: crate::join /// [`select!`]: crate::select fn err_into(self) -> ErrInto where Self: Sized, Self::Error: Into, { assert_future::, _>(ErrInto::new(self)) } /// Maps this future's [`Ok`](TryFuture::Ok) to a new type /// using the [`Into`](std::convert::Into) trait. fn ok_into(self) -> OkInto where Self: Sized, Self::Ok: Into, { assert_future::, _>(OkInto::new(self)) } /// Executes another future after this one resolves successfully. The /// success value is passed to a closure to create this subsequent future. /// /// The provided closure `f` will only be called if this future is resolved /// to an [`Ok`]. If this future resolves to an [`Err`], panics, or is /// dropped, then the provided closure will never be invoked. The /// [`Error`](TryFuture::Error) type of this future and the future /// returned by `f` have to match. /// /// Note that this method consumes the future it is called on and returns a /// wrapped version of it. /// /// # Examples /// /// ``` /// use futures::future::TryFutureExt; /// /// # futures::executor::block_on(async { /// let future = async { Ok::(1) }; /// let future = future.and_then(|x| async move { Ok::(x + 3) }); /// assert_eq!(future.await, Ok(4)); /// # }); /// ``` /// /// Calling [`and_then`](TryFutureExt::and_then) on an errored future has no /// effect: /// /// ``` /// use futures::future::TryFutureExt; /// /// # futures::executor::block_on(async { /// let future = async { Err::(1) }; /// let future = future.and_then(|x| async move { Err::(x + 3) }); /// assert_eq!(future.await, Err(1)); /// # }); /// ``` fn and_then(self, f: F) -> AndThen where F: FnOnce(Self::Ok) -> Fut, Fut: TryFuture, Self: Sized, { assert_future::, _>(AndThen::new(self, f)) } /// Executes another future if this one resolves to an error. The /// error value is passed to a closure to create this subsequent future. /// /// The provided closure `f` will only be called if this future is resolved /// to an [`Err`]. If this future resolves to an [`Ok`], panics, or is /// dropped, then the provided closure will never be invoked. The /// [`Ok`](TryFuture::Ok) type of this future and the future returned by `f` /// have to match. /// /// Note that this method consumes the future it is called on and returns a /// wrapped version of it. /// /// # Examples /// /// ``` /// use futures::future::TryFutureExt; /// /// # futures::executor::block_on(async { /// let future = async { Err::(1) }; /// let future = future.or_else(|x| async move { Err::(x + 3) }); /// assert_eq!(future.await, Err(4)); /// # }); /// ``` /// /// Calling [`or_else`](TryFutureExt::or_else) on a successful future has /// no effect: /// /// ``` /// use futures::future::TryFutureExt; /// /// # futures::executor::block_on(async { /// let future = async { Ok::(1) }; /// let future = future.or_else(|x| async move { Ok::(x + 3) }); /// assert_eq!(future.await, Ok(1)); /// # }); /// ``` fn or_else(self, f: F) -> OrElse where F: FnOnce(Self::Error) -> Fut, Fut: TryFuture, Self: Sized, { assert_future::, _>(OrElse::new(self, f)) } /// Do something with the success value of a future before passing it on. /// /// When using futures, you'll often chain several of them together. While /// working on such code, you might want to check out what's happening at /// various parts in the pipeline, without consuming the intermediate /// value. To do that, insert a call to `inspect_ok`. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::TryFutureExt; /// /// let future = async { Ok::<_, ()>(1) }; /// let new_future = future.inspect_ok(|&x| println!("about to resolve: {}", x)); /// assert_eq!(new_future.await, Ok(1)); /// # }); /// ``` fn inspect_ok(self, f: F) -> InspectOk where F: FnOnce(&Self::Ok), Self: Sized, { assert_future::, _>(InspectOk::new(self, f)) } /// Do something with the error value of a future before passing it on. /// /// When using futures, you'll often chain several of them together. While /// working on such code, you might want to check out what's happening at /// various parts in the pipeline, without consuming the intermediate /// value. To do that, insert a call to `inspect_err`. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::TryFutureExt; /// /// let future = async { Err::<(), _>(1) }; /// let new_future = future.inspect_err(|&x| println!("about to error: {}", x)); /// assert_eq!(new_future.await, Err(1)); /// # }); /// ``` fn inspect_err(self, f: F) -> InspectErr where F: FnOnce(&Self::Error), Self: Sized, { assert_future::, _>(InspectErr::new(self, f)) } /// Flatten the execution of this future when the successful result of this /// future is another future. /// /// This is equivalent to `future.and_then(|x| x)`. fn try_flatten(self) -> TryFlatten where Self::Ok: TryFuture, Self: Sized, { assert_future::::Ok, Self::Error>, _>(TryFlatten::new(self)) } /// Flatten the execution of this future when the successful result of this /// future is a stream. /// /// This can be useful when stream initialization is deferred, and it is /// convenient to work with that stream as if stream was available at the /// call site. /// /// Note that this function consumes this future and returns a wrapped /// version of it. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::TryFutureExt; /// use futures::stream::{self, TryStreamExt}; /// /// let stream_items = vec![17, 18, 19].into_iter().map(Ok); /// let future_of_a_stream = async { Ok::<_, ()>(stream::iter(stream_items)) }; /// /// let stream = future_of_a_stream.try_flatten_stream(); /// let list = stream.try_collect::>().await; /// assert_eq!(list, Ok(vec![17, 18, 19])); /// # }); /// ``` fn try_flatten_stream(self) -> TryFlattenStream where Self::Ok: TryStream, Self: Sized, { assert_stream::::Ok, Self::Error>, _>(TryFlattenStream::new( self, )) } /// Unwraps this future's output, producing a future with this future's /// [`Ok`](TryFuture::Ok) type as its /// [`Output`](std::future::Future::Output) type. /// /// If this future is resolved successfully, the returned future will /// contain the original future's success value as output. Otherwise, the /// closure `f` is called with the error value to produce an alternate /// success value. /// /// This method is similar to the [`Result::unwrap_or_else`] method. /// /// # Examples /// /// ``` /// use futures::future::TryFutureExt; /// /// # futures::executor::block_on(async { /// let future = async { Err::<(), &str>("Boom!") }; /// let future = future.unwrap_or_else(|_| ()); /// assert_eq!(future.await, ()); /// # }); /// ``` fn unwrap_or_else(self, f: F) -> UnwrapOrElse where Self: Sized, F: FnOnce(Self::Error) -> Self::Ok, { assert_future::(UnwrapOrElse::new(self, f)) } /// Wraps a [`TryFuture`] into a future compatible with libraries using /// futures 0.1 future definitions. Requires the `compat` feature to enable. #[cfg(feature = "compat")] #[cfg_attr(docsrs, doc(cfg(feature = "compat")))] fn compat(self) -> Compat where Self: Sized + Unpin, { Compat::new(self) } /// Wraps a [`TryFuture`] into a type that implements /// [`Future`](std::future::Future). /// /// [`TryFuture`]s currently do not implement the /// [`Future`](std::future::Future) trait due to limitations of the /// compiler. /// /// # Examples /// /// ``` /// use futures::future::{Future, TryFuture, TryFutureExt}; /// /// # type T = i32; /// # type E = (); /// fn make_try_future() -> impl TryFuture { // ... } /// # async { Ok::(1) } /// # } /// fn take_future(future: impl Future>) { /* ... */ } /// /// take_future(make_try_future().into_future()); /// ``` fn into_future(self) -> IntoFuture where Self: Sized, { assert_future::, _>(IntoFuture::new(self)) } /// A convenience method for calling [`TryFuture::try_poll`] on [`Unpin`] /// future types. fn try_poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll> where Self: Unpin, { Pin::new(self).try_poll(cx) } } futures-util-0.3.30/src/future/try_future/try_flatten.rs000064400000000000000000000116651046102023000216020ustar 00000000000000use core::pin::Pin; use futures_core::future::{FusedFuture, Future, TryFuture}; use futures_core::ready; use futures_core::stream::{FusedStream, Stream, TryStream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { #[project = TryFlattenProj] #[derive(Debug)] pub enum TryFlatten { First { #[pin] f: Fut1 }, Second { #[pin] f: Fut2 }, Empty, } } impl TryFlatten { pub(crate) fn new(future: Fut1) -> Self { Self::First { f: future } } } impl FusedFuture for TryFlatten where Fut: TryFuture, Fut::Ok: TryFuture, { fn is_terminated(&self) -> bool { match self { Self::Empty => true, _ => false, } } } impl Future for TryFlatten where Fut: TryFuture, Fut::Ok: TryFuture, { type Output = Result<::Ok, Fut::Error>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Poll::Ready(loop { match self.as_mut().project() { TryFlattenProj::First { f } => match ready!(f.try_poll(cx)) { Ok(f) => self.set(Self::Second { f }), Err(e) => { self.set(Self::Empty); break Err(e); } }, TryFlattenProj::Second { f } => { let output = ready!(f.try_poll(cx)); self.set(Self::Empty); break output; } TryFlattenProj::Empty => panic!("TryFlatten polled after completion"), } }) } } impl FusedStream for TryFlatten where Fut: TryFuture, Fut::Ok: TryStream, { fn is_terminated(&self) -> bool { match self { Self::Empty => true, _ => false, } } } impl Stream for TryFlatten where Fut: TryFuture, Fut::Ok: TryStream, { type Item = Result<::Ok, Fut::Error>; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Poll::Ready(loop { match self.as_mut().project() { TryFlattenProj::First { f } => match ready!(f.try_poll(cx)) { Ok(f) => self.set(Self::Second { f }), Err(e) => { self.set(Self::Empty); break Some(Err(e)); } }, TryFlattenProj::Second { f } => { let output = ready!(f.try_poll_next(cx)); if output.is_none() { self.set(Self::Empty); } break output; } TryFlattenProj::Empty => break None, } }) } } #[cfg(feature = "sink")] impl Sink for TryFlatten where Fut: TryFuture, Fut::Ok: Sink, { type Error = Fut::Error; fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Poll::Ready(loop { match self.as_mut().project() { TryFlattenProj::First { f } => match ready!(f.try_poll(cx)) { Ok(f) => self.set(Self::Second { f }), Err(e) => { self.set(Self::Empty); break Err(e); } }, TryFlattenProj::Second { f } => { break ready!(f.poll_ready(cx)); } TryFlattenProj::Empty => panic!("poll_ready called after eof"), } }) } fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { match self.project() { TryFlattenProj::First { .. } => panic!("poll_ready not called first"), TryFlattenProj::Second { f } => f.start_send(item), TryFlattenProj::Empty => panic!("start_send called after eof"), } } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match self.project() { TryFlattenProj::First { .. } => Poll::Ready(Ok(())), TryFlattenProj::Second { f } => f.poll_flush(cx), TryFlattenProj::Empty => panic!("poll_flush called after eof"), } } fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let res = match self.as_mut().project() { TryFlattenProj::Second { f } => f.poll_close(cx), _ => Poll::Ready(Ok(())), }; if res.is_ready() { self.set(Self::Empty); } res } } futures-util-0.3.30/src/future/try_future/try_flatten_err.rs000064400000000000000000000033341046102023000224440ustar 00000000000000use core::pin::Pin; use futures_core::future::{FusedFuture, Future, TryFuture}; use futures_core::ready; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { #[project = TryFlattenErrProj] #[derive(Debug)] pub enum TryFlattenErr { First { #[pin] f: Fut1 }, Second { #[pin] f: Fut2 }, Empty, } } impl TryFlattenErr { pub(crate) fn new(future: Fut1) -> Self { Self::First { f: future } } } impl FusedFuture for TryFlattenErr where Fut: TryFuture, Fut::Error: TryFuture, { fn is_terminated(&self) -> bool { match self { Self::Empty => true, _ => false, } } } impl Future for TryFlattenErr where Fut: TryFuture, Fut::Error: TryFuture, { type Output = Result::Error>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Poll::Ready(loop { match self.as_mut().project() { TryFlattenErrProj::First { f } => match ready!(f.try_poll(cx)) { Err(f) => self.set(Self::Second { f }), Ok(e) => { self.set(Self::Empty); break Ok(e); } }, TryFlattenErrProj::Second { f } => { let output = ready!(f.try_poll(cx)); self.set(Self::Empty); break output; } TryFlattenErrProj::Empty => panic!("TryFlattenErr polled after completion"), } }) } } futures-util-0.3.30/src/future/try_join.rs000064400000000000000000000164241046102023000166720ustar 00000000000000#![allow(non_snake_case)] use crate::future::{assert_future, try_maybe_done, TryMaybeDone}; use core::fmt; use core::pin::Pin; use futures_core::future::{Future, TryFuture}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; macro_rules! generate { ($( $(#[$doc:meta])* ($Join:ident, ), )*) => ($( pin_project! { $(#[$doc])* #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct $Join { #[pin] Fut1: TryMaybeDone, $(#[pin] $Fut: TryMaybeDone<$Fut>,)* } } impl fmt::Debug for $Join where Fut1: TryFuture + fmt::Debug, Fut1::Ok: fmt::Debug, Fut1::Error: fmt::Debug, $( $Fut: TryFuture + fmt::Debug, $Fut::Ok: fmt::Debug, $Fut::Error: fmt::Debug, )* { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct(stringify!($Join)) .field("Fut1", &self.Fut1) $(.field(stringify!($Fut), &self.$Fut))* .finish() } } impl $Join where Fut1: TryFuture, $( $Fut: TryFuture ),* { fn new(Fut1: Fut1, $($Fut: $Fut),*) -> Self { Self { Fut1: try_maybe_done(Fut1), $($Fut: try_maybe_done($Fut)),* } } } impl Future for $Join where Fut1: TryFuture, $( $Fut: TryFuture ),* { type Output = Result<(Fut1::Ok, $($Fut::Ok),*), Fut1::Error>; fn poll( self: Pin<&mut Self>, cx: &mut Context<'_> ) -> Poll { let mut all_done = true; let mut futures = self.project(); all_done &= futures.Fut1.as_mut().poll(cx)?.is_ready(); $( all_done &= futures.$Fut.as_mut().poll(cx)?.is_ready(); )* if all_done { Poll::Ready(Ok(( futures.Fut1.take_output().unwrap(), $( futures.$Fut.take_output().unwrap() ),* ))) } else { Poll::Pending } } } )*) } generate! { /// Future for the [`try_join`](try_join()) function. (TryJoin, ), /// Future for the [`try_join3`] function. (TryJoin3, ), /// Future for the [`try_join4`] function. (TryJoin4, ), /// Future for the [`try_join5`] function. (TryJoin5, ), } /// Joins the result of two futures, waiting for them both to complete or /// for one to produce an error. /// /// This function will return a new future which awaits both futures to /// complete. If successful, the returned future will finish with a tuple of /// both results. If unsuccessful, it will complete with the first error /// encountered. /// /// Note that this function consumes the passed futures and returns a /// wrapped version of it. /// /// # Examples /// /// When used on multiple futures that return [`Ok`], `try_join` will return /// [`Ok`] of a tuple of the values: /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// /// let a = future::ready(Ok::(1)); /// let b = future::ready(Ok::(2)); /// let pair = future::try_join(a, b); /// /// assert_eq!(pair.await, Ok((1, 2))); /// # }); /// ``` /// /// If one of the futures resolves to an error, `try_join` will return /// that error: /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// /// let a = future::ready(Ok::(1)); /// let b = future::ready(Err::(2)); /// let pair = future::try_join(a, b); /// /// assert_eq!(pair.await, Err(2)); /// # }); /// ``` pub fn try_join(future1: Fut1, future2: Fut2) -> TryJoin where Fut1: TryFuture, Fut2: TryFuture, { assert_future::, _>(TryJoin::new(future1, future2)) } /// Same as [`try_join`](try_join()), but with more futures. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// /// let a = future::ready(Ok::(1)); /// let b = future::ready(Ok::(2)); /// let c = future::ready(Ok::(3)); /// let tuple = future::try_join3(a, b, c); /// /// assert_eq!(tuple.await, Ok((1, 2, 3))); /// # }); /// ``` pub fn try_join3( future1: Fut1, future2: Fut2, future3: Fut3, ) -> TryJoin3 where Fut1: TryFuture, Fut2: TryFuture, Fut3: TryFuture, { assert_future::, _>(TryJoin3::new( future1, future2, future3, )) } /// Same as [`try_join`](try_join()), but with more futures. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// /// let a = future::ready(Ok::(1)); /// let b = future::ready(Ok::(2)); /// let c = future::ready(Ok::(3)); /// let d = future::ready(Ok::(4)); /// let tuple = future::try_join4(a, b, c, d); /// /// assert_eq!(tuple.await, Ok((1, 2, 3, 4))); /// # }); /// ``` pub fn try_join4( future1: Fut1, future2: Fut2, future3: Fut3, future4: Fut4, ) -> TryJoin4 where Fut1: TryFuture, Fut2: TryFuture, Fut3: TryFuture, Fut4: TryFuture, { assert_future::, _>( TryJoin4::new(future1, future2, future3, future4), ) } /// Same as [`try_join`](try_join()), but with more futures. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// /// let a = future::ready(Ok::(1)); /// let b = future::ready(Ok::(2)); /// let c = future::ready(Ok::(3)); /// let d = future::ready(Ok::(4)); /// let e = future::ready(Ok::(5)); /// let tuple = future::try_join5(a, b, c, d, e); /// /// assert_eq!(tuple.await, Ok((1, 2, 3, 4, 5))); /// # }); /// ``` pub fn try_join5( future1: Fut1, future2: Fut2, future3: Fut3, future4: Fut4, future5: Fut5, ) -> TryJoin5 where Fut1: TryFuture, Fut2: TryFuture, Fut3: TryFuture, Fut4: TryFuture, Fut5: TryFuture, { assert_future::, _>( TryJoin5::new(future1, future2, future3, future4, future5), ) } futures-util-0.3.30/src/future/try_join_all.rs000064400000000000000000000143431046102023000175200ustar 00000000000000//! Definition of the `TryJoinAll` combinator, waiting for all of a list of //! futures to finish with either success or error. use alloc::boxed::Box; use alloc::vec::Vec; use core::fmt; use core::future::Future; use core::iter::FromIterator; use core::mem; use core::pin::Pin; use core::task::{Context, Poll}; use super::{assert_future, join_all, IntoFuture, TryFuture, TryMaybeDone}; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] use crate::stream::{FuturesOrdered, TryCollect, TryStreamExt}; use crate::TryFutureExt; enum FinalState { Pending, AllDone, Error(E), } /// Future for the [`try_join_all`] function. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct TryJoinAll where F: TryFuture, { kind: TryJoinAllKind, } enum TryJoinAllKind where F: TryFuture, { Small { elems: Pin>]>>, }, #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] Big { fut: TryCollect>, Vec>, }, } impl fmt::Debug for TryJoinAll where F: TryFuture + fmt::Debug, F::Ok: fmt::Debug, F::Error: fmt::Debug, F::Output: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { TryJoinAllKind::Small { ref elems } => { f.debug_struct("TryJoinAll").field("elems", elems).finish() } #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] TryJoinAllKind::Big { ref fut, .. } => fmt::Debug::fmt(fut, f), } } } /// Creates a future which represents either a collection of the results of the /// futures given or an error. /// /// The returned future will drive execution for all of its underlying futures, /// collecting the results into a destination `Vec` in the same order as they /// were provided. /// /// If any future returns an error then all other futures will be canceled and /// an error will be returned immediately. If all futures complete successfully, /// however, then the returned future will succeed with a `Vec` of all the /// successful results. /// /// This function is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. /// /// # See Also /// /// `try_join_all` will switch to the more powerful [`FuturesOrdered`] for performance /// reasons if the number of futures is large. You may want to look into using it or /// it's counterpart [`FuturesUnordered`][crate::stream::FuturesUnordered] directly. /// /// Some examples for additional functionality provided by these are: /// /// * Adding new futures to the set even after it has been started. /// /// * Only polling the specific futures that have been woken. In cases where /// you have a lot of futures this will result in much more efficient polling. /// /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future::{self, try_join_all}; /// /// let futures = vec![ /// future::ok::(1), /// future::ok::(2), /// future::ok::(3), /// ]; /// /// assert_eq!(try_join_all(futures).await, Ok(vec![1, 2, 3])); /// /// let futures = vec![ /// future::ok::(1), /// future::err::(2), /// future::ok::(3), /// ]; /// /// assert_eq!(try_join_all(futures).await, Err(2)); /// # }); /// ``` pub fn try_join_all(iter: I) -> TryJoinAll where I: IntoIterator, I::Item: TryFuture, { let iter = iter.into_iter().map(TryFutureExt::into_future); #[cfg(target_os = "none")] #[cfg_attr(target_os = "none", cfg(not(target_has_atomic = "ptr")))] { let kind = TryJoinAllKind::Small { elems: iter.map(TryMaybeDone::Future).collect::>().into(), }; assert_future::::Ok>, ::Error>, _>( TryJoinAll { kind }, ) } #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] { let kind = match iter.size_hint().1 { Some(max) if max <= join_all::SMALL => TryJoinAllKind::Small { elems: iter.map(TryMaybeDone::Future).collect::>().into(), }, _ => TryJoinAllKind::Big { fut: iter.collect::>().try_collect() }, }; assert_future::::Ok>, ::Error>, _>( TryJoinAll { kind }, ) } } impl Future for TryJoinAll where F: TryFuture, { type Output = Result, F::Error>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { match &mut self.kind { TryJoinAllKind::Small { elems } => { let mut state = FinalState::AllDone; for elem in join_all::iter_pin_mut(elems.as_mut()) { match elem.try_poll(cx) { Poll::Pending => state = FinalState::Pending, Poll::Ready(Ok(())) => {} Poll::Ready(Err(e)) => { state = FinalState::Error(e); break; } } } match state { FinalState::Pending => Poll::Pending, FinalState::AllDone => { let mut elems = mem::replace(elems, Box::pin([])); let results = join_all::iter_pin_mut(elems.as_mut()) .map(|e| e.take_output().unwrap()) .collect(); Poll::Ready(Ok(results)) } FinalState::Error(e) => { let _ = mem::replace(elems, Box::pin([])); Poll::Ready(Err(e)) } } } #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] TryJoinAllKind::Big { fut } => Pin::new(fut).poll(cx), } } } impl FromIterator for TryJoinAll where F: TryFuture, { fn from_iter>(iter: T) -> Self { try_join_all(iter) } } futures-util-0.3.30/src/future/try_maybe_done.rs000064400000000000000000000060211046102023000200250ustar 00000000000000//! Definition of the TryMaybeDone combinator use super::assert_future; use core::mem; use core::pin::Pin; use futures_core::future::{FusedFuture, Future, TryFuture}; use futures_core::ready; use futures_core::task::{Context, Poll}; /// A future that may have completed with an error. /// /// This is created by the [`try_maybe_done()`] function. #[derive(Debug)] pub enum TryMaybeDone { /// A not-yet-completed future Future(/* #[pin] */ Fut), /// The output of the completed future Done(Fut::Ok), /// The empty variant after the result of a [`TryMaybeDone`] has been /// taken using the [`take_output`](TryMaybeDone::take_output) method, /// or if the future returned an error. Gone, } impl Unpin for TryMaybeDone {} /// Wraps a future into a `TryMaybeDone` pub fn try_maybe_done(future: Fut) -> TryMaybeDone { assert_future::, _>(TryMaybeDone::Future(future)) } impl TryMaybeDone { /// Returns an [`Option`] containing a mutable reference to the output of the future. /// The output of this method will be [`Some`] if and only if the inner /// future has completed successfully and [`take_output`](TryMaybeDone::take_output) /// has not yet been called. #[inline] pub fn output_mut(self: Pin<&mut Self>) -> Option<&mut Fut::Ok> { unsafe { match self.get_unchecked_mut() { TryMaybeDone::Done(res) => Some(res), _ => None, } } } /// Attempt to take the output of a `TryMaybeDone` without driving it /// towards completion. #[inline] pub fn take_output(self: Pin<&mut Self>) -> Option { match &*self { Self::Done(_) => {} Self::Future(_) | Self::Gone => return None, } unsafe { match mem::replace(self.get_unchecked_mut(), Self::Gone) { TryMaybeDone::Done(output) => Some(output), _ => unreachable!(), } } } } impl FusedFuture for TryMaybeDone { fn is_terminated(&self) -> bool { match self { Self::Future(_) => false, Self::Done(_) | Self::Gone => true, } } } impl Future for TryMaybeDone { type Output = Result<(), Fut::Error>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { unsafe { match self.as_mut().get_unchecked_mut() { TryMaybeDone::Future(f) => match ready!(Pin::new_unchecked(f).try_poll(cx)) { Ok(res) => self.set(Self::Done(res)), Err(e) => { self.set(Self::Gone); return Poll::Ready(Err(e)); } }, TryMaybeDone::Done(_) => {} TryMaybeDone::Gone => panic!("TryMaybeDone polled after value taken"), } } Poll::Ready(Ok(())) } } futures-util-0.3.30/src/future/try_select.rs000064400000000000000000000062111046102023000172030ustar 00000000000000use crate::future::{Either, TryFutureExt}; use core::pin::Pin; use futures_core::future::{Future, TryFuture}; use futures_core::task::{Context, Poll}; /// Future for the [`try_select()`] function. #[must_use = "futures do nothing unless you `.await` or poll them"] #[derive(Debug)] pub struct TrySelect { inner: Option<(A, B)>, } impl Unpin for TrySelect {} type EitherOk = Either<(::Ok, B), (::Ok, A)>; type EitherErr = Either<(::Error, B), (::Error, A)>; /// Waits for either one of two differently-typed futures to complete. /// /// This function will return a new future which awaits for either one of both /// futures to complete. The returned future will finish with both the value /// resolved and a future representing the completion of the other work. /// /// Note that this function consumes the receiving futures and returns a /// wrapped version of them. /// /// Also note that if both this and the second future have the same /// success/error type you can use the `Either::factor_first` method to /// conveniently extract out the value at the end. /// /// # Examples /// /// ``` /// use futures::future::{self, Either, Future, FutureExt, TryFuture, TryFutureExt}; /// /// // A poor-man's try_join implemented on top of select /// /// fn try_join(a: A, b: B) -> impl TryFuture /// where A: TryFuture + Unpin + 'static, /// B: TryFuture + Unpin + 'static, /// E: 'static, /// { /// future::try_select(a, b).then(|res| -> Box> + Unpin> { /// match res { /// Ok(Either::Left((x, b))) => Box::new(b.map_ok(move |y| (x, y))), /// Ok(Either::Right((y, a))) => Box::new(a.map_ok(move |x| (x, y))), /// Err(Either::Left((e, _))) => Box::new(future::err(e)), /// Err(Either::Right((e, _))) => Box::new(future::err(e)), /// } /// }) /// } /// ``` pub fn try_select(future1: A, future2: B) -> TrySelect where A: TryFuture + Unpin, B: TryFuture + Unpin, { super::assert_future::, EitherErr>, _>(TrySelect { inner: Some((future1, future2)), }) } impl Future for TrySelect where A: TryFuture, B: TryFuture, { type Output = Result, EitherErr>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let (mut a, mut b) = self.inner.take().expect("cannot poll Select twice"); match a.try_poll_unpin(cx) { Poll::Ready(Err(x)) => Poll::Ready(Err(Either::Left((x, b)))), Poll::Ready(Ok(x)) => Poll::Ready(Ok(Either::Left((x, b)))), Poll::Pending => match b.try_poll_unpin(cx) { Poll::Ready(Err(x)) => Poll::Ready(Err(Either::Right((x, a)))), Poll::Ready(Ok(x)) => Poll::Ready(Ok(Either::Right((x, a)))), Poll::Pending => { self.inner = Some((a, b)); Poll::Pending } }, } } } futures-util-0.3.30/src/io/allow_std.rs000064400000000000000000000123271046102023000161200ustar 00000000000000use futures_core::task::{Context, Poll}; use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, SeekFrom}; use std::pin::Pin; use std::{fmt, io}; /// A simple wrapper type which allows types which implement only /// implement `std::io::Read` or `std::io::Write` /// to be used in contexts which expect an `AsyncRead` or `AsyncWrite`. /// /// If these types issue an error with the kind `io::ErrorKind::WouldBlock`, /// it is expected that they will notify the current task on readiness. /// Synchronous `std` types should not issue errors of this kind and /// are safe to use in this context. However, using these types with /// `AllowStdIo` will cause the event loop to block, so they should be used /// with care. #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct AllowStdIo(T); impl Unpin for AllowStdIo {} macro_rules! try_with_interrupt { ($e:expr) => { loop { match $e { Ok(e) => { break e; } Err(ref e) if e.kind() == ::std::io::ErrorKind::Interrupted => { continue; } Err(e) => { return Poll::Ready(Err(e)); } } } }; } impl AllowStdIo { /// Creates a new `AllowStdIo` from an existing IO object. pub fn new(io: T) -> Self { Self(io) } /// Returns a reference to the contained IO object. pub fn get_ref(&self) -> &T { &self.0 } /// Returns a mutable reference to the contained IO object. pub fn get_mut(&mut self) -> &mut T { &mut self.0 } /// Consumes self and returns the contained IO object. pub fn into_inner(self) -> T { self.0 } } impl io::Write for AllowStdIo where T: io::Write, { fn write(&mut self, buf: &[u8]) -> io::Result { self.0.write(buf) } fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { self.0.write_vectored(bufs) } fn flush(&mut self) -> io::Result<()> { self.0.flush() } fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { self.0.write_all(buf) } fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> { self.0.write_fmt(fmt) } } impl AsyncWrite for AllowStdIo where T: io::Write, { fn poll_write( mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &[u8], ) -> Poll> { Poll::Ready(Ok(try_with_interrupt!(self.0.write(buf)))) } fn poll_write_vectored( mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll> { Poll::Ready(Ok(try_with_interrupt!(self.0.write_vectored(bufs)))) } fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { try_with_interrupt!(self.0.flush()); Poll::Ready(Ok(())) } fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.poll_flush(cx) } } impl io::Read for AllowStdIo where T: io::Read, { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.0.read(buf) } fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { self.0.read_vectored(bufs) } fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { self.0.read_to_end(buf) } fn read_to_string(&mut self, buf: &mut String) -> io::Result { self.0.read_to_string(buf) } fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { self.0.read_exact(buf) } } impl AsyncRead for AllowStdIo where T: io::Read, { fn poll_read( mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &mut [u8], ) -> Poll> { Poll::Ready(Ok(try_with_interrupt!(self.0.read(buf)))) } fn poll_read_vectored( mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>], ) -> Poll> { Poll::Ready(Ok(try_with_interrupt!(self.0.read_vectored(bufs)))) } } impl io::Seek for AllowStdIo where T: io::Seek, { fn seek(&mut self, pos: SeekFrom) -> io::Result { self.0.seek(pos) } } impl AsyncSeek for AllowStdIo where T: io::Seek, { fn poll_seek( mut self: Pin<&mut Self>, _: &mut Context<'_>, pos: SeekFrom, ) -> Poll> { Poll::Ready(Ok(try_with_interrupt!(self.0.seek(pos)))) } } impl io::BufRead for AllowStdIo where T: io::BufRead, { fn fill_buf(&mut self) -> io::Result<&[u8]> { self.0.fill_buf() } fn consume(&mut self, amt: usize) { self.0.consume(amt) } } impl AsyncBufRead for AllowStdIo where T: io::BufRead, { fn poll_fill_buf(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { let this: *mut Self = &mut *self as *mut _; Poll::Ready(Ok(try_with_interrupt!(unsafe { &mut *this }.0.fill_buf()))) } fn consume(mut self: Pin<&mut Self>, amt: usize) { self.0.consume(amt) } } futures-util-0.3.30/src/io/buf_reader.rs000064400000000000000000000240751046102023000162310ustar 00000000000000use super::DEFAULT_BUF_SIZE; use futures_core::future::Future; use futures_core::ready; use futures_core::task::{Context, Poll}; use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSliceMut, SeekFrom}; use pin_project_lite::pin_project; use std::io::{self, Read}; use std::pin::Pin; use std::{cmp, fmt}; pin_project! { /// The `BufReader` struct adds buffering to any reader. /// /// It can be excessively inefficient to work directly with a [`AsyncRead`] /// instance. A `BufReader` performs large, infrequent reads on the underlying /// [`AsyncRead`] and maintains an in-memory buffer of the results. /// /// `BufReader` can improve the speed of programs that make *small* and /// *repeated* read calls to the same file or network socket. It does not /// help when reading very large amounts at once, or reading just one or a few /// times. It also provides no advantage when reading from a source that is /// already in memory, like a `Vec`. /// /// When the `BufReader` is dropped, the contents of its buffer will be /// discarded. Creating multiple instances of a `BufReader` on the same /// stream can cause data loss. /// /// [`AsyncRead`]: futures_io::AsyncRead /// // TODO: Examples pub struct BufReader { #[pin] inner: R, buffer: Box<[u8]>, pos: usize, cap: usize, } } impl BufReader { /// Creates a new `BufReader` with a default buffer capacity. The default is currently 8 KB, /// but may change in the future. pub fn new(inner: R) -> Self { Self::with_capacity(DEFAULT_BUF_SIZE, inner) } /// Creates a new `BufReader` with the specified buffer capacity. pub fn with_capacity(capacity: usize, inner: R) -> Self { unsafe { let mut buffer = Vec::with_capacity(capacity); buffer.set_len(capacity); super::initialize(&inner, &mut buffer); Self { inner, buffer: buffer.into_boxed_slice(), pos: 0, cap: 0 } } } delegate_access_inner!(inner, R, ()); /// Returns a reference to the internally buffered data. /// /// Unlike `fill_buf`, this will not attempt to fill the buffer if it is empty. pub fn buffer(&self) -> &[u8] { &self.buffer[self.pos..self.cap] } /// Invalidates all data in the internal buffer. #[inline] fn discard_buffer(self: Pin<&mut Self>) { let this = self.project(); *this.pos = 0; *this.cap = 0; } } impl BufReader { /// Seeks relative to the current position. If the new position lies within the buffer, /// the buffer will not be flushed, allowing for more efficient seeks. /// This method does not return the location of the underlying reader, so the caller /// must track this information themselves if it is required. pub fn seek_relative(self: Pin<&mut Self>, offset: i64) -> SeeKRelative<'_, R> { SeeKRelative { inner: self, offset, first: true } } /// Attempts to seek relative to the current position. If the new position lies within the buffer, /// the buffer will not be flushed, allowing for more efficient seeks. /// This method does not return the location of the underlying reader, so the caller /// must track this information themselves if it is required. pub fn poll_seek_relative( self: Pin<&mut Self>, cx: &mut Context<'_>, offset: i64, ) -> Poll> { let pos = self.pos as u64; if offset < 0 { if let Some(new_pos) = pos.checked_sub((-offset) as u64) { *self.project().pos = new_pos as usize; return Poll::Ready(Ok(())); } } else if let Some(new_pos) = pos.checked_add(offset as u64) { if new_pos <= self.cap as u64 { *self.project().pos = new_pos as usize; return Poll::Ready(Ok(())); } } self.poll_seek(cx, SeekFrom::Current(offset)).map(|res| res.map(|_| ())) } } impl AsyncRead for BufReader { fn poll_read( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll> { // If we don't have any buffered data and we're doing a massive read // (larger than our internal buffer), bypass our internal buffer // entirely. if self.pos == self.cap && buf.len() >= self.buffer.len() { let res = ready!(self.as_mut().project().inner.poll_read(cx, buf)); self.discard_buffer(); return Poll::Ready(res); } let mut rem = ready!(self.as_mut().poll_fill_buf(cx))?; let nread = rem.read(buf)?; self.consume(nread); Poll::Ready(Ok(nread)) } fn poll_read_vectored( mut self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>], ) -> Poll> { let total_len = bufs.iter().map(|b| b.len()).sum::(); if self.pos == self.cap && total_len >= self.buffer.len() { let res = ready!(self.as_mut().project().inner.poll_read_vectored(cx, bufs)); self.discard_buffer(); return Poll::Ready(res); } let mut rem = ready!(self.as_mut().poll_fill_buf(cx))?; let nread = rem.read_vectored(bufs)?; self.consume(nread); Poll::Ready(Ok(nread)) } } impl AsyncBufRead for BufReader { fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); // If we've reached the end of our internal buffer then we need to fetch // some more data from the underlying reader. // Branch using `>=` instead of the more correct `==` // to tell the compiler that the pos..cap slice is always valid. if *this.pos >= *this.cap { debug_assert!(*this.pos == *this.cap); *this.cap = ready!(this.inner.poll_read(cx, this.buffer))?; *this.pos = 0; } Poll::Ready(Ok(&this.buffer[*this.pos..*this.cap])) } fn consume(self: Pin<&mut Self>, amt: usize) { *self.project().pos = cmp::min(self.pos + amt, self.cap); } } impl AsyncWrite for BufReader { delegate_async_write!(inner); } impl fmt::Debug for BufReader { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("BufReader") .field("reader", &self.inner) .field("buffer", &format_args!("{}/{}", self.cap - self.pos, self.buffer.len())) .finish() } } impl AsyncSeek for BufReader { /// Seek to an offset, in bytes, in the underlying reader. /// /// The position used for seeking with `SeekFrom::Current(_)` is the /// position the underlying reader would be at if the `BufReader` had no /// internal buffer. /// /// Seeking always discards the internal buffer, even if the seek position /// would otherwise fall within it. This guarantees that calling /// `.into_inner()` immediately after a seek yields the underlying reader /// at the same position. /// /// To seek without discarding the internal buffer, use /// [`BufReader::seek_relative`](BufReader::seek_relative) or /// [`BufReader::poll_seek_relative`](BufReader::poll_seek_relative). /// /// See [`AsyncSeek`](futures_io::AsyncSeek) for more details. /// /// Note: In the edge case where you're seeking with `SeekFrom::Current(n)` /// where `n` minus the internal buffer length overflows an `i64`, two /// seeks will be performed instead of one. If the second seek returns /// `Err`, the underlying reader will be left at the same position it would /// have if you called `seek` with `SeekFrom::Current(0)`. fn poll_seek( mut self: Pin<&mut Self>, cx: &mut Context<'_>, pos: SeekFrom, ) -> Poll> { let result: u64; if let SeekFrom::Current(n) = pos { let remainder = (self.cap - self.pos) as i64; // it should be safe to assume that remainder fits within an i64 as the alternative // means we managed to allocate 8 exbibytes and that's absurd. // But it's not out of the realm of possibility for some weird underlying reader to // support seeking by i64::min_value() so we need to handle underflow when subtracting // remainder. if let Some(offset) = n.checked_sub(remainder) { result = ready!(self.as_mut().project().inner.poll_seek(cx, SeekFrom::Current(offset)))?; } else { // seek backwards by our remainder, and then by the offset ready!(self.as_mut().project().inner.poll_seek(cx, SeekFrom::Current(-remainder)))?; self.as_mut().discard_buffer(); result = ready!(self.as_mut().project().inner.poll_seek(cx, SeekFrom::Current(n)))?; } } else { // Seeking with Start/End doesn't care about our buffer length. result = ready!(self.as_mut().project().inner.poll_seek(cx, pos))?; } self.discard_buffer(); Poll::Ready(Ok(result)) } } /// Future for the [`BufReader::seek_relative`](self::BufReader::seek_relative) method. #[derive(Debug)] #[must_use = "futures do nothing unless polled"] pub struct SeeKRelative<'a, R> { inner: Pin<&'a mut BufReader>, offset: i64, first: bool, } impl Future for SeeKRelative<'_, R> where R: AsyncRead + AsyncSeek, { type Output = io::Result<()>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let offset = self.offset; if self.first { self.first = false; self.inner.as_mut().poll_seek_relative(cx, offset) } else { self.inner .as_mut() .as_mut() .poll_seek(cx, SeekFrom::Current(offset)) .map(|res| res.map(|_| ())) } } } futures-util-0.3.30/src/io/buf_writer.rs000064400000000000000000000165601046102023000163030ustar 00000000000000use super::DEFAULT_BUF_SIZE; use futures_core::ready; use futures_core::task::{Context, Poll}; use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, SeekFrom}; use pin_project_lite::pin_project; use std::fmt; use std::io::{self, Write}; use std::pin::Pin; use std::ptr; pin_project! { /// Wraps a writer and buffers its output. /// /// It can be excessively inefficient to work directly with something that /// implements [`AsyncWrite`]. A `BufWriter` keeps an in-memory buffer of data and /// writes it to an underlying writer in large, infrequent batches. /// /// `BufWriter` can improve the speed of programs that make *small* and /// *repeated* write calls to the same file or network socket. It does not /// help when writing very large amounts at once, or writing just one or a few /// times. It also provides no advantage when writing to a destination that is /// in memory, like a `Vec`. /// /// When the `BufWriter` is dropped, the contents of its buffer will be /// discarded. Creating multiple instances of a `BufWriter` on the same /// stream can cause data loss. If you need to write out the contents of its /// buffer, you must manually call flush before the writer is dropped. /// /// [`AsyncWrite`]: futures_io::AsyncWrite /// [`flush`]: super::AsyncWriteExt::flush /// // TODO: Examples pub struct BufWriter { #[pin] inner: W, buf: Vec, written: usize, } } impl BufWriter { /// Creates a new `BufWriter` with a default buffer capacity. The default is currently 8 KB, /// but may change in the future. pub fn new(inner: W) -> Self { Self::with_capacity(DEFAULT_BUF_SIZE, inner) } /// Creates a new `BufWriter` with the specified buffer capacity. pub fn with_capacity(cap: usize, inner: W) -> Self { Self { inner, buf: Vec::with_capacity(cap), written: 0 } } pub(super) fn flush_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); let len = this.buf.len(); let mut ret = Ok(()); while *this.written < len { match ready!(this.inner.as_mut().poll_write(cx, &this.buf[*this.written..])) { Ok(0) => { ret = Err(io::Error::new( io::ErrorKind::WriteZero, "failed to write the buffered data", )); break; } Ok(n) => *this.written += n, Err(e) => { ret = Err(e); break; } } } if *this.written > 0 { this.buf.drain(..*this.written); } *this.written = 0; Poll::Ready(ret) } delegate_access_inner!(inner, W, ()); /// Returns a reference to the internally buffered data. pub fn buffer(&self) -> &[u8] { &self.buf } /// Capacity of `buf`. how many chars can be held in buffer pub(super) fn capacity(&self) -> usize { self.buf.capacity() } /// Remaining number of bytes to reach `buf` 's capacity #[inline] pub(super) fn spare_capacity(&self) -> usize { self.buf.capacity() - self.buf.len() } /// Write a byte slice directly into buffer /// /// Will truncate the number of bytes written to `spare_capacity()` so you want to /// calculate the size of your slice to avoid losing bytes /// /// Based on `std::io::BufWriter` pub(super) fn write_to_buf(self: Pin<&mut Self>, buf: &[u8]) -> usize { let available = self.spare_capacity(); let amt_to_buffer = available.min(buf.len()); // SAFETY: `amt_to_buffer` is <= buffer's spare capacity by construction. unsafe { self.write_to_buffer_unchecked(&buf[..amt_to_buffer]); } amt_to_buffer } /// Write byte slice directly into `self.buf` /// /// Based on `std::io::BufWriter` #[inline] unsafe fn write_to_buffer_unchecked(self: Pin<&mut Self>, buf: &[u8]) { debug_assert!(buf.len() <= self.spare_capacity()); let this = self.project(); let old_len = this.buf.len(); let buf_len = buf.len(); let src = buf.as_ptr(); let dst = this.buf.as_mut_ptr().add(old_len); ptr::copy_nonoverlapping(src, dst, buf_len); this.buf.set_len(old_len + buf_len); } /// Write directly using `inner`, bypassing buffering pub(super) fn inner_poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll> { self.project().inner.poll_write(cx, buf) } /// Write directly using `inner`, bypassing buffering pub(super) fn inner_poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll> { self.project().inner.poll_write_vectored(cx, bufs) } } impl AsyncWrite for BufWriter { fn poll_write( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll> { if self.buf.len() + buf.len() > self.buf.capacity() { ready!(self.as_mut().flush_buf(cx))?; } if buf.len() >= self.buf.capacity() { self.project().inner.poll_write(cx, buf) } else { Poll::Ready(self.project().buf.write(buf)) } } fn poll_write_vectored( mut self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll> { let total_len = bufs.iter().map(|b| b.len()).sum::(); if self.buf.len() + total_len > self.buf.capacity() { ready!(self.as_mut().flush_buf(cx))?; } if total_len >= self.buf.capacity() { self.project().inner.poll_write_vectored(cx, bufs) } else { Poll::Ready(self.project().buf.write_vectored(bufs)) } } fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { ready!(self.as_mut().flush_buf(cx))?; self.project().inner.poll_flush(cx) } fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { ready!(self.as_mut().flush_buf(cx))?; self.project().inner.poll_close(cx) } } impl AsyncRead for BufWriter { delegate_async_read!(inner); } impl AsyncBufRead for BufWriter { delegate_async_buf_read!(inner); } impl fmt::Debug for BufWriter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("BufWriter") .field("writer", &self.inner) .field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity())) .field("written", &self.written) .finish() } } impl AsyncSeek for BufWriter { /// Seek to the offset, in bytes, in the underlying writer. /// /// Seeking always writes out the internal buffer before seeking. fn poll_seek( mut self: Pin<&mut Self>, cx: &mut Context<'_>, pos: SeekFrom, ) -> Poll> { ready!(self.as_mut().flush_buf(cx))?; self.project().inner.poll_seek(cx, pos) } } futures-util-0.3.30/src/io/chain.rs000064400000000000000000000074561046102023000152210ustar 00000000000000use futures_core::ready; use futures_core::task::{Context, Poll}; use futures_io::{AsyncBufRead, AsyncRead, IoSliceMut}; use pin_project_lite::pin_project; use std::fmt; use std::io; use std::pin::Pin; pin_project! { /// Reader for the [`chain`](super::AsyncReadExt::chain) method. #[must_use = "readers do nothing unless polled"] pub struct Chain { #[pin] first: T, #[pin] second: U, done_first: bool, } } impl Chain where T: AsyncRead, U: AsyncRead, { pub(super) fn new(first: T, second: U) -> Self { Self { first, second, done_first: false } } /// Gets references to the underlying readers in this `Chain`. pub fn get_ref(&self) -> (&T, &U) { (&self.first, &self.second) } /// Gets mutable references to the underlying readers in this `Chain`. /// /// Care should be taken to avoid modifying the internal I/O state of the /// underlying readers as doing so may corrupt the internal state of this /// `Chain`. pub fn get_mut(&mut self) -> (&mut T, &mut U) { (&mut self.first, &mut self.second) } /// Gets pinned mutable references to the underlying readers in this `Chain`. /// /// Care should be taken to avoid modifying the internal I/O state of the /// underlying readers as doing so may corrupt the internal state of this /// `Chain`. pub fn get_pin_mut(self: Pin<&mut Self>) -> (Pin<&mut T>, Pin<&mut U>) { let this = self.project(); (this.first, this.second) } /// Consumes the `Chain`, returning the wrapped readers. pub fn into_inner(self) -> (T, U) { (self.first, self.second) } } impl fmt::Debug for Chain where T: fmt::Debug, U: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Chain") .field("t", &self.first) .field("u", &self.second) .field("done_first", &self.done_first) .finish() } } impl AsyncRead for Chain where T: AsyncRead, U: AsyncRead, { fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll> { let this = self.project(); if !*this.done_first { match ready!(this.first.poll_read(cx, buf)?) { 0 if !buf.is_empty() => *this.done_first = true, n => return Poll::Ready(Ok(n)), } } this.second.poll_read(cx, buf) } fn poll_read_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>], ) -> Poll> { let this = self.project(); if !*this.done_first { let n = ready!(this.first.poll_read_vectored(cx, bufs)?); if n == 0 && bufs.iter().any(|b| !b.is_empty()) { *this.done_first = true } else { return Poll::Ready(Ok(n)); } } this.second.poll_read_vectored(cx, bufs) } } impl AsyncBufRead for Chain where T: AsyncBufRead, U: AsyncBufRead, { fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); if !*this.done_first { match ready!(this.first.poll_fill_buf(cx)?) { buf if buf.is_empty() => { *this.done_first = true; } buf => return Poll::Ready(Ok(buf)), } } this.second.poll_fill_buf(cx) } fn consume(self: Pin<&mut Self>, amt: usize) { let this = self.project(); if !*this.done_first { this.first.consume(amt) } else { this.second.consume(amt) } } } futures-util-0.3.30/src/io/close.rs000064400000000000000000000014131046102023000152270ustar 00000000000000use futures_core::future::Future; use futures_core::task::{Context, Poll}; use futures_io::AsyncWrite; use std::io; use std::pin::Pin; /// Future for the [`close`](super::AsyncWriteExt::close) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Close<'a, W: ?Sized> { writer: &'a mut W, } impl Unpin for Close<'_, W> {} impl<'a, W: AsyncWrite + ?Sized + Unpin> Close<'a, W> { pub(super) fn new(writer: &'a mut W) -> Self { Self { writer } } } impl Future for Close<'_, W> { type Output = io::Result<()>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Pin::new(&mut *self.writer).poll_close(cx) } } futures-util-0.3.30/src/io/copy.rs000064400000000000000000000033401046102023000150750ustar 00000000000000use super::{copy_buf, BufReader, CopyBuf}; use futures_core::future::Future; use futures_core::task::{Context, Poll}; use futures_io::{AsyncRead, AsyncWrite}; use pin_project_lite::pin_project; use std::io; use std::pin::Pin; /// Creates a future which copies all the bytes from one object to another. /// /// The returned future will copy all the bytes read from this `AsyncRead` into the /// `writer` specified. This future will only complete once the `reader` has hit /// EOF and all bytes have been written to and flushed from the `writer` /// provided. /// /// On success the number of bytes is returned. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{self, AsyncWriteExt, Cursor}; /// /// let reader = Cursor::new([1, 2, 3, 4]); /// let mut writer = Cursor::new(vec![0u8; 5]); /// /// let bytes = io::copy(reader, &mut writer).await?; /// writer.close().await?; /// /// assert_eq!(bytes, 4); /// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` pub fn copy(reader: R, writer: &mut W) -> Copy<'_, R, W> where R: AsyncRead, W: AsyncWrite + Unpin + ?Sized, { Copy { inner: copy_buf(BufReader::new(reader), writer) } } pin_project! { /// Future for the [`copy()`] function. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Copy<'a, R, W: ?Sized> { #[pin] inner: CopyBuf<'a, BufReader, W>, } } impl Future for Copy<'_, R, W> { type Output = io::Result; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { self.project().inner.poll(cx) } } futures-util-0.3.30/src/io/copy_buf.rs000064400000000000000000000044351046102023000157370ustar 00000000000000use futures_core::future::Future; use futures_core::ready; use futures_core::task::{Context, Poll}; use futures_io::{AsyncBufRead, AsyncWrite}; use pin_project_lite::pin_project; use std::io; use std::pin::Pin; /// Creates a future which copies all the bytes from one object to another. /// /// The returned future will copy all the bytes read from this `AsyncBufRead` into the /// `writer` specified. This future will only complete once the `reader` has hit /// EOF and all bytes have been written to and flushed from the `writer` /// provided. /// /// On success the number of bytes is returned. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{self, AsyncWriteExt, Cursor}; /// /// let reader = Cursor::new([1, 2, 3, 4]); /// let mut writer = Cursor::new(vec![0u8; 5]); /// /// let bytes = io::copy_buf(reader, &mut writer).await?; /// writer.close().await?; /// /// assert_eq!(bytes, 4); /// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` pub fn copy_buf(reader: R, writer: &mut W) -> CopyBuf<'_, R, W> where R: AsyncBufRead, W: AsyncWrite + Unpin + ?Sized, { CopyBuf { reader, writer, amt: 0 } } pin_project! { /// Future for the [`copy_buf()`] function. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct CopyBuf<'a, R, W: ?Sized> { #[pin] reader: R, writer: &'a mut W, amt: u64, } } impl Future for CopyBuf<'_, R, W> where R: AsyncBufRead, W: AsyncWrite + Unpin + ?Sized, { type Output = io::Result; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.project(); loop { let buffer = ready!(this.reader.as_mut().poll_fill_buf(cx))?; if buffer.is_empty() { ready!(Pin::new(&mut this.writer).poll_flush(cx))?; return Poll::Ready(Ok(*this.amt)); } let i = ready!(Pin::new(&mut this.writer).poll_write(cx, buffer))?; if i == 0 { return Poll::Ready(Err(io::ErrorKind::WriteZero.into())); } *this.amt += i as u64; this.reader.as_mut().consume(i); } } } futures-util-0.3.30/src/io/copy_buf_abortable.rs000064400000000000000000000100341046102023000177420ustar 00000000000000use crate::abortable::{AbortHandle, AbortInner, Aborted}; use futures_core::future::Future; use futures_core::task::{Context, Poll}; use futures_io::{AsyncBufRead, AsyncWrite}; use pin_project_lite::pin_project; use std::io; use std::pin::Pin; use std::sync::atomic::Ordering; use std::sync::Arc; /// Creates a future which copies all the bytes from one object to another, with its `AbortHandle`. /// /// The returned future will copy all the bytes read from this `AsyncBufRead` into the /// `writer` specified. This future will only complete once abort has been requested or the `reader` has hit /// EOF and all bytes have been written to and flushed from the `writer` /// provided. /// /// On success the number of bytes is returned. If aborted, `Aborted` is returned. Otherwise, the underlying error is returned. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{self, AsyncWriteExt, Cursor}; /// use futures::future::Aborted; /// /// let reader = Cursor::new([1, 2, 3, 4]); /// let mut writer = Cursor::new(vec![0u8; 5]); /// /// let (fut, abort_handle) = io::copy_buf_abortable(reader, &mut writer); /// let bytes = fut.await; /// abort_handle.abort(); /// writer.close().await.unwrap(); /// match bytes { /// Ok(Ok(n)) => { /// assert_eq!(n, 4); /// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]); /// Ok(n) /// }, /// Ok(Err(a)) => { /// Err::(a) /// } /// Err(e) => panic!("{}", e) /// } /// # }).unwrap(); /// ``` pub fn copy_buf_abortable( reader: R, writer: &mut W, ) -> (CopyBufAbortable<'_, R, W>, AbortHandle) where R: AsyncBufRead, W: AsyncWrite + Unpin + ?Sized, { let (handle, reg) = AbortHandle::new_pair(); (CopyBufAbortable { reader, writer, amt: 0, inner: reg.inner }, handle) } pin_project! { /// Future for the [`copy_buf_abortable()`] function. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct CopyBufAbortable<'a, R, W: ?Sized> { #[pin] reader: R, writer: &'a mut W, amt: u64, inner: Arc } } macro_rules! ready_or_break { ($e:expr $(,)?) => { match $e { $crate::task::Poll::Ready(t) => t, $crate::task::Poll::Pending => break, } }; } impl Future for CopyBufAbortable<'_, R, W> where R: AsyncBufRead, W: AsyncWrite + Unpin + Sized, { type Output = Result, io::Error>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.project(); loop { // Check if the task has been aborted if this.inner.aborted.load(Ordering::Relaxed) { return Poll::Ready(Ok(Err(Aborted))); } // Read some bytes from the reader, and if we have reached EOF, return total bytes read let buffer = ready_or_break!(this.reader.as_mut().poll_fill_buf(cx))?; if buffer.is_empty() { ready_or_break!(Pin::new(&mut this.writer).poll_flush(cx))?; return Poll::Ready(Ok(Ok(*this.amt))); } // Pass the buffer to the writer, and update the amount written let i = ready_or_break!(Pin::new(&mut this.writer).poll_write(cx, buffer))?; if i == 0 { return Poll::Ready(Err(io::ErrorKind::WriteZero.into())); } *this.amt += i as u64; this.reader.as_mut().consume(i); } // Schedule the task to be woken up again. // Never called unless Poll::Pending is returned from io objects. this.inner.waker.register(cx.waker()); // Check to see if the task was aborted between the first check and // registration. // Checking with `Relaxed` is sufficient because // `register` introduces an `AcqRel` barrier. if this.inner.aborted.load(Ordering::Relaxed) { return Poll::Ready(Ok(Err(Aborted))); } Poll::Pending } } futures-util-0.3.30/src/io/cursor.rs000064400000000000000000000145231046102023000154450ustar 00000000000000use futures_core::task::{Context, Poll}; use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, SeekFrom}; use std::io; use std::pin::Pin; /// A `Cursor` wraps an in-memory buffer and provides it with a /// [`AsyncSeek`] implementation. /// /// `Cursor`s are used with in-memory buffers, anything implementing /// `AsRef<[u8]>`, to allow them to implement [`AsyncRead`] and/or [`AsyncWrite`], /// allowing these buffers to be used anywhere you might use a reader or writer /// that does actual I/O. /// /// This library implements some I/O traits on various types which /// are commonly used as a buffer, like `Cursor<`[`Vec`]`>` and /// `Cursor<`[`&[u8]`][bytes]`>`. /// /// [`AsyncSeek`]: trait.AsyncSeek.html /// [`AsyncRead`]: trait.AsyncRead.html /// [`AsyncWrite`]: trait.AsyncWrite.html /// [bytes]: https://doc.rust-lang.org/std/primitive.slice.html #[derive(Clone, Debug, Default)] pub struct Cursor { inner: io::Cursor, } impl Cursor { /// Creates a new cursor wrapping the provided underlying in-memory buffer. /// /// Cursor initial position is `0` even if underlying buffer (e.g., `Vec`) /// is not empty. So writing to cursor starts with overwriting `Vec` /// content, not with appending to it. /// /// # Examples /// /// ``` /// use futures::io::Cursor; /// /// let buff = Cursor::new(Vec::new()); /// # fn force_inference(_: &Cursor>) {} /// # force_inference(&buff); /// ``` pub fn new(inner: T) -> Self { Self { inner: io::Cursor::new(inner) } } /// Consumes this cursor, returning the underlying value. /// /// # Examples /// /// ``` /// use futures::io::Cursor; /// /// let buff = Cursor::new(Vec::new()); /// # fn force_inference(_: &Cursor>) {} /// # force_inference(&buff); /// /// let vec = buff.into_inner(); /// ``` pub fn into_inner(self) -> T { self.inner.into_inner() } /// Gets a reference to the underlying value in this cursor. /// /// # Examples /// /// ``` /// use futures::io::Cursor; /// /// let buff = Cursor::new(Vec::new()); /// # fn force_inference(_: &Cursor>) {} /// # force_inference(&buff); /// /// let reference = buff.get_ref(); /// ``` pub fn get_ref(&self) -> &T { self.inner.get_ref() } /// Gets a mutable reference to the underlying value in this cursor. /// /// Care should be taken to avoid modifying the internal I/O state of the /// underlying value as it may corrupt this cursor's position. /// /// # Examples /// /// ``` /// use futures::io::Cursor; /// /// let mut buff = Cursor::new(Vec::new()); /// # fn force_inference(_: &Cursor>) {} /// # force_inference(&buff); /// /// let reference = buff.get_mut(); /// ``` pub fn get_mut(&mut self) -> &mut T { self.inner.get_mut() } /// Returns the current position of this cursor. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{AsyncSeekExt, Cursor, SeekFrom}; /// /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); /// /// assert_eq!(buff.position(), 0); /// /// buff.seek(SeekFrom::Current(2)).await?; /// assert_eq!(buff.position(), 2); /// /// buff.seek(SeekFrom::Current(-1)).await?; /// assert_eq!(buff.position(), 1); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` pub fn position(&self) -> u64 { self.inner.position() } /// Sets the position of this cursor. /// /// # Examples /// /// ``` /// use futures::io::Cursor; /// /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); /// /// assert_eq!(buff.position(), 0); /// /// buff.set_position(2); /// assert_eq!(buff.position(), 2); /// /// buff.set_position(4); /// assert_eq!(buff.position(), 4); /// ``` pub fn set_position(&mut self, pos: u64) { self.inner.set_position(pos) } } impl AsyncSeek for Cursor where T: AsRef<[u8]> + Unpin, { fn poll_seek( mut self: Pin<&mut Self>, _: &mut Context<'_>, pos: SeekFrom, ) -> Poll> { Poll::Ready(io::Seek::seek(&mut self.inner, pos)) } } impl + Unpin> AsyncRead for Cursor { fn poll_read( mut self: Pin<&mut Self>, _cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll> { Poll::Ready(io::Read::read(&mut self.inner, buf)) } fn poll_read_vectored( mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>], ) -> Poll> { Poll::Ready(io::Read::read_vectored(&mut self.inner, bufs)) } } impl AsyncBufRead for Cursor where T: AsRef<[u8]> + Unpin, { fn poll_fill_buf(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { Poll::Ready(io::BufRead::fill_buf(&mut self.get_mut().inner)) } fn consume(mut self: Pin<&mut Self>, amt: usize) { io::BufRead::consume(&mut self.inner, amt) } } macro_rules! delegate_async_write_to_stdio { () => { fn poll_write( mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &[u8], ) -> Poll> { Poll::Ready(io::Write::write(&mut self.inner, buf)) } fn poll_write_vectored( mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll> { Poll::Ready(io::Write::write_vectored(&mut self.inner, bufs)) } fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { Poll::Ready(io::Write::flush(&mut self.inner)) } fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.poll_flush(cx) } }; } impl AsyncWrite for Cursor<&mut [u8]> { delegate_async_write_to_stdio!(); } impl AsyncWrite for Cursor<&mut Vec> { delegate_async_write_to_stdio!(); } impl AsyncWrite for Cursor> { delegate_async_write_to_stdio!(); } impl AsyncWrite for Cursor> { delegate_async_write_to_stdio!(); } futures-util-0.3.30/src/io/empty.rs000064400000000000000000000026161046102023000152660ustar 00000000000000use futures_core::task::{Context, Poll}; use futures_io::{AsyncBufRead, AsyncRead}; use std::fmt; use std::io; use std::pin::Pin; /// Reader for the [`empty()`] function. #[must_use = "readers do nothing unless polled"] pub struct Empty { _priv: (), } /// Constructs a new handle to an empty reader. /// /// All reads from the returned reader will return `Poll::Ready(Ok(0))`. /// /// # Examples /// /// A slightly sad example of not reading anything into a buffer: /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{self, AsyncReadExt}; /// /// let mut buffer = String::new(); /// let mut reader = io::empty(); /// reader.read_to_string(&mut buffer).await?; /// assert!(buffer.is_empty()); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` pub fn empty() -> Empty { Empty { _priv: () } } impl AsyncRead for Empty { #[inline] fn poll_read( self: Pin<&mut Self>, _: &mut Context<'_>, _: &mut [u8], ) -> Poll> { Poll::Ready(Ok(0)) } } impl AsyncBufRead for Empty { #[inline] fn poll_fill_buf(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(&[])) } #[inline] fn consume(self: Pin<&mut Self>, _: usize) {} } impl fmt::Debug for Empty { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.pad("Empty { .. }") } } futures-util-0.3.30/src/io/fill_buf.rs000064400000000000000000000030231046102023000157030ustar 00000000000000use futures_core::future::Future; use futures_core::task::{Context, Poll}; use futures_io::AsyncBufRead; use std::io; use std::pin::Pin; use std::slice; /// Future for the [`fill_buf`](super::AsyncBufReadExt::fill_buf) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct FillBuf<'a, R: ?Sized> { reader: Option<&'a mut R>, } impl Unpin for FillBuf<'_, R> {} impl<'a, R: AsyncBufRead + ?Sized + Unpin> FillBuf<'a, R> { pub(super) fn new(reader: &'a mut R) -> Self { Self { reader: Some(reader) } } } impl<'a, R> Future for FillBuf<'a, R> where R: AsyncBufRead + ?Sized + Unpin, { type Output = io::Result<&'a [u8]>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = &mut *self; let reader = this.reader.take().expect("Polled FillBuf after completion"); match Pin::new(&mut *reader).poll_fill_buf(cx) { Poll::Ready(Ok(slice)) => { // With polonius it is possible to remove this lifetime transmutation and just have // the correct lifetime of the reference inferred based on which branch is taken let slice: &'a [u8] = unsafe { slice::from_raw_parts(slice.as_ptr(), slice.len()) }; Poll::Ready(Ok(slice)) } Poll::Ready(Err(err)) => Poll::Ready(Err(err)), Poll::Pending => { this.reader = Some(reader); Poll::Pending } } } } futures-util-0.3.30/src/io/flush.rs000064400000000000000000000014301046102023000152420ustar 00000000000000use futures_core::future::Future; use futures_core::task::{Context, Poll}; use futures_io::AsyncWrite; use std::io; use std::pin::Pin; /// Future for the [`flush`](super::AsyncWriteExt::flush) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Flush<'a, W: ?Sized> { writer: &'a mut W, } impl Unpin for Flush<'_, W> {} impl<'a, W: AsyncWrite + ?Sized + Unpin> Flush<'a, W> { pub(super) fn new(writer: &'a mut W) -> Self { Self { writer } } } impl Future for Flush<'_, W> where W: AsyncWrite + ?Sized + Unpin, { type Output = io::Result<()>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Pin::new(&mut *self.writer).poll_flush(cx) } } futures-util-0.3.30/src/io/into_sink.rs000064400000000000000000000051571046102023000161300ustar 00000000000000use futures_core::ready; use futures_core::task::{Context, Poll}; use futures_io::AsyncWrite; use futures_sink::Sink; use pin_project_lite::pin_project; use std::io; use std::pin::Pin; #[derive(Debug)] struct Block { offset: usize, bytes: Item, } pin_project! { /// Sink for the [`into_sink`](super::AsyncWriteExt::into_sink) method. #[must_use = "sinks do nothing unless polled"] #[derive(Debug)] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] pub struct IntoSink { #[pin] writer: W, // An outstanding block for us to push into the underlying writer, along with an offset of how // far into this block we have written already. buffer: Option>, } } impl> IntoSink { pub(super) fn new(writer: W) -> Self { Self { writer, buffer: None } } /// If we have an outstanding block in `buffer` attempt to push it into the writer, does _not_ /// flush the writer after it succeeds in pushing the block into it. fn poll_flush_buffer( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll> { let mut this = self.project(); if let Some(buffer) = this.buffer { loop { let bytes = buffer.bytes.as_ref(); let written = ready!(this.writer.as_mut().poll_write(cx, &bytes[buffer.offset..]))?; buffer.offset += written; if buffer.offset == bytes.len() { break; } } } *this.buffer = None; Poll::Ready(Ok(())) } } impl> Sink for IntoSink { type Error = io::Error; fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { ready!(self.poll_flush_buffer(cx))?; Poll::Ready(Ok(())) } fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { debug_assert!(self.buffer.is_none()); *self.project().buffer = Some(Block { offset: 0, bytes: item }); Ok(()) } fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { ready!(self.as_mut().poll_flush_buffer(cx))?; ready!(self.project().writer.poll_flush(cx))?; Poll::Ready(Ok(())) } fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { ready!(self.as_mut().poll_flush_buffer(cx))?; ready!(self.project().writer.poll_close(cx))?; Poll::Ready(Ok(())) } } futures-util-0.3.30/src/io/line_writer.rs000064400000000000000000000122201046102023000164430ustar 00000000000000use super::buf_writer::BufWriter; use futures_core::ready; use futures_core::task::{Context, Poll}; use futures_io::AsyncWrite; use futures_io::IoSlice; use pin_project_lite::pin_project; use std::io; use std::pin::Pin; pin_project! { /// Wrap a writer, like [`BufWriter`] does, but prioritizes buffering lines /// /// This was written based on `std::io::LineWriter` which goes into further details /// explaining the code. /// /// Buffering is actually done using `BufWriter`. This class will leverage `BufWriter` /// to write on-each-line. #[derive(Debug)] pub struct LineWriter { #[pin] buf_writer: BufWriter, } } impl LineWriter { /// Create a new `LineWriter` with default buffer capacity. The default is currently 1KB /// which was taken from `std::io::LineWriter` pub fn new(inner: W) -> LineWriter { LineWriter::with_capacity(1024, inner) } /// Creates a new `LineWriter` with the specified buffer capacity. pub fn with_capacity(capacity: usize, inner: W) -> LineWriter { LineWriter { buf_writer: BufWriter::with_capacity(capacity, inner) } } /// Flush `buf_writer` if last char is "new line" fn flush_if_completed_line(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); match this.buf_writer.buffer().last().copied() { Some(b'\n') => this.buf_writer.flush_buf(cx), _ => Poll::Ready(Ok(())), } } /// Returns a reference to `buf_writer`'s internally buffered data. pub fn buffer(&self) -> &[u8] { self.buf_writer.buffer() } /// Acquires a reference to the underlying sink or stream that this combinator is /// pulling from. pub fn get_ref(&self) -> &W { self.buf_writer.get_ref() } } impl AsyncWrite for LineWriter { fn poll_write( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll> { let mut this = self.as_mut().project(); let newline_index = match memchr::memrchr(b'\n', buf) { None => { ready!(self.as_mut().flush_if_completed_line(cx)?); return self.project().buf_writer.poll_write(cx, buf); } Some(newline_index) => newline_index + 1, }; ready!(this.buf_writer.as_mut().poll_flush(cx)?); let lines = &buf[..newline_index]; let flushed = { ready!(this.buf_writer.as_mut().inner_poll_write(cx, lines))? }; if flushed == 0 { return Poll::Ready(Ok(0)); } let tail = if flushed >= newline_index { &buf[flushed..] } else if newline_index - flushed <= this.buf_writer.capacity() { &buf[flushed..newline_index] } else { let scan_area = &buf[flushed..]; let scan_area = &scan_area[..this.buf_writer.capacity()]; match memchr::memrchr(b'\n', scan_area) { Some(newline_index) => &scan_area[..newline_index + 1], None => scan_area, } }; let buffered = this.buf_writer.as_mut().write_to_buf(tail); Poll::Ready(Ok(flushed + buffered)) } fn poll_write_vectored( mut self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll> { let mut this = self.as_mut().project(); // `is_write_vectored()` is handled in original code, but not in this crate // see https://github.com/rust-lang/rust/issues/70436 let last_newline_buf_idx = bufs .iter() .enumerate() .rev() .find_map(|(i, buf)| memchr::memchr(b'\n', buf).map(|_| i)); let last_newline_buf_idx = match last_newline_buf_idx { None => { ready!(self.as_mut().flush_if_completed_line(cx)?); return self.project().buf_writer.poll_write_vectored(cx, bufs); } Some(i) => i, }; ready!(this.buf_writer.as_mut().poll_flush(cx)?); let (lines, tail) = bufs.split_at(last_newline_buf_idx + 1); let flushed = { ready!(this.buf_writer.as_mut().inner_poll_write_vectored(cx, lines))? }; if flushed == 0 { return Poll::Ready(Ok(0)); } let lines_len = lines.iter().map(|buf| buf.len()).sum(); if flushed < lines_len { return Poll::Ready(Ok(flushed)); } let buffered: usize = tail .iter() .filter(|buf| !buf.is_empty()) .map(|buf| this.buf_writer.as_mut().write_to_buf(buf)) .take_while(|&n| n > 0) .sum(); Poll::Ready(Ok(flushed + buffered)) } /// Forward to `buf_writer` 's `BufWriter::poll_flush()` fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.as_mut().project().buf_writer.poll_flush(cx) } /// Forward to `buf_writer` 's `BufWriter::poll_close()` fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.as_mut().project().buf_writer.poll_close(cx) } } futures-util-0.3.30/src/io/lines.rs000064400000000000000000000024531046102023000152410ustar 00000000000000use super::read_line::read_line_internal; use futures_core::ready; use futures_core::stream::Stream; use futures_core::task::{Context, Poll}; use futures_io::AsyncBufRead; use pin_project_lite::pin_project; use std::io; use std::mem; use std::pin::Pin; pin_project! { /// Stream for the [`lines`](super::AsyncBufReadExt::lines) method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct Lines { #[pin] reader: R, buf: String, bytes: Vec, read: usize, } } impl Lines { pub(super) fn new(reader: R) -> Self { Self { reader, buf: String::new(), bytes: Vec::new(), read: 0 } } } impl Stream for Lines { type Item = io::Result; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); let n = ready!(read_line_internal(this.reader, cx, this.buf, this.bytes, this.read))?; if n == 0 && this.buf.is_empty() { return Poll::Ready(None); } if this.buf.ends_with('\n') { this.buf.pop(); if this.buf.ends_with('\r') { this.buf.pop(); } } Poll::Ready(Some(Ok(mem::take(this.buf)))) } } futures-util-0.3.30/src/io/mod.rs000064400000000000000000000652761046102023000147220ustar 00000000000000//! Asynchronous I/O. //! //! This module is the asynchronous version of `std::io`. It defines four //! traits, [`AsyncRead`], [`AsyncWrite`], [`AsyncSeek`], and [`AsyncBufRead`], //! which mirror the `Read`, `Write`, `Seek`, and `BufRead` traits of the //! standard library. However, these traits integrate with the asynchronous //! task system, so that if an I/O object isn't ready for reading (or writing), //! the thread is not blocked, and instead the current task is queued to be //! woken when I/O is ready. //! //! In addition, the [`AsyncReadExt`], [`AsyncWriteExt`], [`AsyncSeekExt`], and //! [`AsyncBufReadExt`] extension traits offer a variety of useful combinators //! for operating with asynchronous I/O objects, including ways to work with //! them using futures, streams and sinks. //! //! This module is only available when the `std` feature of this //! library is activated, and it is activated by default. #[cfg(feature = "io-compat")] #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] use crate::compat::Compat; use crate::future::assert_future; use crate::stream::assert_stream; use std::{pin::Pin, ptr}; // Re-export some types from `std::io` so that users don't have to deal // with conflicts when `use`ing `futures::io` and `std::io`. #[doc(no_inline)] pub use std::io::{Error, ErrorKind, IoSlice, IoSliceMut, Result, SeekFrom}; pub use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite}; // used by `BufReader` and `BufWriter` // https://github.com/rust-lang/rust/blob/master/src/libstd/sys_common/io.rs#L1 const DEFAULT_BUF_SIZE: usize = 8 * 1024; /// Initializes a buffer if necessary. /// /// A buffer is currently always initialized. #[inline] unsafe fn initialize(_reader: &R, buf: &mut [u8]) { ptr::write_bytes(buf.as_mut_ptr(), 0, buf.len()) } mod allow_std; pub use self::allow_std::AllowStdIo; mod buf_reader; pub use self::buf_reader::{BufReader, SeeKRelative}; mod buf_writer; pub use self::buf_writer::BufWriter; mod line_writer; pub use self::line_writer::LineWriter; mod chain; pub use self::chain::Chain; mod close; pub use self::close::Close; mod copy; pub use self::copy::{copy, Copy}; mod copy_buf; pub use self::copy_buf::{copy_buf, CopyBuf}; mod copy_buf_abortable; pub use self::copy_buf_abortable::{copy_buf_abortable, CopyBufAbortable}; mod cursor; pub use self::cursor::Cursor; mod empty; pub use self::empty::{empty, Empty}; mod fill_buf; pub use self::fill_buf::FillBuf; mod flush; pub use self::flush::Flush; #[cfg(feature = "sink")] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] mod into_sink; #[cfg(feature = "sink")] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] pub use self::into_sink::IntoSink; mod lines; pub use self::lines::Lines; mod read; pub use self::read::Read; mod read_vectored; pub use self::read_vectored::ReadVectored; mod read_exact; pub use self::read_exact::ReadExact; mod read_line; pub use self::read_line::ReadLine; mod read_to_end; pub use self::read_to_end::ReadToEnd; mod read_to_string; pub use self::read_to_string::ReadToString; mod read_until; pub use self::read_until::ReadUntil; mod repeat; pub use self::repeat::{repeat, Repeat}; mod seek; pub use self::seek::Seek; mod sink; pub use self::sink::{sink, Sink}; mod split; pub use self::split::{ReadHalf, ReuniteError, WriteHalf}; mod take; pub use self::take::Take; mod window; pub use self::window::Window; mod write; pub use self::write::Write; mod write_vectored; pub use self::write_vectored::WriteVectored; mod write_all; pub use self::write_all::WriteAll; #[cfg(feature = "write-all-vectored")] mod write_all_vectored; #[cfg(feature = "write-all-vectored")] pub use self::write_all_vectored::WriteAllVectored; /// An extension trait which adds utility methods to `AsyncRead` types. pub trait AsyncReadExt: AsyncRead { /// Creates an adaptor which will chain this stream with another. /// /// The returned `AsyncRead` instance will first read all bytes from this object /// until EOF is encountered. Afterwards the output is equivalent to the /// output of `next`. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{AsyncReadExt, Cursor}; /// /// let reader1 = Cursor::new([1, 2, 3, 4]); /// let reader2 = Cursor::new([5, 6, 7, 8]); /// /// let mut reader = reader1.chain(reader2); /// let mut buffer = Vec::new(); /// /// // read the value into a Vec. /// reader.read_to_end(&mut buffer).await?; /// assert_eq!(buffer, [1, 2, 3, 4, 5, 6, 7, 8]); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` fn chain(self, next: R) -> Chain where Self: Sized, R: AsyncRead, { assert_read(Chain::new(self, next)) } /// Tries to read some bytes directly into the given `buf` in asynchronous /// manner, returning a future type. /// /// The returned future will resolve to the number of bytes read once the read /// operation is completed. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{AsyncReadExt, Cursor}; /// /// let mut reader = Cursor::new([1, 2, 3, 4]); /// let mut output = [0u8; 5]; /// /// let bytes = reader.read(&mut output[..]).await?; /// /// // This is only guaranteed to be 4 because `&[u8]` is a synchronous /// // reader. In a real system you could get anywhere from 1 to /// // `output.len()` bytes in a single read. /// assert_eq!(bytes, 4); /// assert_eq!(output, [1, 2, 3, 4, 0]); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self> where Self: Unpin, { assert_future::, _>(Read::new(self, buf)) } /// Creates a future which will read from the `AsyncRead` into `bufs` using vectored /// IO operations. /// /// The returned future will resolve to the number of bytes read once the read /// operation is completed. fn read_vectored<'a>(&'a mut self, bufs: &'a mut [IoSliceMut<'a>]) -> ReadVectored<'a, Self> where Self: Unpin, { assert_future::, _>(ReadVectored::new(self, bufs)) } /// Creates a future which will read exactly enough bytes to fill `buf`, /// returning an error if end of file (EOF) is hit sooner. /// /// The returned future will resolve once the read operation is completed. /// /// In the case of an error the buffer and the object will be discarded, with /// the error yielded. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{AsyncReadExt, Cursor}; /// /// let mut reader = Cursor::new([1, 2, 3, 4]); /// let mut output = [0u8; 4]; /// /// reader.read_exact(&mut output).await?; /// /// assert_eq!(output, [1, 2, 3, 4]); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` /// /// ## EOF is hit before `buf` is filled /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{self, AsyncReadExt, Cursor}; /// /// let mut reader = Cursor::new([1, 2, 3, 4]); /// let mut output = [0u8; 5]; /// /// let result = reader.read_exact(&mut output).await; /// /// assert_eq!(result.unwrap_err().kind(), io::ErrorKind::UnexpectedEof); /// # }); /// ``` fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self> where Self: Unpin, { assert_future::, _>(ReadExact::new(self, buf)) } /// Creates a future which will read all the bytes from this `AsyncRead`. /// /// On success the total number of bytes read is returned. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{AsyncReadExt, Cursor}; /// /// let mut reader = Cursor::new([1, 2, 3, 4]); /// let mut output = Vec::with_capacity(4); /// /// let bytes = reader.read_to_end(&mut output).await?; /// /// assert_eq!(bytes, 4); /// assert_eq!(output, vec![1, 2, 3, 4]); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` fn read_to_end<'a>(&'a mut self, buf: &'a mut Vec) -> ReadToEnd<'a, Self> where Self: Unpin, { assert_future::, _>(ReadToEnd::new(self, buf)) } /// Creates a future which will read all the bytes from this `AsyncRead`. /// /// On success the total number of bytes read is returned. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{AsyncReadExt, Cursor}; /// /// let mut reader = Cursor::new(&b"1234"[..]); /// let mut buffer = String::with_capacity(4); /// /// let bytes = reader.read_to_string(&mut buffer).await?; /// /// assert_eq!(bytes, 4); /// assert_eq!(buffer, String::from("1234")); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` fn read_to_string<'a>(&'a mut self, buf: &'a mut String) -> ReadToString<'a, Self> where Self: Unpin, { assert_future::, _>(ReadToString::new(self, buf)) } /// Helper method for splitting this read/write object into two halves. /// /// The two halves returned implement the `AsyncRead` and `AsyncWrite` /// traits, respectively. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{self, AsyncReadExt, Cursor}; /// /// // Note that for `Cursor` the read and write halves share a single /// // seek position. This may or may not be true for other types that /// // implement both `AsyncRead` and `AsyncWrite`. /// /// let reader = Cursor::new([1, 2, 3, 4]); /// let mut buffer = Cursor::new(vec![0, 0, 0, 0, 5, 6, 7, 8]); /// let mut writer = Cursor::new(vec![0u8; 5]); /// /// { /// let (buffer_reader, mut buffer_writer) = (&mut buffer).split(); /// io::copy(reader, &mut buffer_writer).await?; /// io::copy(buffer_reader, &mut writer).await?; /// } /// /// assert_eq!(buffer.into_inner(), [1, 2, 3, 4, 5, 6, 7, 8]); /// assert_eq!(writer.into_inner(), [5, 6, 7, 8, 0]); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` fn split(self) -> (ReadHalf, WriteHalf) where Self: AsyncWrite + Sized, { let (r, w) = split::split(self); (assert_read(r), assert_write(w)) } /// Creates an AsyncRead adapter which will read at most `limit` bytes /// from the underlying reader. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{AsyncReadExt, Cursor}; /// /// let reader = Cursor::new(&b"12345678"[..]); /// let mut buffer = [0; 5]; /// /// let mut take = reader.take(4); /// let n = take.read(&mut buffer).await?; /// /// assert_eq!(n, 4); /// assert_eq!(&buffer, b"1234\0"); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` fn take(self, limit: u64) -> Take where Self: Sized, { assert_read(Take::new(self, limit)) } /// Wraps an [`AsyncRead`] in a compatibility wrapper that allows it to be /// used as a futures 0.1 / tokio-io 0.1 `AsyncRead`. If the wrapped type /// implements [`AsyncWrite`] as well, the result will also implement the /// futures 0.1 / tokio 0.1 `AsyncWrite` trait. /// /// Requires the `io-compat` feature to enable. #[cfg(feature = "io-compat")] #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] fn compat(self) -> Compat where Self: Sized + Unpin, { Compat::new(self) } } impl AsyncReadExt for R {} /// An extension trait which adds utility methods to `AsyncWrite` types. pub trait AsyncWriteExt: AsyncWrite { /// Creates a future which will entirely flush this `AsyncWrite`. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{AllowStdIo, AsyncWriteExt}; /// use std::io::{BufWriter, Cursor}; /// /// let mut output = vec![0u8; 5]; /// /// { /// let writer = Cursor::new(&mut output); /// let mut buffered = AllowStdIo::new(BufWriter::new(writer)); /// buffered.write_all(&[1, 2]).await?; /// buffered.write_all(&[3, 4]).await?; /// buffered.flush().await?; /// } /// /// assert_eq!(output, [1, 2, 3, 4, 0]); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` fn flush(&mut self) -> Flush<'_, Self> where Self: Unpin, { assert_future::, _>(Flush::new(self)) } /// Creates a future which will entirely close this `AsyncWrite`. fn close(&mut self) -> Close<'_, Self> where Self: Unpin, { assert_future::, _>(Close::new(self)) } /// Creates a future which will write bytes from `buf` into the object. /// /// The returned future will resolve to the number of bytes written once the write /// operation is completed. fn write<'a>(&'a mut self, buf: &'a [u8]) -> Write<'a, Self> where Self: Unpin, { assert_future::, _>(Write::new(self, buf)) } /// Creates a future which will write bytes from `bufs` into the object using vectored /// IO operations. /// /// The returned future will resolve to the number of bytes written once the write /// operation is completed. fn write_vectored<'a>(&'a mut self, bufs: &'a [IoSlice<'a>]) -> WriteVectored<'a, Self> where Self: Unpin, { assert_future::, _>(WriteVectored::new(self, bufs)) } /// Write data into this object. /// /// Creates a future that will write the entire contents of the buffer `buf` into /// this `AsyncWrite`. /// /// The returned future will not complete until all the data has been written. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{AsyncWriteExt, Cursor}; /// /// let mut writer = Cursor::new(vec![0u8; 5]); /// /// writer.write_all(&[1, 2, 3, 4]).await?; /// /// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> WriteAll<'a, Self> where Self: Unpin, { assert_future::, _>(WriteAll::new(self, buf)) } /// Attempts to write multiple buffers into this writer. /// /// Creates a future that will write the entire contents of `bufs` into this /// `AsyncWrite` using [vectored writes]. /// /// The returned future will not complete until all the data has been /// written. /// /// [vectored writes]: std::io::Write::write_vectored /// /// # Notes /// /// Unlike `io::Write::write_vectored`, this takes a *mutable* reference to /// a slice of `IoSlice`s, not an immutable one. That's because we need to /// modify the slice to keep track of the bytes already written. /// /// Once this futures returns, the contents of `bufs` are unspecified, as /// this depends on how many calls to `write_vectored` were necessary. It is /// best to understand this function as taking ownership of `bufs` and to /// not use `bufs` afterwards. The underlying buffers, to which the /// `IoSlice`s point (but not the `IoSlice`s themselves), are unchanged and /// can be reused. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::AsyncWriteExt; /// use futures_util::io::Cursor; /// use std::io::IoSlice; /// /// let mut writer = Cursor::new(Vec::new()); /// let bufs = &mut [ /// IoSlice::new(&[1]), /// IoSlice::new(&[2, 3]), /// IoSlice::new(&[4, 5, 6]), /// ]; /// /// writer.write_all_vectored(bufs).await?; /// // Note: the contents of `bufs` is now unspecified, see the Notes section. /// /// assert_eq!(writer.into_inner(), &[1, 2, 3, 4, 5, 6]); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` #[cfg(feature = "write-all-vectored")] fn write_all_vectored<'a>( &'a mut self, bufs: &'a mut [IoSlice<'a>], ) -> WriteAllVectored<'a, Self> where Self: Unpin, { assert_future::, _>(WriteAllVectored::new(self, bufs)) } /// Wraps an [`AsyncWrite`] in a compatibility wrapper that allows it to be /// used as a futures 0.1 / tokio-io 0.1 `AsyncWrite`. /// Requires the `io-compat` feature to enable. #[cfg(feature = "io-compat")] #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] fn compat_write(self) -> Compat where Self: Sized + Unpin, { Compat::new(self) } /// Allow using an [`AsyncWrite`] as a [`Sink`](futures_sink::Sink)`>`. /// /// This adapter produces a sink that will write each value passed to it /// into the underlying writer. /// /// Note that this function consumes the given writer, returning a wrapped /// version. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::AsyncWriteExt; /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::iter(vec![Ok([1, 2, 3]), Ok([4, 5, 6])]); /// /// let mut writer = vec![]; /// /// stream.forward((&mut writer).into_sink()).await?; /// /// assert_eq!(writer, vec![1, 2, 3, 4, 5, 6]); /// # Ok::<(), Box>(()) /// # })?; /// # Ok::<(), Box>(()) /// ``` #[cfg(feature = "sink")] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] fn into_sink>(self) -> IntoSink where Self: Sized, { crate::sink::assert_sink::(IntoSink::new(self)) } } impl AsyncWriteExt for W {} /// An extension trait which adds utility methods to `AsyncSeek` types. pub trait AsyncSeekExt: AsyncSeek { /// Creates a future which will seek an IO object, and then yield the /// new position in the object and the object itself. /// /// In the case of an error the buffer and the object will be discarded, with /// the error yielded. fn seek(&mut self, pos: SeekFrom) -> Seek<'_, Self> where Self: Unpin, { assert_future::, _>(Seek::new(self, pos)) } /// Creates a future which will return the current seek position from the /// start of the stream. /// /// This is equivalent to `self.seek(SeekFrom::Current(0))`. fn stream_position(&mut self) -> Seek<'_, Self> where Self: Unpin, { self.seek(SeekFrom::Current(0)) } } impl AsyncSeekExt for S {} /// An extension trait which adds utility methods to `AsyncBufRead` types. pub trait AsyncBufReadExt: AsyncBufRead { /// Creates a future which will wait for a non-empty buffer to be available from this I/O /// object or EOF to be reached. /// /// This method is the async equivalent to [`BufRead::fill_buf`](std::io::BufRead::fill_buf). /// /// ```rust /// # futures::executor::block_on(async { /// use futures::{io::AsyncBufReadExt as _, stream::{iter, TryStreamExt as _}}; /// /// let mut stream = iter(vec![Ok(vec![1, 2, 3]), Ok(vec![4, 5, 6])]).into_async_read(); /// /// assert_eq!(stream.fill_buf().await?, vec![1, 2, 3]); /// stream.consume_unpin(2); /// /// assert_eq!(stream.fill_buf().await?, vec![3]); /// stream.consume_unpin(1); /// /// assert_eq!(stream.fill_buf().await?, vec![4, 5, 6]); /// stream.consume_unpin(3); /// /// assert_eq!(stream.fill_buf().await?, vec![]); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` fn fill_buf(&mut self) -> FillBuf<'_, Self> where Self: Unpin, { assert_future::, _>(FillBuf::new(self)) } /// A convenience for calling [`AsyncBufRead::consume`] on [`Unpin`] IO types. /// /// ```rust /// # futures::executor::block_on(async { /// use futures::{io::AsyncBufReadExt as _, stream::{iter, TryStreamExt as _}}; /// /// let mut stream = iter(vec![Ok(vec![1, 2, 3])]).into_async_read(); /// /// assert_eq!(stream.fill_buf().await?, vec![1, 2, 3]); /// stream.consume_unpin(2); /// /// assert_eq!(stream.fill_buf().await?, vec![3]); /// stream.consume_unpin(1); /// /// assert_eq!(stream.fill_buf().await?, vec![]); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` fn consume_unpin(&mut self, amt: usize) where Self: Unpin, { Pin::new(self).consume(amt) } /// Creates a future which will read all the bytes associated with this I/O /// object into `buf` until the delimiter `byte` or EOF is reached. /// This method is the async equivalent to [`BufRead::read_until`](std::io::BufRead::read_until). /// /// This function will read bytes from the underlying stream until the /// delimiter or EOF is found. Once found, all bytes up to, and including, /// the delimiter (if found) will be appended to `buf`. /// /// The returned future will resolve to the number of bytes read once the read /// operation is completed. /// /// In the case of an error the buffer and the object will be discarded, with /// the error yielded. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{AsyncBufReadExt, Cursor}; /// /// let mut cursor = Cursor::new(b"lorem-ipsum"); /// let mut buf = vec![]; /// /// // cursor is at 'l' /// let num_bytes = cursor.read_until(b'-', &mut buf).await?; /// assert_eq!(num_bytes, 6); /// assert_eq!(buf, b"lorem-"); /// buf.clear(); /// /// // cursor is at 'i' /// let num_bytes = cursor.read_until(b'-', &mut buf).await?; /// assert_eq!(num_bytes, 5); /// assert_eq!(buf, b"ipsum"); /// buf.clear(); /// /// // cursor is at EOF /// let num_bytes = cursor.read_until(b'-', &mut buf).await?; /// assert_eq!(num_bytes, 0); /// assert_eq!(buf, b""); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` fn read_until<'a>(&'a mut self, byte: u8, buf: &'a mut Vec) -> ReadUntil<'a, Self> where Self: Unpin, { assert_future::, _>(ReadUntil::new(self, byte, buf)) } /// Creates a future which will read all the bytes associated with this I/O /// object into `buf` until a newline (the 0xA byte) or EOF is reached, /// This method is the async equivalent to [`BufRead::read_line`](std::io::BufRead::read_line). /// /// This function will read bytes from the underlying stream until the /// newline delimiter (the 0xA byte) or EOF is found. Once found, all bytes /// up to, and including, the delimiter (if found) will be appended to /// `buf`. /// /// The returned future will resolve to the number of bytes read once the read /// operation is completed. /// /// In the case of an error the buffer and the object will be discarded, with /// the error yielded. /// /// # Errors /// /// This function has the same error semantics as [`read_until`] and will /// also return an error if the read bytes are not valid UTF-8. If an I/O /// error is encountered then `buf` may contain some bytes already read in /// the event that all data read so far was valid UTF-8. /// /// [`read_until`]: AsyncBufReadExt::read_until /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{AsyncBufReadExt, Cursor}; /// /// let mut cursor = Cursor::new(b"foo\nbar"); /// let mut buf = String::new(); /// /// // cursor is at 'f' /// let num_bytes = cursor.read_line(&mut buf).await?; /// assert_eq!(num_bytes, 4); /// assert_eq!(buf, "foo\n"); /// buf.clear(); /// /// // cursor is at 'b' /// let num_bytes = cursor.read_line(&mut buf).await?; /// assert_eq!(num_bytes, 3); /// assert_eq!(buf, "bar"); /// buf.clear(); /// /// // cursor is at EOF /// let num_bytes = cursor.read_line(&mut buf).await?; /// assert_eq!(num_bytes, 0); /// assert_eq!(buf, ""); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` fn read_line<'a>(&'a mut self, buf: &'a mut String) -> ReadLine<'a, Self> where Self: Unpin, { assert_future::, _>(ReadLine::new(self, buf)) } /// Returns a stream over the lines of this reader. /// This method is the async equivalent to [`BufRead::lines`](std::io::BufRead::lines). /// /// The stream returned from this function will yield instances of /// [`io::Result`]`<`[`String`]`>`. Each string returned will *not* have a newline /// byte (the 0xA byte) or CRLF (0xD, 0xA bytes) at the end. /// /// [`io::Result`]: std::io::Result /// [`String`]: String /// /// # Errors /// /// Each line of the stream has the same error semantics as [`AsyncBufReadExt::read_line`]. /// /// [`AsyncBufReadExt::read_line`]: AsyncBufReadExt::read_line /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{AsyncBufReadExt, Cursor}; /// use futures::stream::StreamExt; /// /// let cursor = Cursor::new(b"lorem\nipsum\xc2\r\ndolor"); /// /// let mut lines_stream = cursor.lines().map(|l| l.unwrap_or(String::from("invalid UTF_8"))); /// assert_eq!(lines_stream.next().await, Some(String::from("lorem"))); /// assert_eq!(lines_stream.next().await, Some(String::from("invalid UTF_8"))); /// assert_eq!(lines_stream.next().await, Some(String::from("dolor"))); /// assert_eq!(lines_stream.next().await, None); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` fn lines(self) -> Lines where Self: Sized, { assert_stream::, _>(Lines::new(self)) } } impl AsyncBufReadExt for R {} // Just a helper function to ensure the reader we're returning all have the // right implementations. pub(crate) fn assert_read(reader: R) -> R where R: AsyncRead, { reader } // Just a helper function to ensure the writer we're returning all have the // right implementations. pub(crate) fn assert_write(writer: W) -> W where W: AsyncWrite, { writer } futures-util-0.3.30/src/io/read.rs000064400000000000000000000015311046102023000150360ustar 00000000000000use crate::io::AsyncRead; use futures_core::future::Future; use futures_core::task::{Context, Poll}; use std::io; use std::pin::Pin; /// Future for the [`read`](super::AsyncReadExt::read) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Read<'a, R: ?Sized> { reader: &'a mut R, buf: &'a mut [u8], } impl Unpin for Read<'_, R> {} impl<'a, R: AsyncRead + ?Sized + Unpin> Read<'a, R> { pub(super) fn new(reader: &'a mut R, buf: &'a mut [u8]) -> Self { Self { reader, buf } } } impl Future for Read<'_, R> { type Output = io::Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = &mut *self; Pin::new(&mut this.reader).poll_read(cx, this.buf) } } futures-util-0.3.30/src/io/read_exact.rs000064400000000000000000000023711046102023000162250ustar 00000000000000use crate::io::AsyncRead; use futures_core::future::Future; use futures_core::ready; use futures_core::task::{Context, Poll}; use std::io; use std::mem; use std::pin::Pin; /// Future for the [`read_exact`](super::AsyncReadExt::read_exact) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct ReadExact<'a, R: ?Sized> { reader: &'a mut R, buf: &'a mut [u8], } impl Unpin for ReadExact<'_, R> {} impl<'a, R: AsyncRead + ?Sized + Unpin> ReadExact<'a, R> { pub(super) fn new(reader: &'a mut R, buf: &'a mut [u8]) -> Self { Self { reader, buf } } } impl Future for ReadExact<'_, R> { type Output = io::Result<()>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = &mut *self; while !this.buf.is_empty() { let n = ready!(Pin::new(&mut this.reader).poll_read(cx, this.buf))?; { let (_, rest) = mem::take(&mut this.buf).split_at_mut(n); this.buf = rest; } if n == 0 { return Poll::Ready(Err(io::ErrorKind::UnexpectedEof.into())); } } Poll::Ready(Ok(())) } } futures-util-0.3.30/src/io/read_line.rs000064400000000000000000000035231046102023000160500ustar 00000000000000use super::read_until::read_until_internal; use futures_core::future::Future; use futures_core::ready; use futures_core::task::{Context, Poll}; use futures_io::AsyncBufRead; use std::io; use std::mem; use std::pin::Pin; use std::str; /// Future for the [`read_line`](super::AsyncBufReadExt::read_line) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct ReadLine<'a, R: ?Sized> { reader: &'a mut R, buf: &'a mut String, bytes: Vec, read: usize, } impl Unpin for ReadLine<'_, R> {} impl<'a, R: AsyncBufRead + ?Sized + Unpin> ReadLine<'a, R> { pub(super) fn new(reader: &'a mut R, buf: &'a mut String) -> Self { Self { reader, bytes: mem::take(buf).into_bytes(), buf, read: 0 } } } pub(super) fn read_line_internal( reader: Pin<&mut R>, cx: &mut Context<'_>, buf: &mut String, bytes: &mut Vec, read: &mut usize, ) -> Poll> { let ret = ready!(read_until_internal(reader, cx, b'\n', bytes, read)); if str::from_utf8(bytes).is_err() { bytes.clear(); Poll::Ready(ret.and_then(|_| { Err(io::Error::new(io::ErrorKind::InvalidData, "stream did not contain valid UTF-8")) })) } else { debug_assert!(buf.is_empty()); debug_assert_eq!(*read, 0); // Safety: `bytes` is a valid UTF-8 because `str::from_utf8` returned `Ok`. mem::swap(unsafe { buf.as_mut_vec() }, bytes); Poll::Ready(ret) } } impl Future for ReadLine<'_, R> { type Output = io::Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let Self { reader, buf, bytes, read } = &mut *self; read_line_internal(Pin::new(reader), cx, buf, bytes, read) } } futures-util-0.3.30/src/io/read_to_end.rs000064400000000000000000000056061046102023000163750ustar 00000000000000use futures_core::future::Future; use futures_core::ready; use futures_core::task::{Context, Poll}; use futures_io::AsyncRead; use std::io; use std::pin::Pin; use std::vec::Vec; /// Future for the [`read_to_end`](super::AsyncReadExt::read_to_end) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct ReadToEnd<'a, R: ?Sized> { reader: &'a mut R, buf: &'a mut Vec, start_len: usize, } impl Unpin for ReadToEnd<'_, R> {} impl<'a, R: AsyncRead + ?Sized + Unpin> ReadToEnd<'a, R> { pub(super) fn new(reader: &'a mut R, buf: &'a mut Vec) -> Self { let start_len = buf.len(); Self { reader, buf, start_len } } } struct Guard<'a> { buf: &'a mut Vec, len: usize, } impl Drop for Guard<'_> { fn drop(&mut self) { unsafe { self.buf.set_len(self.len); } } } // This uses an adaptive system to extend the vector when it fills. We want to // avoid paying to allocate and zero a huge chunk of memory if the reader only // has 4 bytes while still making large reads if the reader does have a ton // of data to return. Simply tacking on an extra DEFAULT_BUF_SIZE space every // time is 4,500 times (!) slower than this if the reader has a very small // amount of data to return. // // Because we're extending the buffer with uninitialized data for trusted // readers, we need to make sure to truncate that if any of this panics. pub(super) fn read_to_end_internal( mut rd: Pin<&mut R>, cx: &mut Context<'_>, buf: &mut Vec, start_len: usize, ) -> Poll> { let mut g = Guard { len: buf.len(), buf }; loop { if g.len == g.buf.len() { unsafe { g.buf.reserve(32); let capacity = g.buf.capacity(); g.buf.set_len(capacity); super::initialize(&rd, &mut g.buf[g.len..]); } } let buf = &mut g.buf[g.len..]; match ready!(rd.as_mut().poll_read(cx, buf)) { Ok(0) => return Poll::Ready(Ok(g.len - start_len)), Ok(n) => { // We can't allow bogus values from read. If it is too large, the returned vec could have its length // set past its capacity, or if it overflows the vec could be shortened which could create an invalid // string if this is called via read_to_string. assert!(n <= buf.len()); g.len += n; } Err(e) => return Poll::Ready(Err(e)), } } } impl Future for ReadToEnd<'_, A> where A: AsyncRead + ?Sized + Unpin, { type Output = io::Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = &mut *self; read_to_end_internal(Pin::new(&mut this.reader), cx, this.buf, this.start_len) } } futures-util-0.3.30/src/io/read_to_string.rs000064400000000000000000000035501046102023000171310ustar 00000000000000use super::read_to_end::read_to_end_internal; use futures_core::future::Future; use futures_core::ready; use futures_core::task::{Context, Poll}; use futures_io::AsyncRead; use std::pin::Pin; use std::vec::Vec; use std::{io, mem, str}; /// Future for the [`read_to_string`](super::AsyncReadExt::read_to_string) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct ReadToString<'a, R: ?Sized> { reader: &'a mut R, buf: &'a mut String, bytes: Vec, start_len: usize, } impl Unpin for ReadToString<'_, R> {} impl<'a, R: AsyncRead + ?Sized + Unpin> ReadToString<'a, R> { pub(super) fn new(reader: &'a mut R, buf: &'a mut String) -> Self { let start_len = buf.len(); Self { reader, bytes: mem::take(buf).into_bytes(), buf, start_len } } } fn read_to_string_internal( reader: Pin<&mut R>, cx: &mut Context<'_>, buf: &mut String, bytes: &mut Vec, start_len: usize, ) -> Poll> { let ret = ready!(read_to_end_internal(reader, cx, bytes, start_len)); if str::from_utf8(bytes).is_err() { Poll::Ready(ret.and_then(|_| { Err(io::Error::new(io::ErrorKind::InvalidData, "stream did not contain valid UTF-8")) })) } else { debug_assert!(buf.is_empty()); // Safety: `bytes` is a valid UTF-8 because `str::from_utf8` returned `Ok`. mem::swap(unsafe { buf.as_mut_vec() }, bytes); Poll::Ready(ret) } } impl Future for ReadToString<'_, A> where A: AsyncRead + ?Sized + Unpin, { type Output = io::Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let Self { reader, buf, bytes, start_len } = &mut *self; read_to_string_internal(Pin::new(reader), cx, buf, bytes, *start_len) } } futures-util-0.3.30/src/io/read_until.rs000064400000000000000000000034301046102023000162510ustar 00000000000000use futures_core::future::Future; use futures_core::ready; use futures_core::task::{Context, Poll}; use futures_io::AsyncBufRead; use std::io; use std::mem; use std::pin::Pin; /// Future for the [`read_until`](super::AsyncBufReadExt::read_until) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct ReadUntil<'a, R: ?Sized> { reader: &'a mut R, byte: u8, buf: &'a mut Vec, read: usize, } impl Unpin for ReadUntil<'_, R> {} impl<'a, R: AsyncBufRead + ?Sized + Unpin> ReadUntil<'a, R> { pub(super) fn new(reader: &'a mut R, byte: u8, buf: &'a mut Vec) -> Self { Self { reader, byte, buf, read: 0 } } } pub(super) fn read_until_internal( mut reader: Pin<&mut R>, cx: &mut Context<'_>, byte: u8, buf: &mut Vec, read: &mut usize, ) -> Poll> { loop { let (done, used) = { let available = ready!(reader.as_mut().poll_fill_buf(cx))?; if let Some(i) = memchr::memchr(byte, available) { buf.extend_from_slice(&available[..=i]); (true, i + 1) } else { buf.extend_from_slice(available); (false, available.len()) } }; reader.as_mut().consume(used); *read += used; if done || used == 0 { return Poll::Ready(Ok(mem::replace(read, 0))); } } } impl Future for ReadUntil<'_, R> { type Output = io::Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let Self { reader, byte, buf, read } = &mut *self; read_until_internal(Pin::new(reader), cx, *byte, buf, read) } } futures-util-0.3.30/src/io/read_vectored.rs000064400000000000000000000017041046102023000167330ustar 00000000000000use crate::io::AsyncRead; use futures_core::future::Future; use futures_core::task::{Context, Poll}; use std::io::{self, IoSliceMut}; use std::pin::Pin; /// Future for the [`read_vectored`](super::AsyncReadExt::read_vectored) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct ReadVectored<'a, R: ?Sized> { reader: &'a mut R, bufs: &'a mut [IoSliceMut<'a>], } impl Unpin for ReadVectored<'_, R> {} impl<'a, R: AsyncRead + ?Sized + Unpin> ReadVectored<'a, R> { pub(super) fn new(reader: &'a mut R, bufs: &'a mut [IoSliceMut<'a>]) -> Self { Self { reader, bufs } } } impl Future for ReadVectored<'_, R> { type Output = io::Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = &mut *self; Pin::new(&mut this.reader).poll_read_vectored(cx, this.bufs) } } futures-util-0.3.30/src/io/repeat.rs000064400000000000000000000031601046102023000154030ustar 00000000000000use futures_core::ready; use futures_core::task::{Context, Poll}; use futures_io::{AsyncRead, IoSliceMut}; use std::fmt; use std::io; use std::pin::Pin; /// Reader for the [`repeat()`] function. #[must_use = "readers do nothing unless polled"] pub struct Repeat { byte: u8, } /// Creates an instance of a reader that infinitely repeats one byte. /// /// All reads from this reader will succeed by filling the specified buffer with /// the given byte. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{self, AsyncReadExt}; /// /// let mut buffer = [0; 3]; /// let mut reader = io::repeat(0b101); /// reader.read_exact(&mut buffer).await.unwrap(); /// assert_eq!(buffer, [0b101, 0b101, 0b101]); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` pub fn repeat(byte: u8) -> Repeat { Repeat { byte } } impl AsyncRead for Repeat { #[inline] fn poll_read( self: Pin<&mut Self>, _: &mut Context<'_>, buf: &mut [u8], ) -> Poll> { for slot in &mut *buf { *slot = self.byte; } Poll::Ready(Ok(buf.len())) } #[inline] fn poll_read_vectored( mut self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>], ) -> Poll> { let mut nwritten = 0; for buf in bufs { nwritten += ready!(self.as_mut().poll_read(cx, buf))?; } Poll::Ready(Ok(nwritten)) } } impl fmt::Debug for Repeat { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.pad("Repeat { .. }") } } futures-util-0.3.30/src/io/seek.rs000064400000000000000000000015271046102023000150570ustar 00000000000000use crate::io::{AsyncSeek, SeekFrom}; use futures_core::future::Future; use futures_core::task::{Context, Poll}; use std::io; use std::pin::Pin; /// Future for the [`seek`](crate::io::AsyncSeekExt::seek) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Seek<'a, S: ?Sized> { seek: &'a mut S, pos: SeekFrom, } impl Unpin for Seek<'_, S> {} impl<'a, S: AsyncSeek + ?Sized + Unpin> Seek<'a, S> { pub(super) fn new(seek: &'a mut S, pos: SeekFrom) -> Self { Self { seek, pos } } } impl Future for Seek<'_, S> { type Output = io::Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = &mut *self; Pin::new(&mut this.seek).poll_seek(cx, this.pos) } } futures-util-0.3.30/src/io/sink.rs000064400000000000000000000033031046102023000150660ustar 00000000000000use futures_core::task::{Context, Poll}; use futures_io::{AsyncWrite, IoSlice}; use std::fmt; use std::io; use std::pin::Pin; /// Writer for the [`sink()`] function. #[must_use = "writers do nothing unless polled"] pub struct Sink { _priv: (), } /// Creates an instance of a writer which will successfully consume all data. /// /// All calls to `poll_write` on the returned instance will return `Poll::Ready(Ok(buf.len()))` /// and the contents of the buffer will not be inspected. /// /// # Examples /// /// ```rust /// # futures::executor::block_on(async { /// use futures::io::{self, AsyncWriteExt}; /// /// let buffer = vec![1, 2, 3, 5, 8]; /// let mut writer = io::sink(); /// let num_bytes = writer.write(&buffer).await?; /// assert_eq!(num_bytes, 5); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` pub fn sink() -> Sink { Sink { _priv: () } } impl AsyncWrite for Sink { #[inline] fn poll_write( self: Pin<&mut Self>, _: &mut Context<'_>, buf: &[u8], ) -> Poll> { Poll::Ready(Ok(buf.len())) } #[inline] fn poll_write_vectored( self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll> { Poll::Ready(Ok(bufs.iter().map(|b| b.len()).sum())) } #[inline] fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) } #[inline] fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) } } impl fmt::Debug for Sink { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.pad("Sink { .. }") } } futures-util-0.3.30/src/io/split.rs000064400000000000000000000102321046102023000152540ustar 00000000000000use crate::lock::BiLock; use core::fmt; use futures_core::ready; use futures_core::task::{Context, Poll}; use futures_io::{AsyncRead, AsyncWrite, IoSlice, IoSliceMut}; use std::io; use std::pin::Pin; /// The readable half of an object returned from `AsyncRead::split`. #[derive(Debug)] pub struct ReadHalf { handle: BiLock, } /// The writable half of an object returned from `AsyncRead::split`. #[derive(Debug)] pub struct WriteHalf { handle: BiLock, } fn lock_and_then(lock: &BiLock, cx: &mut Context<'_>, f: F) -> Poll> where F: FnOnce(Pin<&mut T>, &mut Context<'_>) -> Poll>, { let mut l = ready!(lock.poll_lock(cx)); f(l.as_pin_mut(), cx) } pub(super) fn split(t: T) -> (ReadHalf, WriteHalf) { let (a, b) = BiLock::new(t); (ReadHalf { handle: a }, WriteHalf { handle: b }) } impl ReadHalf { /// Checks if this `ReadHalf` and some `WriteHalf` were split from the same stream. pub fn is_pair_of(&self, other: &WriteHalf) -> bool { self.handle.is_pair_of(&other.handle) } } impl ReadHalf { /// Attempts to put the two "halves" of a split `AsyncRead + AsyncWrite` back /// together. Succeeds only if the `ReadHalf` and `WriteHalf` are /// a matching pair originating from the same call to `AsyncReadExt::split`. pub fn reunite(self, other: WriteHalf) -> Result> { self.handle .reunite(other.handle) .map_err(|err| ReuniteError(ReadHalf { handle: err.0 }, WriteHalf { handle: err.1 })) } } impl WriteHalf { /// Checks if this `WriteHalf` and some `ReadHalf` were split from the same stream. pub fn is_pair_of(&self, other: &ReadHalf) -> bool { self.handle.is_pair_of(&other.handle) } } impl WriteHalf { /// Attempts to put the two "halves" of a split `AsyncRead + AsyncWrite` back /// together. Succeeds only if the `ReadHalf` and `WriteHalf` are /// a matching pair originating from the same call to `AsyncReadExt::split`. pub fn reunite(self, other: ReadHalf) -> Result> { other.reunite(self) } } impl AsyncRead for ReadHalf { fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll> { lock_and_then(&self.handle, cx, |l, cx| l.poll_read(cx, buf)) } fn poll_read_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>], ) -> Poll> { lock_and_then(&self.handle, cx, |l, cx| l.poll_read_vectored(cx, bufs)) } } impl AsyncWrite for WriteHalf { fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll> { lock_and_then(&self.handle, cx, |l, cx| l.poll_write(cx, buf)) } fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll> { lock_and_then(&self.handle, cx, |l, cx| l.poll_write_vectored(cx, bufs)) } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { lock_and_then(&self.handle, cx, |l, cx| l.poll_flush(cx)) } fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { lock_and_then(&self.handle, cx, |l, cx| l.poll_close(cx)) } } /// Error indicating a `ReadHalf` and `WriteHalf` were not two halves /// of a `AsyncRead + AsyncWrite`, and thus could not be `reunite`d. pub struct ReuniteError(pub ReadHalf, pub WriteHalf); impl fmt::Debug for ReuniteError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("ReuniteError").field(&"...").finish() } } impl fmt::Display for ReuniteError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "tried to reunite a ReadHalf and WriteHalf that don't form a pair") } } #[cfg(feature = "std")] impl std::error::Error for ReuniteError {} futures-util-0.3.30/src/io/take.rs000064400000000000000000000071301046102023000150500ustar 00000000000000use futures_core::ready; use futures_core::task::{Context, Poll}; use futures_io::{AsyncBufRead, AsyncRead}; use pin_project_lite::pin_project; use std::pin::Pin; use std::{cmp, io}; pin_project! { /// Reader for the [`take`](super::AsyncReadExt::take) method. #[derive(Debug)] #[must_use = "readers do nothing unless you `.await` or poll them"] pub struct Take { #[pin] inner: R, limit: u64, } } impl Take { pub(super) fn new(inner: R, limit: u64) -> Self { Self { inner, limit } } /// Returns the remaining number of bytes that can be /// read before this instance will return EOF. /// /// # Note /// /// This instance may reach `EOF` after reading fewer bytes than indicated by /// this method if the underlying [`AsyncRead`] instance reaches EOF. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{AsyncReadExt, Cursor}; /// /// let reader = Cursor::new(&b"12345678"[..]); /// let mut buffer = [0; 2]; /// /// let mut take = reader.take(4); /// let n = take.read(&mut buffer).await?; /// /// assert_eq!(take.limit(), 2); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` pub fn limit(&self) -> u64 { self.limit } /// Sets the number of bytes that can be read before this instance will /// return EOF. This is the same as constructing a new `Take` instance, so /// the amount of bytes read and the previous limit value don't matter when /// calling this method. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::io::{AsyncReadExt, Cursor}; /// /// let reader = Cursor::new(&b"12345678"[..]); /// let mut buffer = [0; 4]; /// /// let mut take = reader.take(4); /// let n = take.read(&mut buffer).await?; /// /// assert_eq!(n, 4); /// assert_eq!(take.limit(), 0); /// /// take.set_limit(10); /// let n = take.read(&mut buffer).await?; /// assert_eq!(n, 4); /// /// # Ok::<(), Box>(()) }).unwrap(); /// ``` pub fn set_limit(&mut self, limit: u64) { self.limit = limit } delegate_access_inner!(inner, R, ()); } impl AsyncRead for Take { fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll> { let this = self.project(); if *this.limit == 0 { return Poll::Ready(Ok(0)); } let max = cmp::min(buf.len() as u64, *this.limit) as usize; let n = ready!(this.inner.poll_read(cx, &mut buf[..max]))?; *this.limit -= n as u64; Poll::Ready(Ok(n)) } } impl AsyncBufRead for Take { fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); // Don't call into inner reader at all at EOF because it may still block if *this.limit == 0 { return Poll::Ready(Ok(&[])); } let buf = ready!(this.inner.poll_fill_buf(cx)?); let cap = cmp::min(buf.len() as u64, *this.limit) as usize; Poll::Ready(Ok(&buf[..cap])) } fn consume(self: Pin<&mut Self>, amt: usize) { let this = self.project(); // Don't let callers reset the limit by passing an overlarge value let amt = cmp::min(amt as u64, *this.limit) as usize; *this.limit -= amt as u64; this.inner.consume(amt); } } futures-util-0.3.30/src/io/window.rs000064400000000000000000000065471046102023000154460ustar 00000000000000use std::ops::{Bound, Range, RangeBounds}; /// An owned window around an underlying buffer. /// /// Normally slices work great for considering sub-portions of a buffer, but /// unfortunately a slice is a *borrowed* type in Rust which has an associated /// lifetime. When working with future and async I/O these lifetimes are not /// always appropriate, and are sometimes difficult to store in tasks. This /// type strives to fill this gap by providing an "owned slice" around an /// underlying buffer of bytes. /// /// A `Window` wraps an underlying buffer, `T`, and has configurable /// start/end indexes to alter the behavior of the `AsRef<[u8]>` implementation /// that this type carries. /// /// This type can be particularly useful when working with the `write_all` /// combinator in this crate. Data can be sliced via `Window`, consumed by /// `write_all`, and then earned back once the write operation finishes through /// the `into_inner` method on this type. #[derive(Debug)] pub struct Window { inner: T, range: Range, } impl> Window { /// Creates a new window around the buffer `t` defaulting to the entire /// slice. /// /// Further methods can be called on the returned `Window` to alter the /// window into the data provided. pub fn new(t: T) -> Self { Self { range: 0..t.as_ref().len(), inner: t } } /// Gets a shared reference to the underlying buffer inside of this /// `Window`. pub fn get_ref(&self) -> &T { &self.inner } /// Gets a mutable reference to the underlying buffer inside of this /// `Window`. pub fn get_mut(&mut self) -> &mut T { &mut self.inner } /// Consumes this `Window`, returning the underlying buffer. pub fn into_inner(self) -> T { self.inner } /// Returns the starting index of this window into the underlying buffer /// `T`. pub fn start(&self) -> usize { self.range.start } /// Returns the end index of this window into the underlying buffer /// `T`. pub fn end(&self) -> usize { self.range.end } /// Changes the range of this window to the range specified. /// /// # Panics /// /// This method will panic if `range` is out of bounds for the underlying /// slice or if [`start_bound()`] of `range` comes after the [`end_bound()`]. /// /// [`start_bound()`]: std::ops::RangeBounds::start_bound /// [`end_bound()`]: std::ops::RangeBounds::end_bound pub fn set>(&mut self, range: R) { let start = match range.start_bound() { Bound::Included(n) => *n, Bound::Excluded(n) => *n + 1, Bound::Unbounded => 0, }; let end = match range.end_bound() { Bound::Included(n) => *n + 1, Bound::Excluded(n) => *n, Bound::Unbounded => self.inner.as_ref().len(), }; assert!(end <= self.inner.as_ref().len()); assert!(start <= end); self.range.start = start; self.range.end = end; } } impl> AsRef<[u8]> for Window { fn as_ref(&self) -> &[u8] { &self.inner.as_ref()[self.range.start..self.range.end] } } impl> AsMut<[u8]> for Window { fn as_mut(&mut self) -> &mut [u8] { &mut self.inner.as_mut()[self.range.start..self.range.end] } } futures-util-0.3.30/src/io/write.rs000064400000000000000000000015341046102023000152600ustar 00000000000000use crate::io::AsyncWrite; use futures_core::future::Future; use futures_core::task::{Context, Poll}; use std::io; use std::pin::Pin; /// Future for the [`write`](super::AsyncWriteExt::write) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Write<'a, W: ?Sized> { writer: &'a mut W, buf: &'a [u8], } impl Unpin for Write<'_, W> {} impl<'a, W: AsyncWrite + ?Sized + Unpin> Write<'a, W> { pub(super) fn new(writer: &'a mut W, buf: &'a [u8]) -> Self { Self { writer, buf } } } impl Future for Write<'_, W> { type Output = io::Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = &mut *self; Pin::new(&mut this.writer).poll_write(cx, this.buf) } } futures-util-0.3.30/src/io/write_all.rs000064400000000000000000000023541046102023000161110ustar 00000000000000use futures_core::future::Future; use futures_core::ready; use futures_core::task::{Context, Poll}; use futures_io::AsyncWrite; use std::io; use std::mem; use std::pin::Pin; /// Future for the [`write_all`](super::AsyncWriteExt::write_all) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct WriteAll<'a, W: ?Sized> { writer: &'a mut W, buf: &'a [u8], } impl Unpin for WriteAll<'_, W> {} impl<'a, W: AsyncWrite + ?Sized + Unpin> WriteAll<'a, W> { pub(super) fn new(writer: &'a mut W, buf: &'a [u8]) -> Self { Self { writer, buf } } } impl Future for WriteAll<'_, W> { type Output = io::Result<()>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = &mut *self; while !this.buf.is_empty() { let n = ready!(Pin::new(&mut this.writer).poll_write(cx, this.buf))?; { let (_, rest) = mem::take(&mut this.buf).split_at(n); this.buf = rest; } if n == 0 { return Poll::Ready(Err(io::ErrorKind::WriteZero.into())); } } Poll::Ready(Ok(())) } } futures-util-0.3.30/src/io/write_all_vectored.rs000064400000000000000000000152751046102023000200120ustar 00000000000000use futures_core::future::Future; use futures_core::ready; use futures_core::task::{Context, Poll}; use futures_io::AsyncWrite; use futures_io::IoSlice; use std::io; use std::pin::Pin; /// Future for the /// [`write_all_vectored`](super::AsyncWriteExt::write_all_vectored) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct WriteAllVectored<'a, W: ?Sized + Unpin> { writer: &'a mut W, bufs: &'a mut [IoSlice<'a>], } impl Unpin for WriteAllVectored<'_, W> {} impl<'a, W: AsyncWrite + ?Sized + Unpin> WriteAllVectored<'a, W> { pub(super) fn new(writer: &'a mut W, mut bufs: &'a mut [IoSlice<'a>]) -> Self { IoSlice::advance_slices(&mut bufs, 0); Self { writer, bufs } } } impl Future for WriteAllVectored<'_, W> { type Output = io::Result<()>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = &mut *self; while !this.bufs.is_empty() { let n = ready!(Pin::new(&mut this.writer).poll_write_vectored(cx, this.bufs))?; if n == 0 { return Poll::Ready(Err(io::ErrorKind::WriteZero.into())); } else { IoSlice::advance_slices(&mut this.bufs, n); } } Poll::Ready(Ok(())) } } #[cfg(test)] mod tests { use std::cmp::min; use std::future::Future; use std::io; use std::pin::Pin; use std::task::{Context, Poll}; use crate::io::{AsyncWrite, AsyncWriteExt, IoSlice}; use crate::task::noop_waker; /// Create a new writer that reads from at most `n_bufs` and reads /// `per_call` bytes (in total) per call to write. fn test_writer(n_bufs: usize, per_call: usize) -> TestWriter { TestWriter { n_bufs, per_call, written: Vec::new() } } // TODO: maybe move this the future-test crate? struct TestWriter { n_bufs: usize, per_call: usize, written: Vec, } impl AsyncWrite for TestWriter { fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll> { self.poll_write_vectored(cx, &[IoSlice::new(buf)]) } fn poll_write_vectored( mut self: Pin<&mut Self>, _cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll> { let mut left = self.per_call; let mut written = 0; for buf in bufs.iter().take(self.n_bufs) { let n = min(left, buf.len()); self.written.extend_from_slice(&buf[0..n]); left -= n; written += n; } Poll::Ready(Ok(written)) } fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) } fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) } } // TODO: maybe move this the future-test crate? macro_rules! assert_poll_ok { ($e:expr, $expected:expr) => { let expected = $expected; match $e { Poll::Ready(Ok(ok)) if ok == expected => {} got => { panic!("unexpected result, got: {:?}, wanted: Ready(Ok({:?}))", got, expected) } } }; } #[test] fn test_writer_read_from_one_buf() { let waker = noop_waker(); let mut cx = Context::from_waker(&waker); let mut dst = test_writer(1, 2); let mut dst = Pin::new(&mut dst); assert_poll_ok!(dst.as_mut().poll_write(&mut cx, &[]), 0); assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, &[]), 0); // Read at most 2 bytes. assert_poll_ok!(dst.as_mut().poll_write(&mut cx, &[1, 1, 1]), 2); let bufs = &[IoSlice::new(&[2, 2, 2])]; assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, bufs), 2); // Only read from first buf. let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4, 4])]; assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, bufs), 1); assert_eq!(dst.written, &[1, 1, 2, 2, 3]); } #[test] fn test_writer_read_from_multiple_bufs() { let waker = noop_waker(); let mut cx = Context::from_waker(&waker); let mut dst = test_writer(3, 3); let mut dst = Pin::new(&mut dst); // Read at most 3 bytes from two buffers. let bufs = &[IoSlice::new(&[1]), IoSlice::new(&[2, 2, 2])]; assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, bufs), 3); // Read at most 3 bytes from three buffers. let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4]), IoSlice::new(&[5, 5])]; assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, bufs), 3); assert_eq!(dst.written, &[1, 2, 2, 3, 4, 5]); } #[test] fn test_write_all_vectored() { let waker = noop_waker(); let mut cx = Context::from_waker(&waker); #[rustfmt::skip] // Becomes unreadable otherwise. let tests: Vec<(_, &'static [u8])> = vec![ (vec![], &[]), (vec![IoSlice::new(&[]), IoSlice::new(&[])], &[]), (vec![IoSlice::new(&[1])], &[1]), (vec![IoSlice::new(&[1, 2])], &[1, 2]), (vec![IoSlice::new(&[1, 2, 3])], &[1, 2, 3]), (vec![IoSlice::new(&[1, 2, 3, 4])], &[1, 2, 3, 4]), (vec![IoSlice::new(&[1, 2, 3, 4, 5])], &[1, 2, 3, 4, 5]), (vec![IoSlice::new(&[1]), IoSlice::new(&[2])], &[1, 2]), (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2])], &[1, 1, 2, 2]), (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 1, 2, 2, 2]), (vec![IoSlice::new(&[1, 1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 1, 2, 2, 2, 2]), (vec![IoSlice::new(&[1]), IoSlice::new(&[2]), IoSlice::new(&[3])], &[1, 2, 3]), (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3])], &[1, 1, 2, 2, 3, 3]), (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 1, 1, 2, 2, 2, 3, 3, 3]), ]; for (mut input, wanted) in tests { let mut dst = test_writer(2, 2); { let mut future = dst.write_all_vectored(&mut *input); match Pin::new(&mut future).poll(&mut cx) { Poll::Ready(Ok(())) => {} other => panic!("unexpected result polling future: {:?}", other), } } assert_eq!(&*dst.written, &*wanted); } } } futures-util-0.3.30/src/io/write_vectored.rs000064400000000000000000000016761046102023000171620ustar 00000000000000use crate::io::AsyncWrite; use futures_core::future::Future; use futures_core::task::{Context, Poll}; use std::io::{self, IoSlice}; use std::pin::Pin; /// Future for the [`write_vectored`](super::AsyncWriteExt::write_vectored) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct WriteVectored<'a, W: ?Sized> { writer: &'a mut W, bufs: &'a [IoSlice<'a>], } impl Unpin for WriteVectored<'_, W> {} impl<'a, W: AsyncWrite + ?Sized + Unpin> WriteVectored<'a, W> { pub(super) fn new(writer: &'a mut W, bufs: &'a [IoSlice<'a>]) -> Self { Self { writer, bufs } } } impl Future for WriteVectored<'_, W> { type Output = io::Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = &mut *self; Pin::new(&mut this.writer).poll_write_vectored(cx, this.bufs) } } futures-util-0.3.30/src/lib.rs000064400000000000000000000265221046102023000142710ustar 00000000000000//! Combinators and utilities for working with `Future`s, `Stream`s, `Sink`s, //! and the `AsyncRead` and `AsyncWrite` traits. #![cfg_attr(feature = "write-all-vectored", feature(io_slice_advance))] #![cfg_attr(not(feature = "std"), no_std)] #![warn( missing_debug_implementations, missing_docs, rust_2018_idioms, single_use_lifetimes, unreachable_pub )] #![doc(test( no_crate_inject, attr( deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code, unused_assignments, unused_variables) ) ))] #![cfg_attr(docsrs, feature(doc_cfg))] #[cfg(all(feature = "bilock", not(feature = "unstable")))] compile_error!("The `bilock` feature requires the `unstable` feature as an explicit opt-in to unstable features"); #[cfg(feature = "alloc")] extern crate alloc; // Macro re-exports pub use futures_core::ready; pub use pin_utils::pin_mut; #[cfg(feature = "async-await")] #[macro_use] mod async_await; #[cfg(feature = "async-await")] #[doc(hidden)] pub use self::async_await::*; // Not public API. #[cfg(feature = "async-await")] #[doc(hidden)] pub mod __private { pub use crate::*; pub use core::{ option::Option::{self, None, Some}, pin::Pin, result::Result::{Err, Ok}, }; pub mod async_await { pub use crate::async_await::*; } } #[cfg(feature = "sink")] macro_rules! delegate_sink { ($field:ident, $item:ty) => { fn poll_ready( self: core::pin::Pin<&mut Self>, cx: &mut core::task::Context<'_>, ) -> core::task::Poll> { self.project().$field.poll_ready(cx) } fn start_send(self: core::pin::Pin<&mut Self>, item: $item) -> Result<(), Self::Error> { self.project().$field.start_send(item) } fn poll_flush( self: core::pin::Pin<&mut Self>, cx: &mut core::task::Context<'_>, ) -> core::task::Poll> { self.project().$field.poll_flush(cx) } fn poll_close( self: core::pin::Pin<&mut Self>, cx: &mut core::task::Context<'_>, ) -> core::task::Poll> { self.project().$field.poll_close(cx) } }; } macro_rules! delegate_future { ($field:ident) => { fn poll( self: core::pin::Pin<&mut Self>, cx: &mut core::task::Context<'_>, ) -> core::task::Poll { self.project().$field.poll(cx) } }; } macro_rules! delegate_stream { ($field:ident) => { fn poll_next( self: core::pin::Pin<&mut Self>, cx: &mut core::task::Context<'_>, ) -> core::task::Poll> { self.project().$field.poll_next(cx) } fn size_hint(&self) -> (usize, Option) { self.$field.size_hint() } }; } #[cfg(feature = "io")] #[cfg(feature = "std")] macro_rules! delegate_async_write { ($field:ident) => { fn poll_write( self: core::pin::Pin<&mut Self>, cx: &mut core::task::Context<'_>, buf: &[u8], ) -> core::task::Poll> { self.project().$field.poll_write(cx, buf) } fn poll_write_vectored( self: core::pin::Pin<&mut Self>, cx: &mut core::task::Context<'_>, bufs: &[std::io::IoSlice<'_>], ) -> core::task::Poll> { self.project().$field.poll_write_vectored(cx, bufs) } fn poll_flush( self: core::pin::Pin<&mut Self>, cx: &mut core::task::Context<'_>, ) -> core::task::Poll> { self.project().$field.poll_flush(cx) } fn poll_close( self: core::pin::Pin<&mut Self>, cx: &mut core::task::Context<'_>, ) -> core::task::Poll> { self.project().$field.poll_close(cx) } }; } #[cfg(feature = "io")] #[cfg(feature = "std")] macro_rules! delegate_async_read { ($field:ident) => { fn poll_read( self: core::pin::Pin<&mut Self>, cx: &mut core::task::Context<'_>, buf: &mut [u8], ) -> core::task::Poll> { self.project().$field.poll_read(cx, buf) } fn poll_read_vectored( self: core::pin::Pin<&mut Self>, cx: &mut core::task::Context<'_>, bufs: &mut [std::io::IoSliceMut<'_>], ) -> core::task::Poll> { self.project().$field.poll_read_vectored(cx, bufs) } }; } #[cfg(feature = "io")] #[cfg(feature = "std")] macro_rules! delegate_async_buf_read { ($field:ident) => { fn poll_fill_buf( self: core::pin::Pin<&mut Self>, cx: &mut core::task::Context<'_>, ) -> core::task::Poll> { self.project().$field.poll_fill_buf(cx) } fn consume(self: core::pin::Pin<&mut Self>, amt: usize) { self.project().$field.consume(amt) } }; } macro_rules! delegate_access_inner { ($field:ident, $inner:ty, ($($ind:tt)*)) => { /// Acquires a reference to the underlying sink or stream that this combinator is /// pulling from. pub fn get_ref(&self) -> &$inner { (&self.$field) $($ind get_ref())* } /// Acquires a mutable reference to the underlying sink or stream that this /// combinator is pulling from. /// /// Note that care must be taken to avoid tampering with the state of the /// sink or stream which may otherwise confuse this combinator. pub fn get_mut(&mut self) -> &mut $inner { (&mut self.$field) $($ind get_mut())* } /// Acquires a pinned mutable reference to the underlying sink or stream that this /// combinator is pulling from. /// /// Note that care must be taken to avoid tampering with the state of the /// sink or stream which may otherwise confuse this combinator. pub fn get_pin_mut(self: core::pin::Pin<&mut Self>) -> core::pin::Pin<&mut $inner> { self.project().$field $($ind get_pin_mut())* } /// Consumes this combinator, returning the underlying sink or stream. /// /// Note that this may discard intermediate state of this combinator, so /// care should be taken to avoid losing resources when this is called. pub fn into_inner(self) -> $inner { self.$field $($ind into_inner())* } } } macro_rules! delegate_all { (@trait Future $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => { impl<$($arg),*> futures_core::future::Future for $name<$($arg),*> where $t: futures_core::future::Future $(, $($bound)*)* { type Output = <$t as futures_core::future::Future>::Output; delegate_future!(inner); } }; (@trait FusedFuture $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => { impl<$($arg),*> futures_core::future::FusedFuture for $name<$($arg),*> where $t: futures_core::future::FusedFuture $(, $($bound)*)* { fn is_terminated(&self) -> bool { self.inner.is_terminated() } } }; (@trait Stream $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => { impl<$($arg),*> futures_core::stream::Stream for $name<$($arg),*> where $t: futures_core::stream::Stream $(, $($bound)*)* { type Item = <$t as futures_core::stream::Stream>::Item; delegate_stream!(inner); } }; (@trait FusedStream $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => { impl<$($arg),*> futures_core::stream::FusedStream for $name<$($arg),*> where $t: futures_core::stream::FusedStream $(, $($bound)*)* { fn is_terminated(&self) -> bool { self.inner.is_terminated() } } }; (@trait Sink $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => { #[cfg(feature = "sink")] impl<_Item, $($arg),*> futures_sink::Sink<_Item> for $name<$($arg),*> where $t: futures_sink::Sink<_Item> $(, $($bound)*)* { type Error = <$t as futures_sink::Sink<_Item>>::Error; delegate_sink!(inner, _Item); } }; (@trait Debug $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => { impl<$($arg),*> core::fmt::Debug for $name<$($arg),*> where $t: core::fmt::Debug $(, $($bound)*)* { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { core::fmt::Debug::fmt(&self.inner, f) } } }; (@trait AccessInner[$inner:ty, ($($ind:tt)*)] $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => { impl<$($arg),*> $name<$($arg),*> $(where $($bound)*)* { delegate_access_inner!(inner, $inner, ($($ind)*)); } }; (@trait New[|$($param:ident: $paramt:ty),*| $cons:expr] $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => { impl<$($arg),*> $name<$($arg),*> $(where $($bound)*)* { pub(crate) fn new($($param: $paramt),*) -> Self { Self { inner: $cons } } } }; ($(#[$attr:meta])* $name:ident<$($arg:ident),*>($t:ty) : $ftrait:ident $([$($targs:tt)*])* $({$($item:tt)*})* $(where $($bound:tt)*)*) => { pin_project_lite::pin_project! { #[must_use = "futures/streams/sinks do nothing unless you `.await` or poll them"] $(#[$attr])* pub struct $name< $($arg),* > $(where $($bound)*)* { #[pin] inner: $t } } impl<$($arg),*> $name< $($arg),* > $(where $($bound)*)* { $($($item)*)* } delegate_all!(@trait $ftrait $([$($targs)*])* $name<$($arg),*>($t) $(where $($bound)*)*); }; ($(#[$attr:meta])* $name:ident<$($arg:ident),*>($t:ty) : $ftrait:ident $([$($ftargs:tt)*])* + $strait:ident $([$($stargs:tt)*])* $(+ $trait:ident $([$($targs:tt)*])*)* $({$($item:tt)*})* $(where $($bound:tt)*)*) => { delegate_all!($(#[$attr])* $name<$($arg),*>($t) : $strait $([$($stargs)*])* $(+ $trait $([$($targs)*])*)* $({$($item)*})* $(where $($bound)*)*); delegate_all!(@trait $ftrait $([$($ftargs)*])* $name<$($arg),*>($t) $(where $($bound)*)*); }; } pub mod future; #[doc(no_inline)] pub use crate::future::{Future, FutureExt, TryFuture, TryFutureExt}; pub mod stream; #[doc(no_inline)] pub use crate::stream::{Stream, StreamExt, TryStream, TryStreamExt}; #[cfg(feature = "sink")] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] pub mod sink; #[cfg(feature = "sink")] #[doc(no_inline)] pub use crate::sink::{Sink, SinkExt}; pub mod task; pub mod never; #[cfg(feature = "compat")] #[cfg_attr(docsrs, doc(cfg(feature = "compat")))] pub mod compat; #[cfg(feature = "io")] #[cfg_attr(docsrs, doc(cfg(feature = "io")))] #[cfg(feature = "std")] pub mod io; #[cfg(feature = "io")] #[cfg(feature = "std")] #[doc(no_inline)] pub use crate::io::{ AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, AsyncWrite, AsyncWriteExt, }; #[cfg(feature = "alloc")] pub mod lock; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] mod abortable; mod fns; mod unfold_state; futures-util-0.3.30/src/lock/bilock.rs000064400000000000000000000252751046102023000157220ustar 00000000000000//! Futures-powered synchronization primitives. use alloc::boxed::Box; use alloc::sync::Arc; use core::cell::UnsafeCell; use core::ops::{Deref, DerefMut}; use core::pin::Pin; use core::sync::atomic::AtomicPtr; use core::sync::atomic::Ordering::SeqCst; use core::{fmt, ptr}; #[cfg(feature = "bilock")] use futures_core::future::Future; use futures_core::task::{Context, Poll, Waker}; /// A type of futures-powered synchronization primitive which is a mutex between /// two possible owners. /// /// This primitive is not as generic as a full-blown mutex but is sufficient for /// many use cases where there are only two possible owners of a resource. The /// implementation of `BiLock` can be more optimized for just the two possible /// owners. /// /// Note that it's possible to use this lock through a poll-style interface with /// the `poll_lock` method but you can also use it as a future with the `lock` /// method that consumes a `BiLock` and returns a future that will resolve when /// it's locked. /// /// A `BiLock` is typically used for "split" operations where data which serves /// two purposes wants to be split into two to be worked with separately. For /// example a TCP stream could be both a reader and a writer or a framing layer /// could be both a stream and a sink for messages. A `BiLock` enables splitting /// these two and then using each independently in a futures-powered fashion. /// /// This type is only available when the `bilock` feature of this /// library is activated. #[derive(Debug)] #[cfg_attr(docsrs, doc(cfg(feature = "bilock")))] pub struct BiLock { arc: Arc>, } #[derive(Debug)] struct Inner { state: AtomicPtr, value: Option>, } unsafe impl Send for Inner {} unsafe impl Sync for Inner {} impl BiLock { /// Creates a new `BiLock` protecting the provided data. /// /// Two handles to the lock are returned, and these are the only two handles /// that will ever be available to the lock. These can then be sent to separate /// tasks to be managed there. /// /// The data behind the bilock is considered to be pinned, which allows `Pin` /// references to locked data. However, this means that the locked value /// will only be available through `Pin<&mut T>` (not `&mut T`) unless `T` is `Unpin`. /// Similarly, reuniting the lock and extracting the inner value is only /// possible when `T` is `Unpin`. pub fn new(t: T) -> (Self, Self) { let arc = Arc::new(Inner { state: AtomicPtr::new(ptr::null_mut()), value: Some(UnsafeCell::new(t)), }); (Self { arc: arc.clone() }, Self { arc }) } /// Attempt to acquire this lock, returning `Pending` if it can't be /// acquired. /// /// This function will acquire the lock in a nonblocking fashion, returning /// immediately if the lock is already held. If the lock is successfully /// acquired then `Poll::Ready` is returned with a value that represents /// the locked value (and can be used to access the protected data). The /// lock is unlocked when the returned `BiLockGuard` is dropped. /// /// If the lock is already held then this function will return /// `Poll::Pending`. In this case the current task will also be scheduled /// to receive a notification when the lock would otherwise become /// available. /// /// # Panics /// /// This function will panic if called outside the context of a future's /// task. pub fn poll_lock(&self, cx: &mut Context<'_>) -> Poll> { let mut waker = None; loop { let n = self.arc.state.swap(invalid_ptr(1), SeqCst); match n as usize { // Woohoo, we grabbed the lock! 0 => return Poll::Ready(BiLockGuard { bilock: self }), // Oops, someone else has locked the lock 1 => {} // A task was previously blocked on this lock, likely our task, // so we need to update that task. _ => unsafe { let mut prev = Box::from_raw(n); *prev = cx.waker().clone(); waker = Some(prev); }, } // type ascription for safety's sake! let me: Box = waker.take().unwrap_or_else(|| Box::new(cx.waker().clone())); let me = Box::into_raw(me); match self.arc.state.compare_exchange(invalid_ptr(1), me, SeqCst, SeqCst) { // The lock is still locked, but we've now parked ourselves, so // just report that we're scheduled to receive a notification. Ok(_) => return Poll::Pending, // Oops, looks like the lock was unlocked after our swap above // and before the compare_exchange. Deallocate what we just // allocated and go through the loop again. Err(n) if n.is_null() => unsafe { waker = Some(Box::from_raw(me)); }, // The top of this loop set the previous state to 1, so if we // failed the CAS above then it's because the previous value was // *not* zero or one. This indicates that a task was blocked, // but we're trying to acquire the lock and there's only one // other reference of the lock, so it should be impossible for // that task to ever block itself. Err(n) => panic!("invalid state: {}", n as usize), } } } /// Perform a "blocking lock" of this lock, consuming this lock handle and /// returning a future to the acquired lock. /// /// This function consumes the `BiLock` and returns a sentinel future, /// `BiLockAcquire`. The returned future will resolve to /// `BiLockAcquired` which represents a locked lock similarly to /// `BiLockGuard`. /// /// Note that the returned future will never resolve to an error. #[cfg(feature = "bilock")] #[cfg_attr(docsrs, doc(cfg(feature = "bilock")))] pub fn lock(&self) -> BiLockAcquire<'_, T> { BiLockAcquire { bilock: self } } /// Returns `true` only if the other `BiLock` originated from the same call to `BiLock::new`. pub fn is_pair_of(&self, other: &Self) -> bool { Arc::ptr_eq(&self.arc, &other.arc) } /// Attempts to put the two "halves" of a `BiLock` back together and /// recover the original value. Succeeds only if the two `BiLock`s /// originated from the same call to `BiLock::new`. pub fn reunite(self, other: Self) -> Result> where T: Unpin, { if self.is_pair_of(&other) { drop(other); let inner = Arc::try_unwrap(self.arc) .ok() .expect("futures: try_unwrap failed in BiLock::reunite"); Ok(unsafe { inner.into_value() }) } else { Err(ReuniteError(self, other)) } } fn unlock(&self) { let n = self.arc.state.swap(ptr::null_mut(), SeqCst); match n as usize { // we've locked the lock, shouldn't be possible for us to see an // unlocked lock. 0 => panic!("invalid unlocked state"), // Ok, no one else tried to get the lock, we're done. 1 => {} // Another task has parked themselves on this lock, let's wake them // up as its now their turn. _ => unsafe { Box::from_raw(n).wake(); }, } } } impl Inner { unsafe fn into_value(mut self) -> T { self.value.take().unwrap().into_inner() } } impl Drop for Inner { fn drop(&mut self) { assert!(self.state.load(SeqCst).is_null()); } } /// Error indicating two `BiLock`s were not two halves of a whole, and /// thus could not be `reunite`d. #[cfg_attr(docsrs, doc(cfg(feature = "bilock")))] pub struct ReuniteError(pub BiLock, pub BiLock); impl fmt::Debug for ReuniteError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("ReuniteError").field(&"...").finish() } } impl fmt::Display for ReuniteError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "tried to reunite two BiLocks that don't form a pair") } } #[cfg(feature = "std")] impl std::error::Error for ReuniteError {} /// Returned RAII guard from the `poll_lock` method. /// /// This structure acts as a sentinel to the data in the `BiLock` itself, /// implementing `Deref` and `DerefMut` to `T`. When dropped, the lock will be /// unlocked. #[derive(Debug)] #[cfg_attr(docsrs, doc(cfg(feature = "bilock")))] pub struct BiLockGuard<'a, T> { bilock: &'a BiLock, } // We allow parallel access to T via Deref, so Sync bound is also needed here. unsafe impl Sync for BiLockGuard<'_, T> {} impl Deref for BiLockGuard<'_, T> { type Target = T; fn deref(&self) -> &T { unsafe { &*self.bilock.arc.value.as_ref().unwrap().get() } } } impl DerefMut for BiLockGuard<'_, T> { fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.bilock.arc.value.as_ref().unwrap().get() } } } impl BiLockGuard<'_, T> { /// Get a mutable pinned reference to the locked value. pub fn as_pin_mut(&mut self) -> Pin<&mut T> { // Safety: we never allow moving a !Unpin value out of a bilock, nor // allow mutable access to it unsafe { Pin::new_unchecked(&mut *self.bilock.arc.value.as_ref().unwrap().get()) } } } impl Drop for BiLockGuard<'_, T> { fn drop(&mut self) { self.bilock.unlock(); } } /// Future returned by `BiLock::lock` which will resolve when the lock is /// acquired. #[cfg(feature = "bilock")] #[cfg_attr(docsrs, doc(cfg(feature = "bilock")))] #[must_use = "futures do nothing unless you `.await` or poll them"] #[derive(Debug)] pub struct BiLockAcquire<'a, T> { bilock: &'a BiLock, } // Pinning is never projected to fields #[cfg(feature = "bilock")] impl Unpin for BiLockAcquire<'_, T> {} #[cfg(feature = "bilock")] impl<'a, T> Future for BiLockAcquire<'a, T> { type Output = BiLockGuard<'a, T>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { self.bilock.poll_lock(cx) } } // Based on core::ptr::invalid_mut. Equivalent to `addr as *mut T`, but is strict-provenance compatible. #[allow(clippy::useless_transmute)] #[inline] fn invalid_ptr(addr: usize) -> *mut T { // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that // pointer). unsafe { core::mem::transmute(addr) } } futures-util-0.3.30/src/lock/mod.rs000064400000000000000000000021711046102023000152240ustar 00000000000000//! Futures-powered synchronization primitives. //! //! This module is only available when the `std` or `alloc` feature of this //! library is activated, and it is activated by default. #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(any(feature = "sink", feature = "io"))] #[cfg(not(feature = "bilock"))] pub(crate) use self::bilock::BiLock; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "bilock")] #[cfg_attr(docsrs, doc(cfg(feature = "bilock")))] pub use self::bilock::{BiLock, BiLockAcquire, BiLockGuard, ReuniteError}; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "std")] pub use self::mutex::{ MappedMutexGuard, Mutex, MutexGuard, MutexLockFuture, OwnedMutexGuard, OwnedMutexLockFuture, }; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(any(feature = "bilock", feature = "sink", feature = "io"))] #[cfg_attr(docsrs, doc(cfg(feature = "bilock")))] #[cfg_attr(not(feature = "bilock"), allow(unreachable_pub))] mod bilock; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "std")] mod mutex; futures-util-0.3.30/src/lock/mutex.rs000064400000000000000000000423431046102023000156140ustar 00000000000000use std::cell::UnsafeCell; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; use std::pin::Pin; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::{Arc, Mutex as StdMutex}; use std::{fmt, mem}; use slab::Slab; use futures_core::future::{FusedFuture, Future}; use futures_core::task::{Context, Poll, Waker}; /// A futures-aware mutex. /// /// # Fairness /// /// This mutex provides no fairness guarantees. Tasks may not acquire the mutex /// in the order that they requested the lock, and it's possible for a single task /// which repeatedly takes the lock to starve other tasks, which may be left waiting /// indefinitely. pub struct Mutex { state: AtomicUsize, waiters: StdMutex>, value: UnsafeCell, } impl fmt::Debug for Mutex { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let state = self.state.load(Ordering::SeqCst); f.debug_struct("Mutex") .field("is_locked", &((state & IS_LOCKED) != 0)) .field("has_waiters", &((state & HAS_WAITERS) != 0)) .finish() } } impl From for Mutex { fn from(t: T) -> Self { Self::new(t) } } impl Default for Mutex { fn default() -> Self { Self::new(Default::default()) } } enum Waiter { Waiting(Waker), Woken, } impl Waiter { fn register(&mut self, waker: &Waker) { match self { Self::Waiting(w) if waker.will_wake(w) => {} _ => *self = Self::Waiting(waker.clone()), } } fn wake(&mut self) { match mem::replace(self, Self::Woken) { Self::Waiting(waker) => waker.wake(), Self::Woken => {} } } } const IS_LOCKED: usize = 1 << 0; const HAS_WAITERS: usize = 1 << 1; impl Mutex { /// Creates a new futures-aware mutex. pub fn new(t: T) -> Self { Self { state: AtomicUsize::new(0), waiters: StdMutex::new(Slab::new()), value: UnsafeCell::new(t), } } /// Consumes this mutex, returning the underlying data. /// /// # Examples /// /// ``` /// use futures::lock::Mutex; /// /// let mutex = Mutex::new(0); /// assert_eq!(mutex.into_inner(), 0); /// ``` pub fn into_inner(self) -> T { self.value.into_inner() } } impl Mutex { /// Attempt to acquire the lock immediately. /// /// If the lock is currently held, this will return `None`. pub fn try_lock(&self) -> Option> { let old_state = self.state.fetch_or(IS_LOCKED, Ordering::Acquire); if (old_state & IS_LOCKED) == 0 { Some(MutexGuard { mutex: self }) } else { None } } /// Attempt to acquire the lock immediately. /// /// If the lock is currently held, this will return `None`. pub fn try_lock_owned(self: &Arc) -> Option> { let old_state = self.state.fetch_or(IS_LOCKED, Ordering::Acquire); if (old_state & IS_LOCKED) == 0 { Some(OwnedMutexGuard { mutex: self.clone() }) } else { None } } /// Acquire the lock asynchronously. /// /// This method returns a future that will resolve once the lock has been /// successfully acquired. pub fn lock(&self) -> MutexLockFuture<'_, T> { MutexLockFuture { mutex: Some(self), wait_key: WAIT_KEY_NONE } } /// Acquire the lock asynchronously. /// /// This method returns a future that will resolve once the lock has been /// successfully acquired. pub fn lock_owned(self: Arc) -> OwnedMutexLockFuture { OwnedMutexLockFuture { mutex: Some(self), wait_key: WAIT_KEY_NONE } } /// Returns a mutable reference to the underlying data. /// /// Since this call borrows the `Mutex` mutably, no actual locking needs to /// take place -- the mutable borrow statically guarantees no locks exist. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::lock::Mutex; /// /// let mut mutex = Mutex::new(0); /// *mutex.get_mut() = 10; /// assert_eq!(*mutex.lock().await, 10); /// # }); /// ``` pub fn get_mut(&mut self) -> &mut T { // We know statically that there are no other references to `self`, so // there's no need to lock the inner mutex. unsafe { &mut *self.value.get() } } fn remove_waker(&self, wait_key: usize, wake_another: bool) { if wait_key != WAIT_KEY_NONE { let mut waiters = self.waiters.lock().unwrap(); match waiters.remove(wait_key) { Waiter::Waiting(_) => {} Waiter::Woken => { // We were awoken, but then dropped before we could // wake up to acquire the lock. Wake up another // waiter. if wake_another { if let Some((_i, waiter)) = waiters.iter_mut().next() { waiter.wake(); } } } } if waiters.is_empty() { self.state.fetch_and(!HAS_WAITERS, Ordering::Relaxed); // released by mutex unlock } } } // Unlocks the mutex. Called by MutexGuard and MappedMutexGuard when they are // dropped. fn unlock(&self) { let old_state = self.state.fetch_and(!IS_LOCKED, Ordering::AcqRel); if (old_state & HAS_WAITERS) != 0 { let mut waiters = self.waiters.lock().unwrap(); if let Some((_i, waiter)) = waiters.iter_mut().next() { waiter.wake(); } } } } // Sentinel for when no slot in the `Slab` has been dedicated to this object. const WAIT_KEY_NONE: usize = usize::MAX; /// A future which resolves when the target mutex has been successfully acquired, owned version. pub struct OwnedMutexLockFuture { // `None` indicates that the mutex was successfully acquired. mutex: Option>>, wait_key: usize, } impl fmt::Debug for OwnedMutexLockFuture { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("OwnedMutexLockFuture") .field("was_acquired", &self.mutex.is_none()) .field("mutex", &self.mutex) .field( "wait_key", &(if self.wait_key == WAIT_KEY_NONE { None } else { Some(self.wait_key) }), ) .finish() } } impl FusedFuture for OwnedMutexLockFuture { fn is_terminated(&self) -> bool { self.mutex.is_none() } } impl Future for OwnedMutexLockFuture { type Output = OwnedMutexGuard; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.get_mut(); let mutex = this.mutex.as_ref().expect("polled OwnedMutexLockFuture after completion"); if let Some(lock) = mutex.try_lock_owned() { mutex.remove_waker(this.wait_key, false); this.mutex = None; return Poll::Ready(lock); } { let mut waiters = mutex.waiters.lock().unwrap(); if this.wait_key == WAIT_KEY_NONE { this.wait_key = waiters.insert(Waiter::Waiting(cx.waker().clone())); if waiters.len() == 1 { mutex.state.fetch_or(HAS_WAITERS, Ordering::Relaxed); // released by mutex unlock } } else { waiters[this.wait_key].register(cx.waker()); } } // Ensure that we haven't raced `MutexGuard::drop`'s unlock path by // attempting to acquire the lock again. if let Some(lock) = mutex.try_lock_owned() { mutex.remove_waker(this.wait_key, false); this.mutex = None; return Poll::Ready(lock); } Poll::Pending } } impl Drop for OwnedMutexLockFuture { fn drop(&mut self) { if let Some(mutex) = self.mutex.as_ref() { // This future was dropped before it acquired the mutex. // // Remove ourselves from the map, waking up another waiter if we // had been awoken to acquire the lock. mutex.remove_waker(self.wait_key, true); } } } /// An RAII guard returned by the `lock_owned` and `try_lock_owned` methods. /// When this structure is dropped (falls out of scope), the lock will be /// unlocked. pub struct OwnedMutexGuard { mutex: Arc>, } impl fmt::Debug for OwnedMutexGuard { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("OwnedMutexGuard") .field("value", &&**self) .field("mutex", &self.mutex) .finish() } } impl Drop for OwnedMutexGuard { fn drop(&mut self) { self.mutex.unlock() } } impl Deref for OwnedMutexGuard { type Target = T; fn deref(&self) -> &T { unsafe { &*self.mutex.value.get() } } } impl DerefMut for OwnedMutexGuard { fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.mutex.value.get() } } } /// A future which resolves when the target mutex has been successfully acquired. pub struct MutexLockFuture<'a, T: ?Sized> { // `None` indicates that the mutex was successfully acquired. mutex: Option<&'a Mutex>, wait_key: usize, } impl fmt::Debug for MutexLockFuture<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("MutexLockFuture") .field("was_acquired", &self.mutex.is_none()) .field("mutex", &self.mutex) .field( "wait_key", &(if self.wait_key == WAIT_KEY_NONE { None } else { Some(self.wait_key) }), ) .finish() } } impl FusedFuture for MutexLockFuture<'_, T> { fn is_terminated(&self) -> bool { self.mutex.is_none() } } impl<'a, T: ?Sized> Future for MutexLockFuture<'a, T> { type Output = MutexGuard<'a, T>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mutex = self.mutex.expect("polled MutexLockFuture after completion"); if let Some(lock) = mutex.try_lock() { mutex.remove_waker(self.wait_key, false); self.mutex = None; return Poll::Ready(lock); } { let mut waiters = mutex.waiters.lock().unwrap(); if self.wait_key == WAIT_KEY_NONE { self.wait_key = waiters.insert(Waiter::Waiting(cx.waker().clone())); if waiters.len() == 1 { mutex.state.fetch_or(HAS_WAITERS, Ordering::Relaxed); // released by mutex unlock } } else { waiters[self.wait_key].register(cx.waker()); } } // Ensure that we haven't raced `MutexGuard::drop`'s unlock path by // attempting to acquire the lock again. if let Some(lock) = mutex.try_lock() { mutex.remove_waker(self.wait_key, false); self.mutex = None; return Poll::Ready(lock); } Poll::Pending } } impl Drop for MutexLockFuture<'_, T> { fn drop(&mut self) { if let Some(mutex) = self.mutex { // This future was dropped before it acquired the mutex. // // Remove ourselves from the map, waking up another waiter if we // had been awoken to acquire the lock. mutex.remove_waker(self.wait_key, true); } } } /// An RAII guard returned by the `lock` and `try_lock` methods. /// When this structure is dropped (falls out of scope), the lock will be /// unlocked. pub struct MutexGuard<'a, T: ?Sized> { mutex: &'a Mutex, } impl<'a, T: ?Sized> MutexGuard<'a, T> { /// Returns a locked view over a portion of the locked data. /// /// # Example /// /// ``` /// # futures::executor::block_on(async { /// use futures::lock::{Mutex, MutexGuard}; /// /// let data = Mutex::new(Some("value".to_string())); /// { /// let locked_str = MutexGuard::map(data.lock().await, |opt| opt.as_mut().unwrap()); /// assert_eq!(&*locked_str, "value"); /// } /// # }); /// ``` #[inline] pub fn map(this: Self, f: F) -> MappedMutexGuard<'a, T, U> where F: FnOnce(&mut T) -> &mut U, { let mutex = this.mutex; let value = f(unsafe { &mut *this.mutex.value.get() }); // Don't run the `drop` method for MutexGuard. The ownership of the underlying // locked state is being moved to the returned MappedMutexGuard. mem::forget(this); MappedMutexGuard { mutex, value, _marker: PhantomData } } } impl fmt::Debug for MutexGuard<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("MutexGuard").field("value", &&**self).field("mutex", &self.mutex).finish() } } impl Drop for MutexGuard<'_, T> { fn drop(&mut self) { self.mutex.unlock() } } impl Deref for MutexGuard<'_, T> { type Target = T; fn deref(&self) -> &T { unsafe { &*self.mutex.value.get() } } } impl DerefMut for MutexGuard<'_, T> { fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.mutex.value.get() } } } /// An RAII guard returned by the `MutexGuard::map` and `MappedMutexGuard::map` methods. /// When this structure is dropped (falls out of scope), the lock will be unlocked. pub struct MappedMutexGuard<'a, T: ?Sized, U: ?Sized> { mutex: &'a Mutex, value: *mut U, _marker: PhantomData<&'a mut U>, } impl<'a, T: ?Sized, U: ?Sized> MappedMutexGuard<'a, T, U> { /// Returns a locked view over a portion of the locked data. /// /// # Example /// /// ``` /// # futures::executor::block_on(async { /// use futures::lock::{MappedMutexGuard, Mutex, MutexGuard}; /// /// let data = Mutex::new(Some("value".to_string())); /// { /// let locked_str = MutexGuard::map(data.lock().await, |opt| opt.as_mut().unwrap()); /// let locked_char = MappedMutexGuard::map(locked_str, |s| s.get_mut(0..1).unwrap()); /// assert_eq!(&*locked_char, "v"); /// } /// # }); /// ``` #[inline] pub fn map(this: Self, f: F) -> MappedMutexGuard<'a, T, V> where F: FnOnce(&mut U) -> &mut V, { let mutex = this.mutex; let value = f(unsafe { &mut *this.value }); // Don't run the `drop` method for MappedMutexGuard. The ownership of the underlying // locked state is being moved to the returned MappedMutexGuard. mem::forget(this); MappedMutexGuard { mutex, value, _marker: PhantomData } } } impl fmt::Debug for MappedMutexGuard<'_, T, U> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("MappedMutexGuard") .field("value", &&**self) .field("mutex", &self.mutex) .finish() } } impl Drop for MappedMutexGuard<'_, T, U> { fn drop(&mut self) { self.mutex.unlock() } } impl Deref for MappedMutexGuard<'_, T, U> { type Target = U; fn deref(&self) -> &U { unsafe { &*self.value } } } impl DerefMut for MappedMutexGuard<'_, T, U> { fn deref_mut(&mut self) -> &mut U { unsafe { &mut *self.value } } } // Mutexes can be moved freely between threads and acquired on any thread so long // as the inner value can be safely sent between threads. unsafe impl Send for Mutex {} unsafe impl Sync for Mutex {} // It's safe to switch which thread the acquire is being attempted on so long as // `T` can be accessed on that thread. unsafe impl Send for MutexLockFuture<'_, T> {} // doesn't have any interesting `&self` methods (only Debug) unsafe impl Sync for MutexLockFuture<'_, T> {} // It's safe to switch which thread the acquire is being attempted on so long as // `T` can be accessed on that thread. unsafe impl Send for OwnedMutexLockFuture {} // doesn't have any interesting `&self` methods (only Debug) unsafe impl Sync for OwnedMutexLockFuture {} // Safe to send since we don't track any thread-specific details-- the inner // lock is essentially spinlock-equivalent (attempt to flip an atomic bool) unsafe impl Send for MutexGuard<'_, T> {} unsafe impl Sync for MutexGuard<'_, T> {} unsafe impl Send for OwnedMutexGuard {} unsafe impl Sync for OwnedMutexGuard {} unsafe impl Send for MappedMutexGuard<'_, T, U> {} unsafe impl Sync for MappedMutexGuard<'_, T, U> {} #[test] fn test_mutex_guard_debug_not_recurse() { let mutex = Mutex::new(42); let guard = mutex.try_lock().unwrap(); let _ = format!("{:?}", guard); let guard = MutexGuard::map(guard, |n| n); let _ = format!("{:?}", guard); } futures-util-0.3.30/src/never.rs000064400000000000000000000014211046102023000146310ustar 00000000000000//! This module contains the `Never` type. //! //! Values of this type can never be created and will never exist. /// A type with no possible values. /// /// This is used to indicate values which can never be created, such as the /// error type of infallible futures. /// /// This type is a stable equivalent to the `!` type from `std`. /// /// This is currently an alias for [`std::convert::Infallible`], but in /// the future it may be an alias for [`!`][never]. /// See ["Future compatibility" section of `std::convert::Infallible`][infallible] for more. /// /// [never]: https://doc.rust-lang.org/nightly/std/primitive.never.html /// [infallible]: https://doc.rust-lang.org/nightly/std/convert/enum.Infallible.html#future-compatibility pub type Never = core::convert::Infallible; futures-util-0.3.30/src/sink/buffer.rs000064400000000000000000000057741046102023000157460ustar 00000000000000use alloc::collections::VecDeque; use core::pin::Pin; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Sink for the [`buffer`](super::SinkExt::buffer) method. #[derive(Debug)] #[must_use = "sinks do nothing unless polled"] pub struct Buffer { #[pin] sink: Si, buf: VecDeque, // Track capacity separately from the `VecDeque`, which may be rounded up capacity: usize, } } impl, Item> Buffer { pub(super) fn new(sink: Si, capacity: usize) -> Self { Self { sink, buf: VecDeque::with_capacity(capacity), capacity } } delegate_access_inner!(sink, Si, ()); fn try_empty_buffer(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); ready!(this.sink.as_mut().poll_ready(cx))?; while let Some(item) = this.buf.pop_front() { this.sink.as_mut().start_send(item)?; if !this.buf.is_empty() { ready!(this.sink.as_mut().poll_ready(cx))?; } } Poll::Ready(Ok(())) } } // Forwarding impl of Stream from the underlying sink impl Stream for Buffer where S: Sink + Stream, { type Item = S::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.project().sink.poll_next(cx) } fn size_hint(&self) -> (usize, Option) { self.sink.size_hint() } } impl FusedStream for Buffer where S: Sink + FusedStream, { fn is_terminated(&self) -> bool { self.sink.is_terminated() } } impl, Item> Sink for Buffer { type Error = Si::Error; fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { if self.capacity == 0 { return self.project().sink.poll_ready(cx); } let _ = self.as_mut().try_empty_buffer(cx)?; if self.buf.len() >= self.capacity { Poll::Pending } else { Poll::Ready(Ok(())) } } fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { if self.capacity == 0 { self.project().sink.start_send(item) } else { self.project().buf.push_back(item); Ok(()) } } fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { ready!(self.as_mut().try_empty_buffer(cx))?; debug_assert!(self.buf.is_empty()); self.project().sink.poll_flush(cx) } fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { ready!(self.as_mut().try_empty_buffer(cx))?; debug_assert!(self.buf.is_empty()); self.project().sink.poll_close(cx) } } futures-util-0.3.30/src/sink/close.rs000064400000000000000000000020001046102023000155550ustar 00000000000000use core::marker::PhantomData; use core::pin::Pin; use futures_core::future::Future; use futures_core::task::{Context, Poll}; use futures_sink::Sink; /// Future for the [`close`](super::SinkExt::close) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Close<'a, Si: ?Sized, Item> { sink: &'a mut Si, _phantom: PhantomData, } impl Unpin for Close<'_, Si, Item> {} /// A future that completes when the sink has finished closing. /// /// The sink itself is returned after closing is complete. impl<'a, Si: Sink + Unpin + ?Sized, Item> Close<'a, Si, Item> { pub(super) fn new(sink: &'a mut Si) -> Self { Self { sink, _phantom: PhantomData } } } impl + Unpin + ?Sized, Item> Future for Close<'_, Si, Item> { type Output = Result<(), Si::Error>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Pin::new(&mut self.sink).poll_close(cx) } } futures-util-0.3.30/src/sink/drain.rs000064400000000000000000000026441046102023000155630ustar 00000000000000use super::assert_sink; use crate::never::Never; use core::marker::PhantomData; use core::pin::Pin; use futures_core::task::{Context, Poll}; use futures_sink::Sink; /// Sink for the [`drain`] function. #[derive(Debug)] #[must_use = "sinks do nothing unless polled"] pub struct Drain { marker: PhantomData, } /// Create a sink that will just discard all items given to it. /// /// Similar to [`io::Sink`](::std::io::Sink). /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::sink::{self, SinkExt}; /// /// let mut drain = sink::drain(); /// drain.send(5).await?; /// # Ok::<(), futures::never::Never>(()) }).unwrap(); /// ``` pub fn drain() -> Drain { assert_sink::(Drain { marker: PhantomData }) } impl Unpin for Drain {} impl Clone for Drain { fn clone(&self) -> Self { drain() } } impl Sink for Drain { type Error = Never; fn poll_ready(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) } fn start_send(self: Pin<&mut Self>, _item: T) -> Result<(), Self::Error> { Ok(()) } fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) } fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) } } futures-util-0.3.30/src/sink/err_into.rs000064400000000000000000000024041046102023000163010ustar 00000000000000use crate::sink::{SinkExt, SinkMapErr}; use futures_core::stream::{FusedStream, Stream}; use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Sink for the [`sink_err_into`](super::SinkExt::sink_err_into) method. #[derive(Debug)] #[must_use = "sinks do nothing unless polled"] pub struct SinkErrInto, Item, E> { #[pin] sink: SinkMapErr E>, } } impl SinkErrInto where Si: Sink, Si::Error: Into, { pub(super) fn new(sink: Si) -> Self { Self { sink: SinkExt::sink_map_err(sink, Into::into) } } delegate_access_inner!(sink, Si, (.)); } impl Sink for SinkErrInto where Si: Sink, Si::Error: Into, { type Error = E; delegate_sink!(sink, Item); } // Forwarding impl of Stream from the underlying sink impl Stream for SinkErrInto where S: Sink + Stream, S::Error: Into, { type Item = S::Item; delegate_stream!(sink); } impl FusedStream for SinkErrInto where S: Sink + FusedStream, S::Error: Into, { fn is_terminated(&self) -> bool { self.sink.is_terminated() } } futures-util-0.3.30/src/sink/fanout.rs000064400000000000000000000065641046102023000157670ustar 00000000000000use core::fmt::{Debug, Formatter, Result as FmtResult}; use core::pin::Pin; use futures_core::task::{Context, Poll}; use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Sink that clones incoming items and forwards them to two sinks at the same time. /// /// Backpressure from any downstream sink propagates up, which means that this sink /// can only process items as fast as its _slowest_ downstream sink. #[must_use = "sinks do nothing unless polled"] pub struct Fanout { #[pin] sink1: Si1, #[pin] sink2: Si2 } } impl Fanout { pub(super) fn new(sink1: Si1, sink2: Si2) -> Self { Self { sink1, sink2 } } /// Get a shared reference to the inner sinks. pub fn get_ref(&self) -> (&Si1, &Si2) { (&self.sink1, &self.sink2) } /// Get a mutable reference to the inner sinks. pub fn get_mut(&mut self) -> (&mut Si1, &mut Si2) { (&mut self.sink1, &mut self.sink2) } /// Get a pinned mutable reference to the inner sinks. pub fn get_pin_mut(self: Pin<&mut Self>) -> (Pin<&mut Si1>, Pin<&mut Si2>) { let this = self.project(); (this.sink1, this.sink2) } /// Consumes this combinator, returning the underlying sinks. /// /// Note that this may discard intermediate state of this combinator, /// so care should be taken to avoid losing resources when this is called. pub fn into_inner(self) -> (Si1, Si2) { (self.sink1, self.sink2) } } impl Debug for Fanout { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { f.debug_struct("Fanout").field("sink1", &self.sink1).field("sink2", &self.sink2).finish() } } impl Sink for Fanout where Si1: Sink, Item: Clone, Si2: Sink, { type Error = Si1::Error; fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); let sink1_ready = this.sink1.poll_ready(cx)?.is_ready(); let sink2_ready = this.sink2.poll_ready(cx)?.is_ready(); let ready = sink1_ready && sink2_ready; if ready { Poll::Ready(Ok(())) } else { Poll::Pending } } fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { let this = self.project(); this.sink1.start_send(item.clone())?; this.sink2.start_send(item)?; Ok(()) } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); let sink1_ready = this.sink1.poll_flush(cx)?.is_ready(); let sink2_ready = this.sink2.poll_flush(cx)?.is_ready(); let ready = sink1_ready && sink2_ready; if ready { Poll::Ready(Ok(())) } else { Poll::Pending } } fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); let sink1_ready = this.sink1.poll_close(cx)?.is_ready(); let sink2_ready = this.sink2.poll_close(cx)?.is_ready(); let ready = sink1_ready && sink2_ready; if ready { Poll::Ready(Ok(())) } else { Poll::Pending } } } futures-util-0.3.30/src/sink/feed.rs000064400000000000000000000024561046102023000153720ustar 00000000000000use core::pin::Pin; use futures_core::future::Future; use futures_core::ready; use futures_core::task::{Context, Poll}; use futures_sink::Sink; /// Future for the [`feed`](super::SinkExt::feed) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Feed<'a, Si: ?Sized, Item> { sink: &'a mut Si, item: Option, } // Pinning is never projected to children impl Unpin for Feed<'_, Si, Item> {} impl<'a, Si: Sink + Unpin + ?Sized, Item> Feed<'a, Si, Item> { pub(super) fn new(sink: &'a mut Si, item: Item) -> Self { Feed { sink, item: Some(item) } } pub(super) fn sink_pin_mut(&mut self) -> Pin<&mut Si> { Pin::new(self.sink) } pub(super) fn is_item_pending(&self) -> bool { self.item.is_some() } } impl + Unpin + ?Sized, Item> Future for Feed<'_, Si, Item> { type Output = Result<(), Si::Error>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.get_mut(); let mut sink = Pin::new(&mut this.sink); ready!(sink.as_mut().poll_ready(cx))?; let item = this.item.take().expect("polled Feed after completion"); sink.as_mut().start_send(item)?; Poll::Ready(Ok(())) } } futures-util-0.3.30/src/sink/flush.rs000064400000000000000000000023031046102023000155770ustar 00000000000000use core::marker::PhantomData; use core::pin::Pin; use futures_core::future::Future; use futures_core::task::{Context, Poll}; use futures_sink::Sink; /// Future for the [`flush`](super::SinkExt::flush) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Flush<'a, Si: ?Sized, Item> { sink: &'a mut Si, _phantom: PhantomData, } // Pin is never projected to a field. impl Unpin for Flush<'_, Si, Item> {} /// A future that completes when the sink has finished processing all /// pending requests. /// /// The sink itself is returned after flushing is complete; this adapter is /// intended to be used when you want to stop sending to the sink until /// all current requests are processed. impl<'a, Si: Sink + Unpin + ?Sized, Item> Flush<'a, Si, Item> { pub(super) fn new(sink: &'a mut Si) -> Self { Self { sink, _phantom: PhantomData } } } impl + Unpin + ?Sized, Item> Future for Flush<'_, Si, Item> { type Output = Result<(), Si::Error>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Pin::new(&mut self.sink).poll_flush(cx) } } futures-util-0.3.30/src/sink/map_err.rs000064400000000000000000000036311046102023000161100ustar 00000000000000use core::pin::Pin; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Sink for the [`sink_map_err`](super::SinkExt::sink_map_err) method. #[derive(Debug, Clone)] #[must_use = "sinks do nothing unless polled"] pub struct SinkMapErr { #[pin] sink: Si, f: Option, } } impl SinkMapErr { pub(super) fn new(sink: Si, f: F) -> Self { Self { sink, f: Some(f) } } delegate_access_inner!(sink, Si, ()); fn take_f(self: Pin<&mut Self>) -> F { self.project().f.take().expect("polled MapErr after completion") } } impl Sink for SinkMapErr where Si: Sink, F: FnOnce(Si::Error) -> E, { type Error = E; fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.as_mut().project().sink.poll_ready(cx).map_err(|e| self.as_mut().take_f()(e)) } fn start_send(mut self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { self.as_mut().project().sink.start_send(item).map_err(|e| self.as_mut().take_f()(e)) } fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.as_mut().project().sink.poll_flush(cx).map_err(|e| self.as_mut().take_f()(e)) } fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.as_mut().project().sink.poll_close(cx).map_err(|e| self.as_mut().take_f()(e)) } } // Forwarding impl of Stream from the underlying sink impl Stream for SinkMapErr { type Item = S::Item; delegate_stream!(sink); } impl FusedStream for SinkMapErr { fn is_terminated(&self) -> bool { self.sink.is_terminated() } } futures-util-0.3.30/src/sink/mod.rs000064400000000000000000000256741046102023000152550ustar 00000000000000//! Asynchronous sinks. //! //! This module contains: //! //! - The [`Sink`] trait, which allows you to asynchronously write data. //! - The [`SinkExt`] trait, which provides adapters for chaining and composing //! sinks. use crate::future::{assert_future, Either}; use core::pin::Pin; use futures_core::future::Future; use futures_core::stream::{Stream, TryStream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "compat")] use crate::compat::CompatSink; pub use futures_sink::Sink; mod close; pub use self::close::Close; mod drain; pub use self::drain::{drain, Drain}; mod fanout; pub use self::fanout::Fanout; mod feed; pub use self::feed::Feed; mod flush; pub use self::flush::Flush; mod err_into; pub use self::err_into::SinkErrInto; mod map_err; pub use self::map_err::SinkMapErr; mod send; pub use self::send::Send; mod send_all; pub use self::send_all::SendAll; mod unfold; pub use self::unfold::{unfold, Unfold}; mod with; pub use self::with::With; mod with_flat_map; pub use self::with_flat_map::WithFlatMap; #[cfg(feature = "alloc")] mod buffer; #[cfg(feature = "alloc")] pub use self::buffer::Buffer; impl SinkExt for T where T: Sink {} /// An extension trait for `Sink`s that provides a variety of convenient /// combinator functions. pub trait SinkExt: Sink { /// Composes a function *in front of* the sink. /// /// This adapter produces a new sink that passes each value through the /// given function `f` before sending it to `self`. /// /// To process each value, `f` produces a *future*, which is then polled to /// completion before passing its result down to the underlying sink. If the /// future produces an error, that error is returned by the new sink. /// /// Note that this function consumes the given sink, returning a wrapped /// version, much like `Iterator::map`. fn with(self, f: F) -> With where F: FnMut(U) -> Fut, Fut: Future>, E: From, Self: Sized, { assert_sink::(With::new(self, f)) } /// Composes a function *in front of* the sink. /// /// This adapter produces a new sink that passes each value through the /// given function `f` before sending it to `self`. /// /// To process each value, `f` produces a *stream*, of which each value /// is passed to the underlying sink. A new value will not be accepted until /// the stream has been drained /// /// Note that this function consumes the given sink, returning a wrapped /// version, much like `Iterator::flat_map`. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::channel::mpsc; /// use futures::sink::SinkExt; /// use futures::stream::{self, StreamExt}; /// /// let (tx, rx) = mpsc::channel(5); /// /// let mut tx = tx.with_flat_map(|x| { /// stream::iter(vec![Ok(42); x]) /// }); /// /// tx.send(5).await.unwrap(); /// drop(tx); /// let received: Vec = rx.collect().await; /// assert_eq!(received, vec![42, 42, 42, 42, 42]); /// # }); /// ``` fn with_flat_map(self, f: F) -> WithFlatMap where F: FnMut(U) -> St, St: Stream>, Self: Sized, { assert_sink::(WithFlatMap::new(self, f)) } /* fn with_map(self, f: F) -> WithMap where F: FnMut(U) -> Self::SinkItem, Self: Sized; fn with_filter(self, f: F) -> WithFilter where F: FnMut(Self::SinkItem) -> bool, Self: Sized; fn with_filter_map(self, f: F) -> WithFilterMap where F: FnMut(U) -> Option, Self: Sized; */ /// Transforms the error returned by the sink. fn sink_map_err(self, f: F) -> SinkMapErr where F: FnOnce(Self::Error) -> E, Self: Sized, { assert_sink::(SinkMapErr::new(self, f)) } /// Map this sink's error to a different error type using the `Into` trait. /// /// If wanting to map errors of a `Sink + Stream`, use `.sink_err_into().err_into()`. fn sink_err_into(self) -> err_into::SinkErrInto where Self: Sized, Self::Error: Into, { assert_sink::(SinkErrInto::new(self)) } /// Adds a fixed-size buffer to the current sink. /// /// The resulting sink will buffer up to `capacity` items when the /// underlying sink is unwilling to accept additional items. Calling `flush` /// on the buffered sink will attempt to both empty the buffer and complete /// processing on the underlying sink. /// /// Note that this function consumes the given sink, returning a wrapped /// version, much like `Iterator::map`. /// /// This method is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. #[cfg(feature = "alloc")] fn buffer(self, capacity: usize) -> Buffer where Self: Sized, { assert_sink::(Buffer::new(self, capacity)) } /// Close the sink. fn close(&mut self) -> Close<'_, Self, Item> where Self: Unpin, { assert_future::, _>(Close::new(self)) } /// Fanout items to multiple sinks. /// /// This adapter clones each incoming item and forwards it to both this as well as /// the other sink at the same time. fn fanout(self, other: Si) -> Fanout where Self: Sized, Item: Clone, Si: Sink, { assert_sink::(Fanout::new(self, other)) } /// Flush the sink, processing all pending items. /// /// This adapter is intended to be used when you want to stop sending to the sink /// until all current requests are processed. fn flush(&mut self) -> Flush<'_, Self, Item> where Self: Unpin, { assert_future::, _>(Flush::new(self)) } /// A future that completes after the given item has been fully processed /// into the sink, including flushing. /// /// Note that, **because of the flushing requirement, it is usually better /// to batch together items to send via `feed` or `send_all`, /// rather than flushing between each item.** fn send(&mut self, item: Item) -> Send<'_, Self, Item> where Self: Unpin, { assert_future::, _>(Send::new(self, item)) } /// A future that completes after the given item has been received /// by the sink. /// /// Unlike `send`, the returned future does not flush the sink. /// It is the caller's responsibility to ensure all pending items /// are processed, which can be done via `flush` or `close`. fn feed(&mut self, item: Item) -> Feed<'_, Self, Item> where Self: Unpin, { assert_future::, _>(Feed::new(self, item)) } /// A future that completes after the given stream has been fully processed /// into the sink, including flushing. /// /// This future will drive the stream to keep producing items until it is /// exhausted, sending each item to the sink. It will complete once both the /// stream is exhausted, the sink has received all items, and the sink has /// been flushed. Note that the sink is **not** closed. If the stream produces /// an error, that error will be returned by this future without flushing the sink. /// /// Doing `sink.send_all(stream)` is roughly equivalent to /// `stream.forward(sink)`. The returned future will exhaust all items from /// `stream` and send them to `self`. fn send_all<'a, St>(&'a mut self, stream: &'a mut St) -> SendAll<'a, Self, St> where St: TryStream + Stream + Unpin + ?Sized, // St: Stream> + Unpin + ?Sized, Self: Unpin, { // TODO: type mismatch resolving `::Item == std::result::Result>::Error>` // assert_future::, _>(SendAll::new(self, stream)) SendAll::new(self, stream) } /// Wrap this sink in an `Either` sink, making it the left-hand variant /// of that `Either`. /// /// This can be used in combination with the `right_sink` method to write `if` /// statements that evaluate to different streams in different branches. fn left_sink(self) -> Either where Si2: Sink, Self: Sized, { assert_sink::(Either::Left(self)) } /// Wrap this stream in an `Either` stream, making it the right-hand variant /// of that `Either`. /// /// This can be used in combination with the `left_sink` method to write `if` /// statements that evaluate to different streams in different branches. fn right_sink(self) -> Either where Si1: Sink, Self: Sized, { assert_sink::(Either::Right(self)) } /// Wraps a [`Sink`] into a sink compatible with libraries using /// futures 0.1 `Sink`. Requires the `compat` feature to be enabled. #[cfg(feature = "compat")] #[cfg_attr(docsrs, doc(cfg(feature = "compat")))] fn compat(self) -> CompatSink where Self: Sized + Unpin, { CompatSink::new(self) } /// A convenience method for calling [`Sink::poll_ready`] on [`Unpin`] /// sink types. fn poll_ready_unpin(&mut self, cx: &mut Context<'_>) -> Poll> where Self: Unpin, { Pin::new(self).poll_ready(cx) } /// A convenience method for calling [`Sink::start_send`] on [`Unpin`] /// sink types. fn start_send_unpin(&mut self, item: Item) -> Result<(), Self::Error> where Self: Unpin, { Pin::new(self).start_send(item) } /// A convenience method for calling [`Sink::poll_flush`] on [`Unpin`] /// sink types. fn poll_flush_unpin(&mut self, cx: &mut Context<'_>) -> Poll> where Self: Unpin, { Pin::new(self).poll_flush(cx) } /// A convenience method for calling [`Sink::poll_close`] on [`Unpin`] /// sink types. fn poll_close_unpin(&mut self, cx: &mut Context<'_>) -> Poll> where Self: Unpin, { Pin::new(self).poll_close(cx) } } // Just a helper function to ensure the sinks we're returning all have the // right implementations. pub(crate) fn assert_sink(sink: S) -> S where S: Sink, { sink } futures-util-0.3.30/src/sink/send.rs000064400000000000000000000023451046102023000154150ustar 00000000000000use super::Feed; use core::pin::Pin; use futures_core::future::Future; use futures_core::ready; use futures_core::task::{Context, Poll}; use futures_sink::Sink; /// Future for the [`send`](super::SinkExt::send) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Send<'a, Si: ?Sized, Item> { feed: Feed<'a, Si, Item>, } // Pinning is never projected to children impl Unpin for Send<'_, Si, Item> {} impl<'a, Si: Sink + Unpin + ?Sized, Item> Send<'a, Si, Item> { pub(super) fn new(sink: &'a mut Si, item: Item) -> Self { Self { feed: Feed::new(sink, item) } } } impl + Unpin + ?Sized, Item> Future for Send<'_, Si, Item> { type Output = Result<(), Si::Error>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = &mut *self; if this.feed.is_item_pending() { ready!(Pin::new(&mut this.feed).poll(cx))?; debug_assert!(!this.feed.is_item_pending()); } // we're done sending the item, but want to block on flushing the // sink ready!(this.feed.sink_pin_mut().poll_flush(cx))?; Poll::Ready(Ok(())) } } futures-util-0.3.30/src/sink/send_all.rs000064400000000000000000000060121046102023000162400ustar 00000000000000use crate::stream::{Fuse, StreamExt, TryStreamExt}; use core::fmt; use core::pin::Pin; use futures_core::future::Future; use futures_core::ready; use futures_core::stream::{Stream, TryStream}; use futures_core::task::{Context, Poll}; use futures_sink::Sink; /// Future for the [`send_all`](super::SinkExt::send_all) method. #[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993 #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct SendAll<'a, Si, St> where Si: ?Sized, St: ?Sized + TryStream, { sink: &'a mut Si, stream: Fuse<&'a mut St>, buffered: Option, } impl fmt::Debug for SendAll<'_, Si, St> where Si: fmt::Debug + ?Sized, St: fmt::Debug + ?Sized + TryStream, St::Ok: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("SendAll") .field("sink", &self.sink) .field("stream", &self.stream) .field("buffered", &self.buffered) .finish() } } // Pinning is never projected to any fields impl Unpin for SendAll<'_, Si, St> where Si: Unpin + ?Sized, St: TryStream + Unpin + ?Sized, { } impl<'a, Si, St, Ok, Error> SendAll<'a, Si, St> where Si: Sink + Unpin + ?Sized, St: TryStream + Stream + Unpin + ?Sized, { pub(super) fn new(sink: &'a mut Si, stream: &'a mut St) -> Self { Self { sink, stream: stream.fuse(), buffered: None } } fn try_start_send( &mut self, cx: &mut Context<'_>, item: St::Ok, ) -> Poll> { debug_assert!(self.buffered.is_none()); match Pin::new(&mut self.sink).poll_ready(cx)? { Poll::Ready(()) => Poll::Ready(Pin::new(&mut self.sink).start_send(item)), Poll::Pending => { self.buffered = Some(item); Poll::Pending } } } } impl Future for SendAll<'_, Si, St> where Si: Sink + Unpin + ?Sized, St: Stream> + Unpin + ?Sized, { type Output = Result<(), Error>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = &mut *self; // If we've got an item buffered already, we need to write it to the // sink before we can do anything else if let Some(item) = this.buffered.take() { ready!(this.try_start_send(cx, item))? } loop { match this.stream.try_poll_next_unpin(cx)? { Poll::Ready(Some(item)) => ready!(this.try_start_send(cx, item))?, Poll::Ready(None) => { ready!(Pin::new(&mut this.sink).poll_flush(cx))?; return Poll::Ready(Ok(())); } Poll::Pending => { ready!(Pin::new(&mut this.sink).poll_flush(cx))?; return Poll::Pending; } } } } } futures-util-0.3.30/src/sink/unfold.rs000064400000000000000000000051351046102023000157530ustar 00000000000000use super::assert_sink; use crate::unfold_state::UnfoldState; use core::{future::Future, pin::Pin}; use futures_core::ready; use futures_core::task::{Context, Poll}; use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Sink for the [`unfold`] function. #[derive(Debug)] #[must_use = "sinks do nothing unless polled"] pub struct Unfold { function: F, #[pin] state: UnfoldState, } } /// Create a sink from a function which processes one item at a time. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::sink::{self, SinkExt}; /// /// let unfold = sink::unfold(0, |mut sum, i: i32| { /// async move { /// sum += i; /// eprintln!("{}", i); /// Ok::<_, futures::never::Never>(sum) /// } /// }); /// futures::pin_mut!(unfold); /// unfold.send(5).await?; /// # Ok::<(), futures::never::Never>(()) }).unwrap(); /// ``` pub fn unfold(init: T, function: F) -> Unfold where F: FnMut(T, Item) -> R, R: Future>, { assert_sink::(Unfold { function, state: UnfoldState::Value { value: init } }) } impl Sink for Unfold where F: FnMut(T, Item) -> R, R: Future>, { type Error = E; fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.poll_flush(cx) } fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { let mut this = self.project(); let future = match this.state.as_mut().take_value() { Some(value) => (this.function)(value, item), None => panic!("start_send called without poll_ready being called first"), }; this.state.set(UnfoldState::Future { future }); Ok(()) } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); Poll::Ready(if let Some(future) = this.state.as_mut().project_future() { match ready!(future.poll(cx)) { Ok(state) => { this.state.set(UnfoldState::Value { value: state }); Ok(()) } Err(err) => { this.state.set(UnfoldState::Empty); Err(err) } } } else { Ok(()) }) } fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.poll_flush(cx) } } futures-util-0.3.30/src/sink/with.rs000064400000000000000000000067331046102023000154440ustar 00000000000000use core::fmt; use core::marker::PhantomData; use core::pin::Pin; use futures_core::future::Future; use futures_core::ready; use futures_core::stream::Stream; use futures_core::task::{Context, Poll}; use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Sink for the [`with`](super::SinkExt::with) method. #[must_use = "sinks do nothing unless polled"] pub struct With { #[pin] sink: Si, f: F, #[pin] state: Option, _phantom: PhantomData Item>, } } impl fmt::Debug for With where Si: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("With").field("sink", &self.sink).field("state", &self.state).finish() } } impl With where Si: Sink, F: FnMut(U) -> Fut, Fut: Future, { pub(super) fn new(sink: Si, f: F) -> Self where Fut: Future>, E: From, { Self { state: None, sink, f, _phantom: PhantomData } } } impl Clone for With where Si: Clone, F: Clone, Fut: Clone, { fn clone(&self) -> Self { Self { state: self.state.clone(), sink: self.sink.clone(), f: self.f.clone(), _phantom: PhantomData, } } } // Forwarding impl of Stream from the underlying sink impl Stream for With where S: Stream + Sink, F: FnMut(U) -> Fut, Fut: Future, { type Item = S::Item; delegate_stream!(sink); } impl With where Si: Sink, F: FnMut(U) -> Fut, Fut: Future>, E: From, { delegate_access_inner!(sink, Si, ()); /// Completes the processing of previous item if any. fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); let item = match this.state.as_mut().as_pin_mut() { None => return Poll::Ready(Ok(())), Some(fut) => ready!(fut.poll(cx))?, }; this.state.set(None); this.sink.start_send(item)?; Poll::Ready(Ok(())) } } impl Sink for With where Si: Sink, F: FnMut(U) -> Fut, Fut: Future>, E: From, { type Error = E; fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { ready!(self.as_mut().poll(cx))?; ready!(self.project().sink.poll_ready(cx)?); Poll::Ready(Ok(())) } fn start_send(self: Pin<&mut Self>, item: U) -> Result<(), Self::Error> { let mut this = self.project(); assert!(this.state.is_none()); this.state.set(Some((this.f)(item))); Ok(()) } fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { ready!(self.as_mut().poll(cx))?; ready!(self.project().sink.poll_flush(cx)?); Poll::Ready(Ok(())) } fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { ready!(self.as_mut().poll(cx))?; ready!(self.project().sink.poll_close(cx)?); Poll::Ready(Ok(())) } } futures-util-0.3.30/src/sink/with_flat_map.rs000064400000000000000000000072461046102023000173070ustar 00000000000000use core::fmt; use core::marker::PhantomData; use core::pin::Pin; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Sink for the [`with_flat_map`](super::SinkExt::with_flat_map) method. #[must_use = "sinks do nothing unless polled"] pub struct WithFlatMap { #[pin] sink: Si, f: F, #[pin] stream: Option, buffer: Option, _marker: PhantomData, } } impl fmt::Debug for WithFlatMap where Si: fmt::Debug, St: fmt::Debug, Item: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("WithFlatMap") .field("sink", &self.sink) .field("stream", &self.stream) .field("buffer", &self.buffer) .finish() } } impl WithFlatMap where Si: Sink, F: FnMut(U) -> St, St: Stream>, { pub(super) fn new(sink: Si, f: F) -> Self { Self { sink, f, stream: None, buffer: None, _marker: PhantomData } } delegate_access_inner!(sink, Si, ()); fn try_empty_stream(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); if this.buffer.is_some() { ready!(this.sink.as_mut().poll_ready(cx))?; let item = this.buffer.take().unwrap(); this.sink.as_mut().start_send(item)?; } if let Some(mut some_stream) = this.stream.as_mut().as_pin_mut() { while let Some(item) = ready!(some_stream.as_mut().poll_next(cx)?) { match this.sink.as_mut().poll_ready(cx)? { Poll::Ready(()) => this.sink.as_mut().start_send(item)?, Poll::Pending => { *this.buffer = Some(item); return Poll::Pending; } }; } } this.stream.set(None); Poll::Ready(Ok(())) } } // Forwarding impl of Stream from the underlying sink impl Stream for WithFlatMap where S: Stream + Sink, F: FnMut(U) -> St, St: Stream>, { type Item = S::Item; delegate_stream!(sink); } impl FusedStream for WithFlatMap where S: FusedStream + Sink, F: FnMut(U) -> St, St: Stream>, { fn is_terminated(&self) -> bool { self.sink.is_terminated() } } impl Sink for WithFlatMap where Si: Sink, F: FnMut(U) -> St, St: Stream>, { type Error = Si::Error; fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.try_empty_stream(cx) } fn start_send(self: Pin<&mut Self>, item: U) -> Result<(), Self::Error> { let mut this = self.project(); assert!(this.stream.is_none()); this.stream.set(Some((this.f)(item))); Ok(()) } fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { ready!(self.as_mut().try_empty_stream(cx)?); self.project().sink.poll_flush(cx) } fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { ready!(self.as_mut().try_empty_stream(cx)?); self.project().sink.poll_close(cx) } } futures-util-0.3.30/src/stream/abortable.rs000064400000000000000000000012711046102023000167430ustar 00000000000000use super::assert_stream; use crate::stream::{AbortHandle, Abortable}; use crate::Stream; /// Creates a new `Abortable` stream and an `AbortHandle` which can be used to stop it. /// /// This function is a convenient (but less flexible) alternative to calling /// `AbortHandle::new` and `Abortable::new` manually. /// /// This function is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. pub fn abortable(stream: St) -> (Abortable, AbortHandle) where St: Stream, { let (handle, reg) = AbortHandle::new_pair(); let abortable = assert_stream::(Abortable::new(stream, reg)); (abortable, handle) } futures-util-0.3.30/src/stream/empty.rs000064400000000000000000000017611046102023000161520ustar 00000000000000use super::assert_stream; use core::marker::PhantomData; use core::pin::Pin; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; /// Stream for the [`empty`] function. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct Empty { _phantom: PhantomData, } /// Creates a stream which contains no elements. /// /// The returned stream will always return `Ready(None)` when polled. pub fn empty() -> Empty { assert_stream::(Empty { _phantom: PhantomData }) } impl Unpin for Empty {} impl FusedStream for Empty { fn is_terminated(&self) -> bool { true } } impl Stream for Empty { type Item = T; fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { Poll::Ready(None) } fn size_hint(&self) -> (usize, Option) { (0, Some(0)) } } impl Clone for Empty { fn clone(&self) -> Self { empty() } } futures-util-0.3.30/src/stream/futures_ordered.rs000064400000000000000000000214411046102023000202120ustar 00000000000000use crate::stream::{FuturesUnordered, StreamExt}; use alloc::collections::binary_heap::{BinaryHeap, PeekMut}; use core::cmp::Ordering; use core::fmt::{self, Debug}; use core::iter::FromIterator; use core::pin::Pin; use futures_core::future::Future; use futures_core::ready; use futures_core::stream::Stream; use futures_core::{ task::{Context, Poll}, FusedStream, }; use pin_project_lite::pin_project; pin_project! { #[must_use = "futures do nothing unless you `.await` or poll them"] #[derive(Debug)] struct OrderWrapper { #[pin] data: T, // A future or a future's output // Use i64 for index since isize may overflow in 32-bit targets. index: i64, } } impl PartialEq for OrderWrapper { fn eq(&self, other: &Self) -> bool { self.index == other.index } } impl Eq for OrderWrapper {} impl PartialOrd for OrderWrapper { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for OrderWrapper { fn cmp(&self, other: &Self) -> Ordering { // BinaryHeap is a max heap, so compare backwards here. other.index.cmp(&self.index) } } impl Future for OrderWrapper where T: Future, { type Output = OrderWrapper; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let index = self.index; self.project().data.poll(cx).map(|output| OrderWrapper { data: output, index }) } } /// An unbounded queue of futures. /// /// This "combinator" is similar to [`FuturesUnordered`], but it imposes a FIFO /// order on top of the set of futures. While futures in the set will race to /// completion in parallel, results will only be returned in the order their /// originating futures were added to the queue. /// /// Futures are pushed into this queue and their realized values are yielded in /// order. This structure is optimized to manage a large number of futures. /// Futures managed by [`FuturesOrdered`] will only be polled when they generate /// notifications. This reduces the required amount of work needed to coordinate /// large numbers of futures. /// /// When a [`FuturesOrdered`] is first created, it does not contain any futures. /// Calling [`poll_next`](FuturesOrdered::poll_next) in this state will result /// in [`Poll::Ready(None)`](Poll::Ready) to be returned. Futures are submitted /// to the queue using [`push_back`](FuturesOrdered::push_back) (or /// [`push_front`](FuturesOrdered::push_front)); however, the future will /// **not** be polled at this point. [`FuturesOrdered`] will only poll managed /// futures when [`FuturesOrdered::poll_next`] is called. As such, it /// is important to call [`poll_next`](FuturesOrdered::poll_next) after pushing /// new futures. /// /// If [`FuturesOrdered::poll_next`] returns [`Poll::Ready(None)`](Poll::Ready) /// this means that the queue is currently not managing any futures. A future /// may be submitted to the queue at a later time. At that point, a call to /// [`FuturesOrdered::poll_next`] will either return the future's resolved value /// **or** [`Poll::Pending`] if the future has not yet completed. When /// multiple futures are submitted to the queue, [`FuturesOrdered::poll_next`] /// will return [`Poll::Pending`] until the first future completes, even if /// some of the later futures have already completed. /// /// Note that you can create a ready-made [`FuturesOrdered`] via the /// [`collect`](Iterator::collect) method, or you can start with an empty queue /// with the [`FuturesOrdered::new`] constructor. /// /// This type is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. #[must_use = "streams do nothing unless polled"] pub struct FuturesOrdered { in_progress_queue: FuturesUnordered>, queued_outputs: BinaryHeap>, next_incoming_index: i64, next_outgoing_index: i64, } impl Unpin for FuturesOrdered {} impl FuturesOrdered { /// Constructs a new, empty `FuturesOrdered` /// /// The returned [`FuturesOrdered`] does not contain any futures and, in /// this state, [`FuturesOrdered::poll_next`] will return /// [`Poll::Ready(None)`](Poll::Ready). pub fn new() -> Self { Self { in_progress_queue: FuturesUnordered::new(), queued_outputs: BinaryHeap::new(), next_incoming_index: 0, next_outgoing_index: 0, } } /// Returns the number of futures contained in the queue. /// /// This represents the total number of in-flight futures, both /// those currently processing and those that have completed but /// which are waiting for earlier futures to complete. pub fn len(&self) -> usize { self.in_progress_queue.len() + self.queued_outputs.len() } /// Returns `true` if the queue contains no futures pub fn is_empty(&self) -> bool { self.in_progress_queue.is_empty() && self.queued_outputs.is_empty() } /// Push a future into the queue. /// /// This function submits the given future to the internal set for managing. /// This function will not call [`poll`](Future::poll) on the submitted /// future. The caller must ensure that [`FuturesOrdered::poll_next`] is /// called in order to receive task notifications. #[deprecated(note = "use `push_back` instead")] pub fn push(&mut self, future: Fut) { self.push_back(future); } /// Pushes a future to the back of the queue. /// /// This function submits the given future to the internal set for managing. /// This function will not call [`poll`](Future::poll) on the submitted /// future. The caller must ensure that [`FuturesOrdered::poll_next`] is /// called in order to receive task notifications. pub fn push_back(&mut self, future: Fut) { let wrapped = OrderWrapper { data: future, index: self.next_incoming_index }; self.next_incoming_index += 1; self.in_progress_queue.push(wrapped); } /// Pushes a future to the front of the queue. /// /// This function submits the given future to the internal set for managing. /// This function will not call [`poll`](Future::poll) on the submitted /// future. The caller must ensure that [`FuturesOrdered::poll_next`] is /// called in order to receive task notifications. This future will be /// the next future to be returned complete. pub fn push_front(&mut self, future: Fut) { let wrapped = OrderWrapper { data: future, index: self.next_outgoing_index - 1 }; self.next_outgoing_index -= 1; self.in_progress_queue.push(wrapped); } } impl Default for FuturesOrdered { fn default() -> Self { Self::new() } } impl Stream for FuturesOrdered { type Item = Fut::Output; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = &mut *self; // Check to see if we've already received the next value if let Some(next_output) = this.queued_outputs.peek_mut() { if next_output.index == this.next_outgoing_index { this.next_outgoing_index += 1; return Poll::Ready(Some(PeekMut::pop(next_output).data)); } } loop { match ready!(this.in_progress_queue.poll_next_unpin(cx)) { Some(output) => { if output.index == this.next_outgoing_index { this.next_outgoing_index += 1; return Poll::Ready(Some(output.data)); } else { this.queued_outputs.push(output) } } None => return Poll::Ready(None), } } } fn size_hint(&self) -> (usize, Option) { let len = self.len(); (len, Some(len)) } } impl Debug for FuturesOrdered { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "FuturesOrdered {{ ... }}") } } impl FromIterator for FuturesOrdered { fn from_iter(iter: T) -> Self where T: IntoIterator, { let acc = Self::new(); iter.into_iter().fold(acc, |mut acc, item| { acc.push_back(item); acc }) } } impl FusedStream for FuturesOrdered { fn is_terminated(&self) -> bool { self.in_progress_queue.is_terminated() && self.queued_outputs.is_empty() } } impl Extend for FuturesOrdered { fn extend(&mut self, iter: I) where I: IntoIterator, { for item in iter { self.push_back(item); } } } futures-util-0.3.30/src/stream/futures_unordered/abort.rs000064400000000000000000000003731046102023000216650ustar 00000000000000pub(super) fn abort(s: &str) -> ! { struct DoublePanic; impl Drop for DoublePanic { fn drop(&mut self) { panic!("panicking twice to abort the program"); } } let _bomb = DoublePanic; panic!("{}", s); } futures-util-0.3.30/src/stream/futures_unordered/iter.rs000064400000000000000000000123611046102023000215210ustar 00000000000000use super::task::Task; use super::FuturesUnordered; use core::marker::PhantomData; use core::pin::Pin; use core::ptr; use core::sync::atomic::Ordering::Relaxed; /// Mutable iterator over all futures in the unordered set. #[derive(Debug)] pub struct IterPinMut<'a, Fut> { pub(super) task: *const Task, pub(super) len: usize, pub(super) _marker: PhantomData<&'a mut FuturesUnordered>, } /// Mutable iterator over all futures in the unordered set. #[derive(Debug)] pub struct IterMut<'a, Fut: Unpin>(pub(super) IterPinMut<'a, Fut>); /// Immutable iterator over all futures in the unordered set. #[derive(Debug)] pub struct IterPinRef<'a, Fut> { pub(super) task: *const Task, pub(super) len: usize, pub(super) pending_next_all: *mut Task, pub(super) _marker: PhantomData<&'a FuturesUnordered>, } /// Immutable iterator over all the futures in the unordered set. #[derive(Debug)] pub struct Iter<'a, Fut: Unpin>(pub(super) IterPinRef<'a, Fut>); /// Owned iterator over all futures in the unordered set. #[derive(Debug)] pub struct IntoIter { pub(super) len: usize, pub(super) inner: FuturesUnordered, } impl Iterator for IntoIter { type Item = Fut; fn next(&mut self) -> Option { // `head_all` can be accessed directly and we don't need to spin on // `Task::next_all` since we have exclusive access to the set. let task = self.inner.head_all.get_mut(); if (*task).is_null() { return None; } unsafe { // Moving out of the future is safe because it is `Unpin` let future = (*(**task).future.get()).take().unwrap(); // Mutable access to a previously shared `FuturesUnordered` implies // that the other threads already released the object before the // current thread acquired it, so relaxed ordering can be used and // valid `next_all` checks can be skipped. let next = (**task).next_all.load(Relaxed); *task = next; if !task.is_null() { *(**task).prev_all.get() = ptr::null_mut(); } self.len -= 1; Some(future) } } fn size_hint(&self) -> (usize, Option) { (self.len, Some(self.len)) } } impl ExactSizeIterator for IntoIter {} impl<'a, Fut> Iterator for IterPinMut<'a, Fut> { type Item = Pin<&'a mut Fut>; fn next(&mut self) -> Option { if self.task.is_null() { return None; } unsafe { let future = (*(*self.task).future.get()).as_mut().unwrap(); // Mutable access to a previously shared `FuturesUnordered` implies // that the other threads already released the object before the // current thread acquired it, so relaxed ordering can be used and // valid `next_all` checks can be skipped. let next = (*self.task).next_all.load(Relaxed); self.task = next; self.len -= 1; Some(Pin::new_unchecked(future)) } } fn size_hint(&self) -> (usize, Option) { (self.len, Some(self.len)) } } impl ExactSizeIterator for IterPinMut<'_, Fut> {} impl<'a, Fut: Unpin> Iterator for IterMut<'a, Fut> { type Item = &'a mut Fut; fn next(&mut self) -> Option { self.0.next().map(Pin::get_mut) } fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } } impl ExactSizeIterator for IterMut<'_, Fut> {} impl<'a, Fut> Iterator for IterPinRef<'a, Fut> { type Item = Pin<&'a Fut>; fn next(&mut self) -> Option { if self.task.is_null() { return None; } unsafe { let future = (*(*self.task).future.get()).as_ref().unwrap(); // Relaxed ordering can be used since acquire ordering when // `head_all` was initially read for this iterator implies acquire // ordering for all previously inserted nodes (and we don't need to // read `len_all` again for any other nodes). let next = (*self.task).spin_next_all(self.pending_next_all, Relaxed); self.task = next; self.len -= 1; Some(Pin::new_unchecked(future)) } } fn size_hint(&self) -> (usize, Option) { (self.len, Some(self.len)) } } impl ExactSizeIterator for IterPinRef<'_, Fut> {} impl<'a, Fut: Unpin> Iterator for Iter<'a, Fut> { type Item = &'a Fut; fn next(&mut self) -> Option { self.0.next().map(Pin::get_ref) } fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } } impl ExactSizeIterator for Iter<'_, Fut> {} // SAFETY: we do nothing thread-local and there is no interior mutability, // so the usual structural `Send`/`Sync` apply. unsafe impl Send for IterPinRef<'_, Fut> {} unsafe impl Sync for IterPinRef<'_, Fut> {} unsafe impl Send for IterPinMut<'_, Fut> {} unsafe impl Sync for IterPinMut<'_, Fut> {} unsafe impl Send for IntoIter {} unsafe impl Sync for IntoIter {} futures-util-0.3.30/src/stream/futures_unordered/mod.rs000064400000000000000000000640411046102023000213370ustar 00000000000000//! An unbounded set of futures. //! //! This module is only available when the `std` or `alloc` feature of this //! library is activated, and it is activated by default. use crate::task::AtomicWaker; use alloc::sync::{Arc, Weak}; use core::cell::UnsafeCell; use core::fmt::{self, Debug}; use core::iter::FromIterator; use core::marker::PhantomData; use core::mem; use core::pin::Pin; use core::ptr; use core::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release, SeqCst}; use core::sync::atomic::{AtomicBool, AtomicPtr}; use futures_core::future::Future; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use futures_task::{FutureObj, LocalFutureObj, LocalSpawn, Spawn, SpawnError}; mod abort; mod iter; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/102352 pub use self::iter::{IntoIter, Iter, IterMut, IterPinMut, IterPinRef}; mod task; use self::task::Task; mod ready_to_run_queue; use self::ready_to_run_queue::{Dequeue, ReadyToRunQueue}; /// A set of futures which may complete in any order. /// /// See [`FuturesOrdered`](crate::stream::FuturesOrdered) for a version of this /// type that preserves a FIFO order. /// /// This structure is optimized to manage a large number of futures. /// Futures managed by [`FuturesUnordered`] will only be polled when they /// generate wake-up notifications. This reduces the required amount of work /// needed to poll large numbers of futures. /// /// [`FuturesUnordered`] can be filled by [`collect`](Iterator::collect)ing an /// iterator of futures into a [`FuturesUnordered`], or by /// [`push`](FuturesUnordered::push)ing futures onto an existing /// [`FuturesUnordered`]. When new futures are added, /// [`poll_next`](Stream::poll_next) must be called in order to begin receiving /// wake-ups for new futures. /// /// Note that you can create a ready-made [`FuturesUnordered`] via the /// [`collect`](Iterator::collect) method, or you can start with an empty set /// with the [`FuturesUnordered::new`] constructor. /// /// This type is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. #[must_use = "streams do nothing unless polled"] pub struct FuturesUnordered { ready_to_run_queue: Arc>, head_all: AtomicPtr>, is_terminated: AtomicBool, } unsafe impl Send for FuturesUnordered {} unsafe impl Sync for FuturesUnordered {} impl Unpin for FuturesUnordered {} impl Spawn for FuturesUnordered> { fn spawn_obj(&self, future_obj: FutureObj<'static, ()>) -> Result<(), SpawnError> { self.push(future_obj); Ok(()) } } impl LocalSpawn for FuturesUnordered> { fn spawn_local_obj(&self, future_obj: LocalFutureObj<'static, ()>) -> Result<(), SpawnError> { self.push(future_obj); Ok(()) } } // FuturesUnordered is implemented using two linked lists. One which links all // futures managed by a `FuturesUnordered` and one that tracks futures that have // been scheduled for polling. The first linked list allows for thread safe // insertion of nodes at the head as well as forward iteration, but is otherwise // not thread safe and is only accessed by the thread that owns the // `FuturesUnordered` value for any other operations. The second linked list is // an implementation of the intrusive MPSC queue algorithm described by // 1024cores.net. // // When a future is submitted to the set, a task is allocated and inserted in // both linked lists. The next call to `poll_next` will (eventually) see this // task and call `poll` on the future. // // Before a managed future is polled, the current context's waker is replaced // with one that is aware of the specific future being run. This ensures that // wake-up notifications generated by that specific future are visible to // `FuturesUnordered`. When a wake-up notification is received, the task is // inserted into the ready to run queue, so that its future can be polled later. // // Each task is wrapped in an `Arc` and thereby atomically reference counted. // Also, each task contains an `AtomicBool` which acts as a flag that indicates // whether the task is currently inserted in the atomic queue. When a wake-up // notification is received, the task will only be inserted into the ready to // run queue if it isn't inserted already. impl Default for FuturesUnordered { fn default() -> Self { Self::new() } } impl FuturesUnordered { /// Constructs a new, empty [`FuturesUnordered`]. /// /// The returned [`FuturesUnordered`] does not contain any futures. /// In this state, [`FuturesUnordered::poll_next`](Stream::poll_next) will /// return [`Poll::Ready(None)`](Poll::Ready). pub fn new() -> Self { let stub = Arc::new(Task { future: UnsafeCell::new(None), next_all: AtomicPtr::new(ptr::null_mut()), prev_all: UnsafeCell::new(ptr::null()), len_all: UnsafeCell::new(0), next_ready_to_run: AtomicPtr::new(ptr::null_mut()), queued: AtomicBool::new(true), ready_to_run_queue: Weak::new(), woken: AtomicBool::new(false), }); let stub_ptr = Arc::as_ptr(&stub); let ready_to_run_queue = Arc::new(ReadyToRunQueue { waker: AtomicWaker::new(), head: AtomicPtr::new(stub_ptr as *mut _), tail: UnsafeCell::new(stub_ptr), stub, }); Self { head_all: AtomicPtr::new(ptr::null_mut()), ready_to_run_queue, is_terminated: AtomicBool::new(false), } } /// Returns the number of futures contained in the set. /// /// This represents the total number of in-flight futures. pub fn len(&self) -> usize { let (_, len) = self.atomic_load_head_and_len_all(); len } /// Returns `true` if the set contains no futures. pub fn is_empty(&self) -> bool { // Relaxed ordering can be used here since we don't need to read from // the head pointer, only check whether it is null. self.head_all.load(Relaxed).is_null() } /// Push a future into the set. /// /// This method adds the given future to the set. This method will not /// call [`poll`](core::future::Future::poll) on the submitted future. The caller must /// ensure that [`FuturesUnordered::poll_next`](Stream::poll_next) is called /// in order to receive wake-up notifications for the given future. pub fn push(&self, future: Fut) { let task = Arc::new(Task { future: UnsafeCell::new(Some(future)), next_all: AtomicPtr::new(self.pending_next_all()), prev_all: UnsafeCell::new(ptr::null_mut()), len_all: UnsafeCell::new(0), next_ready_to_run: AtomicPtr::new(ptr::null_mut()), queued: AtomicBool::new(true), ready_to_run_queue: Arc::downgrade(&self.ready_to_run_queue), woken: AtomicBool::new(false), }); // Reset the `is_terminated` flag if we've previously marked ourselves // as terminated. self.is_terminated.store(false, Relaxed); // Right now our task has a strong reference count of 1. We transfer // ownership of this reference count to our internal linked list // and we'll reclaim ownership through the `unlink` method below. let ptr = self.link(task); // We'll need to get the future "into the system" to start tracking it, // e.g. getting its wake-up notifications going to us tracking which // futures are ready. To do that we unconditionally enqueue it for // polling here. self.ready_to_run_queue.enqueue(ptr); } /// Returns an iterator that allows inspecting each future in the set. pub fn iter(&self) -> Iter<'_, Fut> where Fut: Unpin, { Iter(Pin::new(self).iter_pin_ref()) } /// Returns an iterator that allows inspecting each future in the set. pub fn iter_pin_ref(self: Pin<&Self>) -> IterPinRef<'_, Fut> { let (task, len) = self.atomic_load_head_and_len_all(); let pending_next_all = self.pending_next_all(); IterPinRef { task, len, pending_next_all, _marker: PhantomData } } /// Returns an iterator that allows modifying each future in the set. pub fn iter_mut(&mut self) -> IterMut<'_, Fut> where Fut: Unpin, { IterMut(Pin::new(self).iter_pin_mut()) } /// Returns an iterator that allows modifying each future in the set. pub fn iter_pin_mut(mut self: Pin<&mut Self>) -> IterPinMut<'_, Fut> { // `head_all` can be accessed directly and we don't need to spin on // `Task::next_all` since we have exclusive access to the set. let task = *self.head_all.get_mut(); let len = if task.is_null() { 0 } else { unsafe { *(*task).len_all.get() } }; IterPinMut { task, len, _marker: PhantomData } } /// Returns the current head node and number of futures in the list of all /// futures within a context where access is shared with other threads /// (mostly for use with the `len` and `iter_pin_ref` methods). fn atomic_load_head_and_len_all(&self) -> (*const Task, usize) { let task = self.head_all.load(Acquire); let len = if task.is_null() { 0 } else { unsafe { (*task).spin_next_all(self.pending_next_all(), Acquire); *(*task).len_all.get() } }; (task, len) } /// Releases the task. It destroys the future inside and either drops /// the `Arc` or transfers ownership to the ready to run queue. /// The task this method is called on must have been unlinked before. fn release_task(&mut self, task: Arc>) { // `release_task` must only be called on unlinked tasks debug_assert_eq!(task.next_all.load(Relaxed), self.pending_next_all()); unsafe { debug_assert!((*task.prev_all.get()).is_null()); } // The future is done, try to reset the queued flag. This will prevent // `wake` from doing any work in the future let prev = task.queued.swap(true, SeqCst); // Drop the future, even if it hasn't finished yet. This is safe // because we're dropping the future on the thread that owns // `FuturesUnordered`, which correctly tracks `Fut`'s lifetimes and // such. unsafe { // Set to `None` rather than `take()`ing to prevent moving the // future. *task.future.get() = None; } // If the queued flag was previously set, then it means that this task // is still in our internal ready to run queue. We then transfer // ownership of our reference count to the ready to run queue, and it'll // come along and free it later, noticing that the future is `None`. // // If, however, the queued flag was *not* set then we're safe to // release our reference count on the task. The queued flag was set // above so all future `enqueue` operations will not actually // enqueue the task, so our task will never see the ready to run queue // again. The task itself will be deallocated once all reference counts // have been dropped elsewhere by the various wakers that contain it. if prev { mem::forget(task); } } /// Insert a new task into the internal linked list. fn link(&self, task: Arc>) -> *const Task { // `next_all` should already be reset to the pending state before this // function is called. debug_assert_eq!(task.next_all.load(Relaxed), self.pending_next_all()); let ptr = Arc::into_raw(task); // Atomically swap out the old head node to get the node that should be // assigned to `next_all`. let next = self.head_all.swap(ptr as *mut _, AcqRel); unsafe { // Store the new list length in the new node. let new_len = if next.is_null() { 1 } else { // Make sure `next_all` has been written to signal that it is // safe to read `len_all`. (*next).spin_next_all(self.pending_next_all(), Acquire); *(*next).len_all.get() + 1 }; *(*ptr).len_all.get() = new_len; // Write the old head as the next node pointer, signaling to other // threads that `len_all` and `next_all` are ready to read. (*ptr).next_all.store(next, Release); // `prev_all` updates don't need to be synchronized, as the field is // only ever used after exclusive access has been acquired. if !next.is_null() { *(*next).prev_all.get() = ptr; } } ptr } /// Remove the task from the linked list tracking all tasks currently /// managed by `FuturesUnordered`. /// This method is unsafe because it has be guaranteed that `task` is a /// valid pointer. unsafe fn unlink(&mut self, task: *const Task) -> Arc> { // Compute the new list length now in case we're removing the head node // and won't be able to retrieve the correct length later. let head = *self.head_all.get_mut(); debug_assert!(!head.is_null()); let new_len = *(*head).len_all.get() - 1; let task = Arc::from_raw(task); let next = task.next_all.load(Relaxed); let prev = *task.prev_all.get(); task.next_all.store(self.pending_next_all(), Relaxed); *task.prev_all.get() = ptr::null_mut(); if !next.is_null() { *(*next).prev_all.get() = prev; } if !prev.is_null() { (*prev).next_all.store(next, Relaxed); } else { *self.head_all.get_mut() = next; } // Store the new list length in the head node. let head = *self.head_all.get_mut(); if !head.is_null() { *(*head).len_all.get() = new_len; } task } /// Returns the reserved value for `Task::next_all` to indicate a pending /// assignment from the thread that inserted the task. /// /// `FuturesUnordered::link` needs to update `Task` pointers in an order /// that ensures any iterators created on other threads can correctly /// traverse the entire `Task` list using the chain of `next_all` pointers. /// This could be solved with a compare-exchange loop that stores the /// current `head_all` in `next_all` and swaps out `head_all` with the new /// `Task` pointer if the head hasn't already changed. Under heavy thread /// contention, this compare-exchange loop could become costly. /// /// An alternative is to initialize `next_all` to a reserved pending state /// first, perform an atomic swap on `head_all`, and finally update /// `next_all` with the old head node. Iterators will then either see the /// pending state value or the correct next node pointer, and can reload /// `next_all` as needed until the correct value is loaded. The number of /// retries needed (if any) would be small and will always be finite, so /// this should generally perform better than the compare-exchange loop. /// /// A valid `Task` pointer in the `head_all` list is guaranteed to never be /// this value, so it is safe to use as a reserved value until the correct /// value can be written. fn pending_next_all(&self) -> *mut Task { // The `ReadyToRunQueue` stub is never inserted into the `head_all` // list, and its pointer value will remain valid for the lifetime of // this `FuturesUnordered`, so we can make use of its value here. Arc::as_ptr(&self.ready_to_run_queue.stub) as *mut _ } } impl Stream for FuturesUnordered { type Item = Fut::Output; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let len = self.len(); // Keep track of how many child futures we have polled, // in case we want to forcibly yield. let mut polled = 0; let mut yielded = 0; // Ensure `parent` is correctly set. self.ready_to_run_queue.waker.register(cx.waker()); loop { // Safety: &mut self guarantees the mutual exclusion `dequeue` // expects let task = match unsafe { self.ready_to_run_queue.dequeue() } { Dequeue::Empty => { if self.is_empty() { // We can only consider ourselves terminated once we // have yielded a `None` *self.is_terminated.get_mut() = true; return Poll::Ready(None); } else { return Poll::Pending; } } Dequeue::Inconsistent => { // At this point, it may be worth yielding the thread & // spinning a few times... but for now, just yield using the // task system. cx.waker().wake_by_ref(); return Poll::Pending; } Dequeue::Data(task) => task, }; debug_assert!(task != self.ready_to_run_queue.stub()); // Safety: // - `task` is a valid pointer. // - We are the only thread that accesses the `UnsafeCell` that // contains the future let future = match unsafe { &mut *(*task).future.get() } { Some(future) => future, // If the future has already gone away then we're just // cleaning out this task. See the comment in // `release_task` for more information, but we're basically // just taking ownership of our reference count here. None => { // This case only happens when `release_task` was called // for this task before and couldn't drop the task // because it was already enqueued in the ready to run // queue. // Safety: `task` is a valid pointer let task = unsafe { Arc::from_raw(task) }; // Double check that the call to `release_task` really // happened. Calling it required the task to be unlinked. debug_assert_eq!(task.next_all.load(Relaxed), self.pending_next_all()); unsafe { debug_assert!((*task.prev_all.get()).is_null()); } continue; } }; // Safety: `task` is a valid pointer let task = unsafe { self.unlink(task) }; // Unset queued flag: This must be done before polling to ensure // that the future's task gets rescheduled if it sends a wake-up // notification **during** the call to `poll`. let prev = task.queued.swap(false, SeqCst); assert!(prev); // We're going to need to be very careful if the `poll` // method below panics. We need to (a) not leak memory and // (b) ensure that we still don't have any use-after-frees. To // manage this we do a few things: // // * A "bomb" is created which if dropped abnormally will call // `release_task`. That way we'll be sure the memory management // of the `task` is managed correctly. In particular // `release_task` will drop the future. This ensures that it is // dropped on this thread and not accidentally on a different // thread (bad). // * We unlink the task from our internal queue to preemptively // assume it'll panic, in which case we'll want to discard it // regardless. struct Bomb<'a, Fut> { queue: &'a mut FuturesUnordered, task: Option>>, } impl Drop for Bomb<'_, Fut> { fn drop(&mut self) { if let Some(task) = self.task.take() { self.queue.release_task(task); } } } let mut bomb = Bomb { task: Some(task), queue: &mut *self }; // Poll the underlying future with the appropriate waker // implementation. This is where a large bit of the unsafety // starts to stem from internally. The waker is basically just // our `Arc>` and can schedule the future for polling by // enqueuing itself in the ready to run queue. // // Critically though `Task` won't actually access `Fut`, the // future, while it's floating around inside of wakers. // These structs will basically just use `Fut` to size // the internal allocation, appropriately accessing fields and // deallocating the task if need be. let res = { let task = bomb.task.as_ref().unwrap(); // We are only interested in whether the future is awoken before it // finishes polling, so reset the flag here. task.woken.store(false, Relaxed); let waker = Task::waker_ref(task); let mut cx = Context::from_waker(&waker); // Safety: We won't move the future ever again let future = unsafe { Pin::new_unchecked(future) }; future.poll(&mut cx) }; polled += 1; match res { Poll::Pending => { let task = bomb.task.take().unwrap(); // If the future was awoken during polling, we assume // the future wanted to explicitly yield. yielded += task.woken.load(Relaxed) as usize; bomb.queue.link(task); // If a future yields, we respect it and yield here. // If all futures have been polled, we also yield here to // avoid starving other tasks waiting on the executor. // (polling the same future twice per iteration may cause // the problem: https://github.com/rust-lang/futures-rs/pull/2333) if yielded >= 2 || polled == len { cx.waker().wake_by_ref(); return Poll::Pending; } continue; } Poll::Ready(output) => return Poll::Ready(Some(output)), } } } fn size_hint(&self) -> (usize, Option) { let len = self.len(); (len, Some(len)) } } impl Debug for FuturesUnordered { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "FuturesUnordered {{ ... }}") } } impl FuturesUnordered { /// Clears the set, removing all futures. pub fn clear(&mut self) { *self = Self::new(); } } impl Drop for FuturesUnordered { fn drop(&mut self) { // When a `FuturesUnordered` is dropped we want to drop all futures // associated with it. At the same time though there may be tons of // wakers flying around which contain `Task` references // inside them. We'll let those naturally get deallocated. while !self.head_all.get_mut().is_null() { let head = *self.head_all.get_mut(); let task = unsafe { self.unlink(head) }; self.release_task(task); } // Note that at this point we could still have a bunch of tasks in the // ready to run queue. None of those tasks, however, have futures // associated with them so they're safe to destroy on any thread. At // this point the `FuturesUnordered` struct, the owner of the one strong // reference to the ready to run queue will drop the strong reference. // At that point whichever thread releases the strong refcount last (be // it this thread or some other thread as part of an `upgrade`) will // clear out the ready to run queue and free all remaining tasks. // // While that freeing operation isn't guaranteed to happen here, it's // guaranteed to happen "promptly" as no more "blocking work" will // happen while there's a strong refcount held. } } impl<'a, Fut: Unpin> IntoIterator for &'a FuturesUnordered { type Item = &'a Fut; type IntoIter = Iter<'a, Fut>; fn into_iter(self) -> Self::IntoIter { self.iter() } } impl<'a, Fut: Unpin> IntoIterator for &'a mut FuturesUnordered { type Item = &'a mut Fut; type IntoIter = IterMut<'a, Fut>; fn into_iter(self) -> Self::IntoIter { self.iter_mut() } } impl IntoIterator for FuturesUnordered { type Item = Fut; type IntoIter = IntoIter; fn into_iter(mut self) -> Self::IntoIter { // `head_all` can be accessed directly and we don't need to spin on // `Task::next_all` since we have exclusive access to the set. let task = *self.head_all.get_mut(); let len = if task.is_null() { 0 } else { unsafe { *(*task).len_all.get() } }; IntoIter { len, inner: self } } } impl FromIterator for FuturesUnordered { fn from_iter(iter: I) -> Self where I: IntoIterator, { let acc = Self::new(); iter.into_iter().fold(acc, |acc, item| { acc.push(item); acc }) } } impl FusedStream for FuturesUnordered { fn is_terminated(&self) -> bool { self.is_terminated.load(Relaxed) } } impl Extend for FuturesUnordered { fn extend(&mut self, iter: I) where I: IntoIterator, { for item in iter { self.push(item); } } } futures-util-0.3.30/src/stream/futures_unordered/ready_to_run_queue.rs000064400000000000000000000066701046102023000244620ustar 00000000000000use crate::task::AtomicWaker; use alloc::sync::Arc; use core::cell::UnsafeCell; use core::ptr; use core::sync::atomic::AtomicPtr; use core::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release}; use super::abort::abort; use super::task::Task; pub(super) enum Dequeue { Data(*const Task), Empty, Inconsistent, } pub(super) struct ReadyToRunQueue { // The waker of the task using `FuturesUnordered`. pub(super) waker: AtomicWaker, // Head/tail of the readiness queue pub(super) head: AtomicPtr>, pub(super) tail: UnsafeCell<*const Task>, pub(super) stub: Arc>, } /// An MPSC queue into which the tasks containing the futures are inserted /// whenever the future inside is scheduled for polling. impl ReadyToRunQueue { /// The enqueue function from the 1024cores intrusive MPSC queue algorithm. pub(super) fn enqueue(&self, task: *const Task) { unsafe { debug_assert!((*task).queued.load(Relaxed)); // This action does not require any coordination (*task).next_ready_to_run.store(ptr::null_mut(), Relaxed); // Note that these atomic orderings come from 1024cores let task = task as *mut _; let prev = self.head.swap(task, AcqRel); (*prev).next_ready_to_run.store(task, Release); } } /// The dequeue function from the 1024cores intrusive MPSC queue algorithm /// /// Note that this is unsafe as it required mutual exclusion (only one /// thread can call this) to be guaranteed elsewhere. pub(super) unsafe fn dequeue(&self) -> Dequeue { let mut tail = *self.tail.get(); let mut next = (*tail).next_ready_to_run.load(Acquire); if tail == self.stub() { if next.is_null() { return Dequeue::Empty; } *self.tail.get() = next; tail = next; next = (*next).next_ready_to_run.load(Acquire); } if !next.is_null() { *self.tail.get() = next; debug_assert!(tail != self.stub()); return Dequeue::Data(tail); } if self.head.load(Acquire) as *const _ != tail { return Dequeue::Inconsistent; } self.enqueue(self.stub()); next = (*tail).next_ready_to_run.load(Acquire); if !next.is_null() { *self.tail.get() = next; return Dequeue::Data(tail); } Dequeue::Inconsistent } pub(super) fn stub(&self) -> *const Task { Arc::as_ptr(&self.stub) } } impl Drop for ReadyToRunQueue { fn drop(&mut self) { // Once we're in the destructor for `Inner` we need to clear out // the ready to run queue of tasks if there's anything left in there. // // Note that each task has a strong reference count associated with it // which is owned by the ready to run queue. All tasks should have had // their futures dropped already by the `FuturesUnordered` destructor // above, so we're just pulling out tasks and dropping their refcounts. unsafe { loop { match self.dequeue() { Dequeue::Empty => break, Dequeue::Inconsistent => abort("inconsistent in drop"), Dequeue::Data(ptr) => drop(Arc::from_raw(ptr)), } } } } } futures-util-0.3.30/src/stream/futures_unordered/task.rs000064400000000000000000000107121046102023000215160ustar 00000000000000use alloc::sync::{Arc, Weak}; use core::cell::UnsafeCell; use core::sync::atomic::Ordering::{self, Relaxed, SeqCst}; use core::sync::atomic::{AtomicBool, AtomicPtr}; use super::abort::abort; use super::ReadyToRunQueue; use crate::task::{waker_ref, ArcWake, WakerRef}; pub(super) struct Task { // The future pub(super) future: UnsafeCell>, // Next pointer for linked list tracking all active tasks (use // `spin_next_all` to read when access is shared across threads) pub(super) next_all: AtomicPtr>, // Previous task in linked list tracking all active tasks pub(super) prev_all: UnsafeCell<*const Task>, // Length of the linked list tracking all active tasks when this node was // inserted (use `spin_next_all` to synchronize before reading when access // is shared across threads) pub(super) len_all: UnsafeCell, // Next pointer in ready to run queue pub(super) next_ready_to_run: AtomicPtr>, // Queue that we'll be enqueued to when woken pub(super) ready_to_run_queue: Weak>, // Whether or not this task is currently in the ready to run queue pub(super) queued: AtomicBool, // Whether the future was awoken during polling // It is possible for this flag to be set to true after the polling, // but it will be ignored. pub(super) woken: AtomicBool, } // `Task` can be sent across threads safely because it ensures that // the underlying `Fut` type isn't touched from any of its methods. // // The parent (`super`) module is trusted not to access `future` // across different threads. unsafe impl Send for Task {} unsafe impl Sync for Task {} impl ArcWake for Task { fn wake_by_ref(arc_self: &Arc) { let inner = match arc_self.ready_to_run_queue.upgrade() { Some(inner) => inner, None => return, }; arc_self.woken.store(true, Relaxed); // It's our job to enqueue this task it into the ready to run queue. To // do this we set the `queued` flag, and if successful we then do the // actual queueing operation, ensuring that we're only queued once. // // Once the task is inserted call `wake` to notify the parent task, // as it'll want to come along and run our task later. // // Note that we don't change the reference count of the task here, // we merely enqueue the raw pointer. The `FuturesUnordered` // implementation guarantees that if we set the `queued` flag that // there's a reference count held by the main `FuturesUnordered` queue // still. let prev = arc_self.queued.swap(true, SeqCst); if !prev { inner.enqueue(Arc::as_ptr(arc_self)); inner.waker.wake(); } } } impl Task { /// Returns a waker reference for this task without cloning the Arc. pub(super) fn waker_ref(this: &Arc) -> WakerRef<'_> { waker_ref(this) } /// Spins until `next_all` is no longer set to `pending_next_all`. /// /// The temporary `pending_next_all` value is typically overwritten fairly /// quickly after a node is inserted into the list of all futures, so this /// should rarely spin much. /// /// When it returns, the correct `next_all` value is returned. /// /// `Relaxed` or `Acquire` ordering can be used. `Acquire` ordering must be /// used before `len_all` can be safely read. #[inline] pub(super) fn spin_next_all( &self, pending_next_all: *mut Self, ordering: Ordering, ) -> *const Self { loop { let next = self.next_all.load(ordering); if next != pending_next_all { return next; } } } } impl Drop for Task { fn drop(&mut self) { // Since `Task` is sent across all threads for any lifetime, // regardless of `Fut`, we, to guarantee memory safety, can't actually // touch `Fut` at any time except when we have a reference to the // `FuturesUnordered` itself . // // Consequently it *should* be the case that we always drop futures from // the `FuturesUnordered` instance. This is a bomb, just in case there's // a bug in that logic. unsafe { if (*self.future.get()).is_some() { abort("future still here when dropping"); } } } } futures-util-0.3.30/src/stream/iter.rs000064400000000000000000000022571046102023000157600ustar 00000000000000use super::assert_stream; use core::pin::Pin; use futures_core::stream::Stream; use futures_core::task::{Context, Poll}; /// Stream for the [`iter`] function. #[derive(Debug, Clone)] #[must_use = "streams do nothing unless polled"] pub struct Iter { iter: I, } impl Unpin for Iter {} /// Converts an `Iterator` into a `Stream` which is always ready /// to yield the next value. /// /// Iterators in Rust don't express the ability to block, so this adapter /// simply always calls `iter.next()` and returns that. /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::iter(vec![17, 19]); /// assert_eq!(vec![17, 19], stream.collect::>().await); /// # }); /// ``` pub fn iter(i: I) -> Iter where I: IntoIterator, { assert_stream::(Iter { iter: i.into_iter() }) } impl Stream for Iter where I: Iterator, { type Item = I::Item; fn poll_next(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { Poll::Ready(self.iter.next()) } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } futures-util-0.3.30/src/stream/mod.rs000064400000000000000000000106501046102023000155700ustar 00000000000000//! Asynchronous streams. //! //! This module contains: //! //! - The [`Stream`] trait, for objects that can asynchronously produce a //! sequence of values. //! - The [`StreamExt`] and [`TryStreamExt`] trait, which provides adapters for //! chaining and composing streams. //! - Top-level stream constructors like [`iter`](iter()) which creates a //! stream from an iterator. #[cfg(feature = "alloc")] pub use futures_core::stream::{BoxStream, LocalBoxStream}; pub use futures_core::stream::{FusedStream, Stream, TryStream}; // Extension traits and combinators #[allow(clippy::module_inception)] mod stream; pub use self::stream::{ All, Any, Chain, Collect, Concat, Count, Cycle, Enumerate, Filter, FilterMap, FlatMap, Flatten, Fold, ForEach, Fuse, Inspect, Map, Next, NextIf, NextIfEq, Peek, PeekMut, Peekable, Scan, SelectNextSome, Skip, SkipWhile, StreamExt, StreamFuture, Take, TakeUntil, TakeWhile, Then, Unzip, Zip, }; #[cfg(feature = "std")] pub use self::stream::CatchUnwind; #[cfg(feature = "alloc")] pub use self::stream::Chunks; #[cfg(feature = "alloc")] pub use self::stream::ReadyChunks; #[cfg(feature = "sink")] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] pub use self::stream::Forward; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] pub use self::stream::{ BufferUnordered, Buffered, FlatMapUnordered, FlattenUnordered, ForEachConcurrent, }; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "sink")] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] #[cfg(feature = "alloc")] pub use self::stream::{ReuniteError, SplitSink, SplitStream}; mod try_stream; pub use self::try_stream::{ try_unfold, AndThen, ErrInto, InspectErr, InspectOk, IntoStream, MapErr, MapOk, OrElse, TryAll, TryAny, TryCollect, TryConcat, TryFilter, TryFilterMap, TryFlatten, TryFold, TryForEach, TryNext, TrySkipWhile, TryStreamExt, TryTakeWhile, TryUnfold, }; #[cfg(feature = "io")] #[cfg_attr(docsrs, doc(cfg(feature = "io")))] #[cfg(feature = "std")] pub use self::try_stream::IntoAsyncRead; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] pub use self::try_stream::{ TryBufferUnordered, TryBuffered, TryFlattenUnordered, TryForEachConcurrent, }; #[cfg(feature = "alloc")] pub use self::try_stream::{TryChunks, TryChunksError, TryReadyChunks, TryReadyChunksError}; // Primitive streams mod iter; pub use self::iter::{iter, Iter}; mod repeat; pub use self::repeat::{repeat, Repeat}; mod repeat_with; pub use self::repeat_with::{repeat_with, RepeatWith}; mod empty; pub use self::empty::{empty, Empty}; mod once; pub use self::once::{once, Once}; mod pending; pub use self::pending::{pending, Pending}; mod poll_fn; pub use self::poll_fn::{poll_fn, PollFn}; mod poll_immediate; pub use self::poll_immediate::{poll_immediate, PollImmediate}; mod select; pub use self::select::{select, Select}; mod select_with_strategy; pub use self::select_with_strategy::{select_with_strategy, PollNext, SelectWithStrategy}; mod unfold; pub use self::unfold::{unfold, Unfold}; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] mod futures_ordered; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] pub use self::futures_ordered::FuturesOrdered; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] pub mod futures_unordered; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] #[doc(inline)] pub use self::futures_unordered::FuturesUnordered; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] pub mod select_all; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] #[doc(inline)] pub use self::select_all::{select_all, SelectAll}; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] mod abortable; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] pub use crate::abortable::{AbortHandle, AbortRegistration, Abortable, Aborted}; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] pub use abortable::abortable; // Just a helper function to ensure the streams we're returning all have the // right implementations. pub(crate) fn assert_stream(stream: S) -> S where S: Stream, { stream } futures-util-0.3.30/src/stream/once.rs000064400000000000000000000032541046102023000157370ustar 00000000000000use super::assert_stream; use core::pin::Pin; use futures_core::future::Future; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; /// Creates a stream of a single element. /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::once(async { 17 }); /// let collected = stream.collect::>().await; /// assert_eq!(collected, vec![17]); /// # }); /// ``` pub fn once(future: Fut) -> Once { assert_stream::(Once::new(future)) } pin_project! { /// A stream which emits single element and then EOF. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct Once { #[pin] future: Option } } impl Once { pub(crate) fn new(future: Fut) -> Self { Self { future: Some(future) } } } impl Stream for Once { type Item = Fut::Output; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); let v = match this.future.as_mut().as_pin_mut() { Some(fut) => ready!(fut.poll(cx)), None => return Poll::Ready(None), }; this.future.set(None); Poll::Ready(Some(v)) } fn size_hint(&self) -> (usize, Option) { if self.future.is_some() { (1, Some(1)) } else { (0, Some(0)) } } } impl FusedStream for Once { fn is_terminated(&self) -> bool { self.future.is_none() } } futures-util-0.3.30/src/stream/pending.rs000064400000000000000000000020021046102023000164250ustar 00000000000000use super::assert_stream; use core::marker; use core::pin::Pin; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; /// Stream for the [`pending()`] function. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct Pending { _data: marker::PhantomData, } /// Creates a stream which never returns any elements. /// /// The returned stream will always return `Pending` when polled. pub fn pending() -> Pending { assert_stream::(Pending { _data: marker::PhantomData }) } impl Unpin for Pending {} impl FusedStream for Pending { fn is_terminated(&self) -> bool { true } } impl Stream for Pending { type Item = T; fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { Poll::Pending } fn size_hint(&self) -> (usize, Option) { (0, Some(0)) } } impl Clone for Pending { fn clone(&self) -> Self { pending() } } futures-util-0.3.30/src/stream/poll_fn.rs000064400000000000000000000024751046102023000164500ustar 00000000000000//! Definition of the `PollFn` combinator use super::assert_stream; use core::fmt; use core::pin::Pin; use futures_core::stream::Stream; use futures_core::task::{Context, Poll}; /// Stream for the [`poll_fn`] function. #[must_use = "streams do nothing unless polled"] pub struct PollFn { f: F, } impl Unpin for PollFn {} impl fmt::Debug for PollFn { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("PollFn").finish() } } /// Creates a new stream wrapping a function returning `Poll>`. /// /// Polling the returned stream calls the wrapped function. /// /// # Examples /// /// ``` /// use futures::stream::poll_fn; /// use futures::task::Poll; /// /// let mut counter = 1usize; /// /// let read_stream = poll_fn(move |_| -> Poll> { /// if counter == 0 { return Poll::Ready(None); } /// counter -= 1; /// Poll::Ready(Some("Hello, World!".to_owned())) /// }); /// ``` pub fn poll_fn(f: F) -> PollFn where F: FnMut(&mut Context<'_>) -> Poll>, { assert_stream::(PollFn { f }) } impl Stream for PollFn where F: FnMut(&mut Context<'_>) -> Poll>, { type Item = T; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { (&mut self.f)(cx) } } futures-util-0.3.30/src/stream/poll_immediate.rs000064400000000000000000000047621046102023000200040ustar 00000000000000use core::pin::Pin; use futures_core::task::{Context, Poll}; use futures_core::Stream; use pin_project_lite::pin_project; pin_project! { /// Stream for the [poll_immediate](poll_immediate()) function. /// /// It will never return [Poll::Pending](core::task::Poll::Pending) #[derive(Debug, Clone)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct PollImmediate { #[pin] stream: Option } } impl Stream for PollImmediate where S: Stream, { type Item = Poll; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); let stream = match this.stream.as_mut().as_pin_mut() { // inner is gone, so we can continue to signal that the stream is closed. None => return Poll::Ready(None), Some(inner) => inner, }; match stream.poll_next(cx) { Poll::Ready(Some(t)) => Poll::Ready(Some(Poll::Ready(t))), Poll::Ready(None) => { this.stream.set(None); Poll::Ready(None) } Poll::Pending => Poll::Ready(Some(Poll::Pending)), } } fn size_hint(&self) -> (usize, Option) { self.stream.as_ref().map_or((0, Some(0)), Stream::size_hint) } } impl super::FusedStream for PollImmediate { fn is_terminated(&self) -> bool { self.stream.is_none() } } /// Creates a new stream that always immediately returns [Poll::Ready](core::task::Poll::Ready) when awaiting it. /// /// This is useful when immediacy is more important than waiting for the next item to be ready. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// use futures::task::Poll; /// /// let mut r = stream::poll_immediate(Box::pin(stream::iter(1_u32..3))); /// assert_eq!(r.next().await, Some(Poll::Ready(1))); /// assert_eq!(r.next().await, Some(Poll::Ready(2))); /// assert_eq!(r.next().await, None); /// /// let mut p = stream::poll_immediate(Box::pin(stream::once(async { /// futures::pending!(); /// 42_u8 /// }))); /// assert_eq!(p.next().await, Some(Poll::Pending)); /// assert_eq!(p.next().await, Some(Poll::Ready(42))); /// assert_eq!(p.next().await, None); /// # }); /// ``` pub fn poll_immediate(s: S) -> PollImmediate { super::assert_stream::, PollImmediate>(PollImmediate { stream: Some(s) }) } futures-util-0.3.30/src/stream/repeat.rs000064400000000000000000000025041046102023000162700ustar 00000000000000use super::assert_stream; use core::pin::Pin; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; /// Stream for the [`repeat`] function. #[derive(Debug, Clone)] #[must_use = "streams do nothing unless polled"] pub struct Repeat { item: T, } /// Create a stream which produces the same item repeatedly. /// /// The stream never terminates. Note that you likely want to avoid /// usage of `collect` or such on the returned stream as it will exhaust /// available memory as it tries to just fill up all RAM. /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::repeat(9); /// assert_eq!(vec![9, 9, 9], stream.take(3).collect::>().await); /// # }); /// ``` pub fn repeat(item: T) -> Repeat where T: Clone, { assert_stream::(Repeat { item }) } impl Unpin for Repeat {} impl Stream for Repeat where T: Clone, { type Item = T; fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { Poll::Ready(Some(self.item.clone())) } fn size_hint(&self) -> (usize, Option) { (usize::max_value(), None) } } impl FusedStream for Repeat where T: Clone, { fn is_terminated(&self) -> bool { false } } futures-util-0.3.30/src/stream/repeat_with.rs000064400000000000000000000054461046102023000173330ustar 00000000000000use super::assert_stream; use core::pin::Pin; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; /// An stream that repeats elements of type `A` endlessly by /// applying the provided closure `F: FnMut() -> A`. /// /// This `struct` is created by the [`repeat_with()`] function. /// See its documentation for more. #[derive(Debug, Clone)] #[must_use = "streams do nothing unless polled"] pub struct RepeatWith { repeater: F, } impl A> Unpin for RepeatWith {} impl A> Stream for RepeatWith { type Item = A; fn poll_next(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { Poll::Ready(Some((&mut self.repeater)())) } fn size_hint(&self) -> (usize, Option) { (usize::max_value(), None) } } impl A> FusedStream for RepeatWith { fn is_terminated(&self) -> bool { false } } /// Creates a new stream that repeats elements of type `A` endlessly by /// applying the provided closure, the repeater, `F: FnMut() -> A`. /// /// The `repeat_with()` function calls the repeater over and over again. /// /// Infinite stream like `repeat_with()` are often used with adapters like /// [`stream.take()`], in order to make them finite. /// /// If the element type of the stream you need implements [`Clone`], and /// it is OK to keep the source element in memory, you should instead use /// the [`stream.repeat()`] function. /// /// # Examples /// /// Basic usage: /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// // let's assume we have some value of a type that is not `Clone` /// // or which don't want to have in memory just yet because it is expensive: /// #[derive(PartialEq, Debug)] /// struct Expensive; /// /// // a particular value forever: /// let mut things = stream::repeat_with(|| Expensive); /// /// assert_eq!(Some(Expensive), things.next().await); /// assert_eq!(Some(Expensive), things.next().await); /// assert_eq!(Some(Expensive), things.next().await); /// # }); /// ``` /// /// Using mutation and going finite: /// /// ```rust /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// // From the zeroth to the third power of two: /// let mut curr = 1; /// let mut pow2 = stream::repeat_with(|| { let tmp = curr; curr *= 2; tmp }) /// .take(4); /// /// assert_eq!(Some(1), pow2.next().await); /// assert_eq!(Some(2), pow2.next().await); /// assert_eq!(Some(4), pow2.next().await); /// assert_eq!(Some(8), pow2.next().await); /// /// // ... and now we're done /// assert_eq!(None, pow2.next().await); /// # }); /// ``` pub fn repeat_with A>(repeater: F) -> RepeatWith { assert_stream::(RepeatWith { repeater }) } futures-util-0.3.30/src/stream/select.rs000064400000000000000000000067211046102023000162740ustar 00000000000000use super::assert_stream; use crate::stream::{select_with_strategy, PollNext, SelectWithStrategy}; use core::pin::Pin; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`select()`] function. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct Select { #[pin] inner: SelectWithStrategy PollNext, PollNext>, } } /// This function will attempt to pull items from both streams. Each /// stream will be polled in a round-robin fashion, and whenever a stream is /// ready to yield an item that item is yielded. /// /// After one of the two input streams completes, the remaining one will be /// polled exclusively. The returned stream completes when both input /// streams have completed. /// /// Note that this function consumes both streams and returns a wrapped /// version of them. /// /// ## Examples /// /// ```rust /// # futures::executor::block_on(async { /// use futures::stream::{ repeat, select, StreamExt }; /// /// let left = repeat(1); /// let right = repeat(2); /// /// let mut out = select(left, right); /// /// for _ in 0..100 { /// // We should be alternating. /// assert_eq!(1, out.select_next_some().await); /// assert_eq!(2, out.select_next_some().await); /// } /// # }); /// ``` pub fn select(stream1: St1, stream2: St2) -> Select where St1: Stream, St2: Stream, { fn round_robin(last: &mut PollNext) -> PollNext { last.toggle() } assert_stream::(Select { inner: select_with_strategy(stream1, stream2, round_robin), }) } impl Select { /// Acquires a reference to the underlying streams that this combinator is /// pulling from. pub fn get_ref(&self) -> (&St1, &St2) { self.inner.get_ref() } /// Acquires a mutable reference to the underlying streams that this /// combinator is pulling from. /// /// Note that care must be taken to avoid tampering with the state of the /// stream which may otherwise confuse this combinator. pub fn get_mut(&mut self) -> (&mut St1, &mut St2) { self.inner.get_mut() } /// Acquires a pinned mutable reference to the underlying streams that this /// combinator is pulling from. /// /// Note that care must be taken to avoid tampering with the state of the /// stream which may otherwise confuse this combinator. pub fn get_pin_mut(self: Pin<&mut Self>) -> (Pin<&mut St1>, Pin<&mut St2>) { let this = self.project(); this.inner.get_pin_mut() } /// Consumes this combinator, returning the underlying streams. /// /// Note that this may discard intermediate state of this combinator, so /// care should be taken to avoid losing resources when this is called. pub fn into_inner(self) -> (St1, St2) { self.inner.into_inner() } } impl FusedStream for Select where St1: Stream, St2: Stream, { fn is_terminated(&self) -> bool { self.inner.is_terminated() } } impl Stream for Select where St1: Stream, St2: Stream, { type Item = St1::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); this.inner.poll_next(cx) } } futures-util-0.3.30/src/stream/select_all.rs000064400000000000000000000165241046102023000171260ustar 00000000000000//! An unbounded set of streams use core::fmt::{self, Debug}; use core::iter::FromIterator; use core::pin::Pin; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use super::assert_stream; use crate::stream::{futures_unordered, FuturesUnordered, StreamExt, StreamFuture}; /// An unbounded set of streams /// /// This "combinator" provides the ability to maintain a set of streams /// and drive them all to completion. /// /// Streams are pushed into this set and their realized values are /// yielded as they become ready. Streams will only be polled when they /// generate notifications. This allows to coordinate a large number of streams. /// /// Note that you can create a ready-made `SelectAll` via the /// `select_all` function in the `stream` module, or you can start with an /// empty set with the `SelectAll::new` constructor. #[must_use = "streams do nothing unless polled"] pub struct SelectAll { inner: FuturesUnordered>, } impl Debug for SelectAll { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "SelectAll {{ ... }}") } } impl SelectAll { /// Constructs a new, empty `SelectAll` /// /// The returned `SelectAll` does not contain any streams and, in this /// state, `SelectAll::poll` will return `Poll::Ready(None)`. pub fn new() -> Self { Self { inner: FuturesUnordered::new() } } /// Returns the number of streams contained in the set. /// /// This represents the total number of in-flight streams. pub fn len(&self) -> usize { self.inner.len() } /// Returns `true` if the set contains no streams pub fn is_empty(&self) -> bool { self.inner.is_empty() } /// Push a stream into the set. /// /// This function submits the given stream to the set for managing. This /// function will not call `poll` on the submitted stream. The caller must /// ensure that `SelectAll::poll` is called in order to receive task /// notifications. pub fn push(&mut self, stream: St) { self.inner.push(stream.into_future()); } /// Returns an iterator that allows inspecting each stream in the set. pub fn iter(&self) -> Iter<'_, St> { Iter(self.inner.iter()) } /// Returns an iterator that allows modifying each stream in the set. pub fn iter_mut(&mut self) -> IterMut<'_, St> { IterMut(self.inner.iter_mut()) } /// Clears the set, removing all streams. pub fn clear(&mut self) { self.inner.clear() } } impl Default for SelectAll { fn default() -> Self { Self::new() } } impl Stream for SelectAll { type Item = St::Item; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { loop { match ready!(self.inner.poll_next_unpin(cx)) { Some((Some(item), remaining)) => { self.push(remaining); return Poll::Ready(Some(item)); } Some((None, _)) => { // `FuturesUnordered` thinks it isn't terminated // because it yielded a Some. // We do not return, but poll `FuturesUnordered` // in the next loop iteration. } None => return Poll::Ready(None), } } } } impl FusedStream for SelectAll { fn is_terminated(&self) -> bool { self.inner.is_terminated() } } /// Convert a list of streams into a `Stream` of results from the streams. /// /// This essentially takes a list of streams (e.g. a vector, an iterator, etc.) /// and bundles them together into a single stream. /// The stream will yield items as they become available on the underlying /// streams internally, in the order they become available. /// /// Note that the returned set can also be used to dynamically push more /// streams into the set as they become available. /// /// This function is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. pub fn select_all(streams: I) -> SelectAll where I: IntoIterator, I::Item: Stream + Unpin, { let mut set = SelectAll::new(); for stream in streams { set.push(stream); } assert_stream::<::Item, _>(set) } impl FromIterator for SelectAll { fn from_iter>(iter: T) -> Self { select_all(iter) } } impl Extend for SelectAll { fn extend>(&mut self, iter: T) { for st in iter { self.push(st) } } } impl IntoIterator for SelectAll { type Item = St; type IntoIter = IntoIter; fn into_iter(self) -> Self::IntoIter { IntoIter(self.inner.into_iter()) } } impl<'a, St: Stream + Unpin> IntoIterator for &'a SelectAll { type Item = &'a St; type IntoIter = Iter<'a, St>; fn into_iter(self) -> Self::IntoIter { self.iter() } } impl<'a, St: Stream + Unpin> IntoIterator for &'a mut SelectAll { type Item = &'a mut St; type IntoIter = IterMut<'a, St>; fn into_iter(self) -> Self::IntoIter { self.iter_mut() } } /// Immutable iterator over all streams in the unordered set. #[derive(Debug)] pub struct Iter<'a, St: Unpin>(futures_unordered::Iter<'a, StreamFuture>); /// Mutable iterator over all streams in the unordered set. #[derive(Debug)] pub struct IterMut<'a, St: Unpin>(futures_unordered::IterMut<'a, StreamFuture>); /// Owned iterator over all streams in the unordered set. #[derive(Debug)] pub struct IntoIter(futures_unordered::IntoIter>); impl<'a, St: Stream + Unpin> Iterator for Iter<'a, St> { type Item = &'a St; fn next(&mut self) -> Option { let st = self.0.next()?; let next = st.get_ref(); // This should always be true because FuturesUnordered removes completed futures. debug_assert!(next.is_some()); next } fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } } impl ExactSizeIterator for Iter<'_, St> {} impl<'a, St: Stream + Unpin> Iterator for IterMut<'a, St> { type Item = &'a mut St; fn next(&mut self) -> Option { let st = self.0.next()?; let next = st.get_mut(); // This should always be true because FuturesUnordered removes completed futures. debug_assert!(next.is_some()); next } fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } } impl ExactSizeIterator for IterMut<'_, St> {} impl Iterator for IntoIter { type Item = St; fn next(&mut self) -> Option { let st = self.0.next()?; let next = st.into_inner(); // This should always be true because FuturesUnordered removes completed futures. debug_assert!(next.is_some()); next } fn size_hint(&self) -> (usize, Option) { self.0.size_hint() } } impl ExactSizeIterator for IntoIter {} futures-util-0.3.30/src/stream/select_with_strategy.rs000064400000000000000000000216031046102023000212450ustar 00000000000000use super::assert_stream; use core::{fmt, pin::Pin}; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; /// Type to tell [`SelectWithStrategy`] which stream to poll next. #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] pub enum PollNext { /// Poll the first stream. Left, /// Poll the second stream. Right, } impl PollNext { /// Toggle the value and return the old one. pub fn toggle(&mut self) -> Self { let old = *self; *self = self.other(); old } fn other(&self) -> PollNext { match self { PollNext::Left => PollNext::Right, PollNext::Right => PollNext::Left, } } } impl Default for PollNext { fn default() -> Self { PollNext::Left } } enum InternalState { Start, LeftFinished, RightFinished, BothFinished, } impl InternalState { fn finish(&mut self, ps: PollNext) { match (&self, ps) { (InternalState::Start, PollNext::Left) => { *self = InternalState::LeftFinished; } (InternalState::Start, PollNext::Right) => { *self = InternalState::RightFinished; } (InternalState::LeftFinished, PollNext::Right) | (InternalState::RightFinished, PollNext::Left) => { *self = InternalState::BothFinished; } _ => {} } } } pin_project! { /// Stream for the [`select_with_strategy()`] function. See function docs for details. #[must_use = "streams do nothing unless polled"] #[project = SelectWithStrategyProj] pub struct SelectWithStrategy { #[pin] stream1: St1, #[pin] stream2: St2, internal_state: InternalState, state: State, clos: Clos, } } /// This function will attempt to pull items from both streams. You provide a /// closure to tell [`SelectWithStrategy`] which stream to poll. The closure can /// store state on `SelectWithStrategy` to which it will receive a `&mut` on every /// invocation. This allows basing the strategy on prior choices. /// /// After one of the two input streams completes, the remaining one will be /// polled exclusively. The returned stream completes when both input /// streams have completed. /// /// Note that this function consumes both streams and returns a wrapped /// version of them. /// /// ## Examples /// /// ### Priority /// This example shows how to always prioritize the left stream. /// /// ```rust /// # futures::executor::block_on(async { /// use futures::stream::{ repeat, select_with_strategy, PollNext, StreamExt }; /// /// let left = repeat(1); /// let right = repeat(2); /// /// // We don't need any state, so let's make it an empty tuple. /// // We must provide some type here, as there is no way for the compiler /// // to infer it. As we don't need to capture variables, we can just /// // use a function pointer instead of a closure. /// fn prio_left(_: &mut ()) -> PollNext { PollNext::Left } /// /// let mut out = select_with_strategy(left, right, prio_left); /// /// for _ in 0..100 { /// // Whenever we poll out, we will alwas get `1`. /// assert_eq!(1, out.select_next_some().await); /// } /// # }); /// ``` /// /// ### Round Robin /// This example shows how to select from both streams round robin. /// Note: this special case is provided by [`futures-util::stream::select`]. /// /// ```rust /// # futures::executor::block_on(async { /// use futures::stream::{ repeat, select_with_strategy, PollNext, StreamExt }; /// /// let left = repeat(1); /// let right = repeat(2); /// /// let rrobin = |last: &mut PollNext| last.toggle(); /// /// let mut out = select_with_strategy(left, right, rrobin); /// /// for _ in 0..100 { /// // We should be alternating now. /// assert_eq!(1, out.select_next_some().await); /// assert_eq!(2, out.select_next_some().await); /// } /// # }); /// ``` pub fn select_with_strategy( stream1: St1, stream2: St2, which: Clos, ) -> SelectWithStrategy where St1: Stream, St2: Stream, Clos: FnMut(&mut State) -> PollNext, State: Default, { assert_stream::(SelectWithStrategy { stream1, stream2, state: Default::default(), internal_state: InternalState::Start, clos: which, }) } impl SelectWithStrategy { /// Acquires a reference to the underlying streams that this combinator is /// pulling from. pub fn get_ref(&self) -> (&St1, &St2) { (&self.stream1, &self.stream2) } /// Acquires a mutable reference to the underlying streams that this /// combinator is pulling from. /// /// Note that care must be taken to avoid tampering with the state of the /// stream which may otherwise confuse this combinator. pub fn get_mut(&mut self) -> (&mut St1, &mut St2) { (&mut self.stream1, &mut self.stream2) } /// Acquires a pinned mutable reference to the underlying streams that this /// combinator is pulling from. /// /// Note that care must be taken to avoid tampering with the state of the /// stream which may otherwise confuse this combinator. pub fn get_pin_mut(self: Pin<&mut Self>) -> (Pin<&mut St1>, Pin<&mut St2>) { let this = self.project(); (this.stream1, this.stream2) } /// Consumes this combinator, returning the underlying streams. /// /// Note that this may discard intermediate state of this combinator, so /// care should be taken to avoid losing resources when this is called. pub fn into_inner(self) -> (St1, St2) { (self.stream1, self.stream2) } } impl FusedStream for SelectWithStrategy where St1: Stream, St2: Stream, Clos: FnMut(&mut State) -> PollNext, { fn is_terminated(&self) -> bool { match self.internal_state { InternalState::BothFinished => true, _ => false, } } } #[inline] fn poll_side( select: &mut SelectWithStrategyProj<'_, St1, St2, Clos, State>, side: PollNext, cx: &mut Context<'_>, ) -> Poll> where St1: Stream, St2: Stream, { match side { PollNext::Left => select.stream1.as_mut().poll_next(cx), PollNext::Right => select.stream2.as_mut().poll_next(cx), } } #[inline] fn poll_inner( select: &mut SelectWithStrategyProj<'_, St1, St2, Clos, State>, side: PollNext, cx: &mut Context<'_>, ) -> Poll> where St1: Stream, St2: Stream, { let first_done = match poll_side(select, side, cx) { Poll::Ready(Some(item)) => return Poll::Ready(Some(item)), Poll::Ready(None) => { select.internal_state.finish(side); true } Poll::Pending => false, }; let other = side.other(); match poll_side(select, other, cx) { Poll::Ready(None) => { select.internal_state.finish(other); if first_done { Poll::Ready(None) } else { Poll::Pending } } a => a, } } impl Stream for SelectWithStrategy where St1: Stream, St2: Stream, Clos: FnMut(&mut State) -> PollNext, { type Item = St1::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); match this.internal_state { InternalState::Start => { let next_side = (this.clos)(this.state); poll_inner(&mut this, next_side, cx) } InternalState::LeftFinished => match this.stream2.poll_next(cx) { Poll::Ready(None) => { *this.internal_state = InternalState::BothFinished; Poll::Ready(None) } a => a, }, InternalState::RightFinished => match this.stream1.poll_next(cx) { Poll::Ready(None) => { *this.internal_state = InternalState::BothFinished; Poll::Ready(None) } a => a, }, InternalState::BothFinished => Poll::Ready(None), } } } impl fmt::Debug for SelectWithStrategy where St1: fmt::Debug, St2: fmt::Debug, State: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("SelectWithStrategy") .field("stream1", &self.stream1) .field("stream2", &self.stream2) .field("state", &self.state) .finish() } } futures-util-0.3.30/src/stream/stream/all.rs000064400000000000000000000047411046102023000170600ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; use futures_core::stream::Stream; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`all`](super::StreamExt::all) method. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct All { #[pin] stream: St, f: F, done: bool, #[pin] future: Option, } } impl fmt::Debug for All where St: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("All") .field("stream", &self.stream) .field("done", &self.done) .field("future", &self.future) .finish() } } impl All where St: Stream, F: FnMut(St::Item) -> Fut, Fut: Future, { pub(super) fn new(stream: St, f: F) -> Self { Self { stream, f, done: false, future: None } } } impl FusedFuture for All where St: Stream, F: FnMut(St::Item) -> Fut, Fut: Future, { fn is_terminated(&self) -> bool { self.done && self.future.is_none() } } impl Future for All where St: Stream, F: FnMut(St::Item) -> Fut, Fut: Future, { type Output = bool; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.project(); Poll::Ready(loop { if let Some(fut) = this.future.as_mut().as_pin_mut() { // we're currently processing a future to produce a new value let res = ready!(fut.poll(cx)); this.future.set(None); if !res { *this.done = true; break false; } // early exit } else if !*this.done { // we're waiting on a new item from the stream match ready!(this.stream.as_mut().poll_next(cx)) { Some(item) => { this.future.set(Some((this.f)(item))); } None => { *this.done = true; break true; } } } else { panic!("All polled after completion") } }) } } futures-util-0.3.30/src/stream/stream/any.rs000064400000000000000000000047401046102023000170760ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; use futures_core::stream::Stream; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`any`](super::StreamExt::any) method. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Any { #[pin] stream: St, f: F, done: bool, #[pin] future: Option, } } impl fmt::Debug for Any where St: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Any") .field("stream", &self.stream) .field("done", &self.done) .field("future", &self.future) .finish() } } impl Any where St: Stream, F: FnMut(St::Item) -> Fut, Fut: Future, { pub(super) fn new(stream: St, f: F) -> Self { Self { stream, f, done: false, future: None } } } impl FusedFuture for Any where St: Stream, F: FnMut(St::Item) -> Fut, Fut: Future, { fn is_terminated(&self) -> bool { self.done && self.future.is_none() } } impl Future for Any where St: Stream, F: FnMut(St::Item) -> Fut, Fut: Future, { type Output = bool; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.project(); Poll::Ready(loop { if let Some(fut) = this.future.as_mut().as_pin_mut() { // we're currently processing a future to produce a new value let res = ready!(fut.poll(cx)); this.future.set(None); if res { *this.done = true; break true; } // early exit } else if !*this.done { // we're waiting on a new item from the stream match ready!(this.stream.as_mut().poll_next(cx)) { Some(item) => { this.future.set(Some((this.f)(item))); } None => { *this.done = true; break false; } } } else { panic!("Any polled after completion") } }) } } futures-util-0.3.30/src/stream/stream/buffer_unordered.rs000064400000000000000000000063211046102023000216240ustar 00000000000000use crate::stream::{Fuse, FuturesUnordered, StreamExt}; use core::fmt; use core::pin::Pin; use futures_core::future::Future; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`buffer_unordered`](super::StreamExt::buffer_unordered) /// method. #[must_use = "streams do nothing unless polled"] pub struct BufferUnordered where St: Stream, { #[pin] stream: Fuse, in_progress_queue: FuturesUnordered, max: usize, } } impl fmt::Debug for BufferUnordered where St: Stream + fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("BufferUnordered") .field("stream", &self.stream) .field("in_progress_queue", &self.in_progress_queue) .field("max", &self.max) .finish() } } impl BufferUnordered where St: Stream, St::Item: Future, { pub(super) fn new(stream: St, n: usize) -> Self { Self { stream: super::Fuse::new(stream), in_progress_queue: FuturesUnordered::new(), max: n, } } delegate_access_inner!(stream, St, (.)); } impl Stream for BufferUnordered where St: Stream, St::Item: Future, { type Item = ::Output; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); // First up, try to spawn off as many futures as possible by filling up // our queue of futures. while this.in_progress_queue.len() < *this.max { match this.stream.as_mut().poll_next(cx) { Poll::Ready(Some(fut)) => this.in_progress_queue.push(fut), Poll::Ready(None) | Poll::Pending => break, } } // Attempt to pull the next value from the in_progress_queue match this.in_progress_queue.poll_next_unpin(cx) { x @ Poll::Pending | x @ Poll::Ready(Some(_)) => return x, Poll::Ready(None) => {} } // If more values are still coming from the stream, we're not done yet if this.stream.is_done() { Poll::Ready(None) } else { Poll::Pending } } fn size_hint(&self) -> (usize, Option) { let queue_len = self.in_progress_queue.len(); let (lower, upper) = self.stream.size_hint(); let lower = lower.saturating_add(queue_len); let upper = match upper { Some(x) => x.checked_add(queue_len), None => None, }; (lower, upper) } } impl FusedStream for BufferUnordered where St: Stream, St::Item: Future, { fn is_terminated(&self) -> bool { self.in_progress_queue.is_terminated() && self.stream.is_terminated() } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for BufferUnordered where S: Stream + Sink, S::Item: Future, { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/stream/buffered.rs000064400000000000000000000062101046102023000200630ustar 00000000000000use crate::stream::{Fuse, FusedStream, FuturesOrdered, StreamExt}; use core::fmt; use core::pin::Pin; use futures_core::future::Future; use futures_core::ready; use futures_core::stream::Stream; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`buffered`](super::StreamExt::buffered) method. #[must_use = "streams do nothing unless polled"] pub struct Buffered where St: Stream, St::Item: Future, { #[pin] stream: Fuse, in_progress_queue: FuturesOrdered, max: usize, } } impl fmt::Debug for Buffered where St: Stream + fmt::Debug, St::Item: Future, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Buffered") .field("stream", &self.stream) .field("in_progress_queue", &self.in_progress_queue) .field("max", &self.max) .finish() } } impl Buffered where St: Stream, St::Item: Future, { pub(super) fn new(stream: St, n: usize) -> Self { Self { stream: super::Fuse::new(stream), in_progress_queue: FuturesOrdered::new(), max: n } } delegate_access_inner!(stream, St, (.)); } impl Stream for Buffered where St: Stream, St::Item: Future, { type Item = ::Output; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); // First up, try to spawn off as many futures as possible by filling up // our queue of futures. while this.in_progress_queue.len() < *this.max { match this.stream.as_mut().poll_next(cx) { Poll::Ready(Some(fut)) => this.in_progress_queue.push_back(fut), Poll::Ready(None) | Poll::Pending => break, } } // Attempt to pull the next value from the in_progress_queue let res = this.in_progress_queue.poll_next_unpin(cx); if let Some(val) = ready!(res) { return Poll::Ready(Some(val)); } // If more values are still coming from the stream, we're not done yet if this.stream.is_done() { Poll::Ready(None) } else { Poll::Pending } } fn size_hint(&self) -> (usize, Option) { let queue_len = self.in_progress_queue.len(); let (lower, upper) = self.stream.size_hint(); let lower = lower.saturating_add(queue_len); let upper = match upper { Some(x) => x.checked_add(queue_len), None => None, }; (lower, upper) } } impl FusedStream for Buffered where St: Stream, St::Item: Future, { fn is_terminated(&self) -> bool { self.stream.is_done() && self.in_progress_queue.is_terminated() } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for Buffered where S: Stream + Sink, S::Item: Future, { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/stream/catch_unwind.rs000064400000000000000000000032671046102023000207600ustar 00000000000000use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; use std::any::Any; use std::panic::{catch_unwind, AssertUnwindSafe, UnwindSafe}; use std::pin::Pin; pin_project! { /// Stream for the [`catch_unwind`](super::StreamExt::catch_unwind) method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct CatchUnwind { #[pin] stream: St, caught_unwind: bool, } } impl CatchUnwind { pub(super) fn new(stream: St) -> Self { Self { stream, caught_unwind: false } } delegate_access_inner!(stream, St, ()); } impl Stream for CatchUnwind { type Item = Result>; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); if *this.caught_unwind { Poll::Ready(None) } else { let res = catch_unwind(AssertUnwindSafe(|| this.stream.as_mut().poll_next(cx))); match res { Ok(poll) => poll.map(|opt| opt.map(Ok)), Err(e) => { *this.caught_unwind = true; Poll::Ready(Some(Err(e))) } } } } fn size_hint(&self) -> (usize, Option) { if self.caught_unwind { (0, Some(0)) } else { self.stream.size_hint() } } } impl FusedStream for CatchUnwind { fn is_terminated(&self) -> bool { self.caught_unwind || self.stream.is_terminated() } } futures-util-0.3.30/src/stream/stream/chain.rs000064400000000000000000000037771046102023000174020ustar 00000000000000use core::pin::Pin; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`chain`](super::StreamExt::chain) method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct Chain { #[pin] first: Option, #[pin] second: St2, } } // All interactions with `Pin<&mut Chain<..>>` happen through these methods impl Chain where St1: Stream, St2: Stream, { pub(super) fn new(stream1: St1, stream2: St2) -> Self { Self { first: Some(stream1), second: stream2 } } } impl FusedStream for Chain where St1: Stream, St2: FusedStream, { fn is_terminated(&self) -> bool { self.first.is_none() && self.second.is_terminated() } } impl Stream for Chain where St1: Stream, St2: Stream, { type Item = St1::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); if let Some(first) = this.first.as_mut().as_pin_mut() { if let Some(item) = ready!(first.poll_next(cx)) { return Poll::Ready(Some(item)); } this.first.set(None); } this.second.poll_next(cx) } fn size_hint(&self) -> (usize, Option) { if let Some(first) = &self.first { let (first_lower, first_upper) = first.size_hint(); let (second_lower, second_upper) = self.second.size_hint(); let lower = first_lower.saturating_add(second_lower); let upper = match (first_upper, second_upper) { (Some(x), Some(y)) => x.checked_add(y), _ => None, }; (lower, upper) } else { self.second.size_hint() } } } futures-util-0.3.30/src/stream/stream/chunks.rs000064400000000000000000000060231046102023000175760ustar 00000000000000use crate::stream::Fuse; use alloc::vec::Vec; use core::mem; use core::pin::Pin; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`chunks`](super::StreamExt::chunks) method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct Chunks { #[pin] stream: Fuse, items: Vec, cap: usize, // https://github.com/rust-lang/futures-rs/issues/1475 } } impl Chunks { pub(super) fn new(stream: St, capacity: usize) -> Self { assert!(capacity > 0); Self { stream: super::Fuse::new(stream), items: Vec::with_capacity(capacity), cap: capacity, } } fn take(self: Pin<&mut Self>) -> Vec { let cap = self.cap; mem::replace(self.project().items, Vec::with_capacity(cap)) } delegate_access_inner!(stream, St, (.)); } impl Stream for Chunks { type Item = Vec; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.as_mut().project(); loop { match ready!(this.stream.as_mut().poll_next(cx)) { // Push the item into the buffer and check whether it is full. // If so, replace our buffer with a new and empty one and return // the full one. Some(item) => { this.items.push(item); if this.items.len() >= *this.cap { return Poll::Ready(Some(self.take())); } } // Since the underlying stream ran out of values, return what we // have buffered, if we have anything. None => { let last = if this.items.is_empty() { None } else { let full_buf = mem::take(this.items); Some(full_buf) }; return Poll::Ready(last); } } } } fn size_hint(&self) -> (usize, Option) { let chunk_len = usize::from(!self.items.is_empty()); let (lower, upper) = self.stream.size_hint(); let lower = (lower / self.cap).saturating_add(chunk_len); let upper = match upper { Some(x) => x.checked_add(chunk_len), None => None, }; (lower, upper) } } impl FusedStream for Chunks { fn is_terminated(&self) -> bool { self.stream.is_terminated() && self.items.is_empty() } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for Chunks where S: Stream + Sink, { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/stream/collect.rs000064400000000000000000000026151046102023000177330ustar 00000000000000use core::mem; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`collect`](super::StreamExt::collect) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Collect { #[pin] stream: St, collection: C, } } impl Collect { fn finish(self: Pin<&mut Self>) -> C { mem::take(self.project().collection) } pub(super) fn new(stream: St) -> Self { Self { stream, collection: Default::default() } } } impl FusedFuture for Collect where St: FusedStream, C: Default + Extend, { fn is_terminated(&self) -> bool { self.stream.is_terminated() } } impl Future for Collect where St: Stream, C: Default + Extend, { type Output = C; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.as_mut().project(); loop { match ready!(this.stream.as_mut().poll_next(cx)) { Some(e) => this.collection.extend(Some(e)), None => return Poll::Ready(self.finish()), } } } } futures-util-0.3.30/src/stream/stream/concat.rs000064400000000000000000000032251046102023000175530ustar 00000000000000use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`concat`](super::StreamExt::concat) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Concat { #[pin] stream: St, accum: Option, } } impl Concat where St: Stream, St::Item: Extend<::Item> + IntoIterator + Default, { pub(super) fn new(stream: St) -> Self { Self { stream, accum: None } } } impl Future for Concat where St: Stream, St::Item: Extend<::Item> + IntoIterator + Default, { type Output = St::Item; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.project(); loop { match ready!(this.stream.as_mut().poll_next(cx)) { None => return Poll::Ready(this.accum.take().unwrap_or_default()), Some(e) => { if let Some(a) = this.accum { a.extend(e) } else { *this.accum = Some(e) } } } } } } impl FusedFuture for Concat where St: FusedStream, St::Item: Extend<::Item> + IntoIterator + Default, { fn is_terminated(&self) -> bool { self.accum.is_none() && self.stream.is_terminated() } } futures-util-0.3.30/src/stream/stream/count.rs000064400000000000000000000025171046102023000174370ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`count`](super::StreamExt::count) method. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Count { #[pin] stream: St, count: usize } } impl fmt::Debug for Count where St: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Count").field("stream", &self.stream).field("count", &self.count).finish() } } impl Count { pub(super) fn new(stream: St) -> Self { Self { stream, count: 0 } } } impl FusedFuture for Count { fn is_terminated(&self) -> bool { self.stream.is_terminated() } } impl Future for Count { type Output = usize; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.project(); Poll::Ready(loop { match ready!(this.stream.as_mut().poll_next(cx)) { Some(_) => *this.count += 1, None => break *this.count, } }) } } futures-util-0.3.30/src/stream/stream/cycle.rs000064400000000000000000000031131046102023000173770ustar 00000000000000use core::pin::Pin; use core::usize; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`cycle`](super::StreamExt::cycle) method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct Cycle { orig: St, #[pin] stream: St, } } impl Cycle where St: Clone + Stream, { pub(super) fn new(stream: St) -> Self { Self { orig: stream.clone(), stream } } } impl Stream for Cycle where St: Clone + Stream, { type Item = St::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); match ready!(this.stream.as_mut().poll_next(cx)) { None => { this.stream.set(this.orig.clone()); this.stream.poll_next(cx) } item => Poll::Ready(item), } } fn size_hint(&self) -> (usize, Option) { // the cycle stream is either empty or infinite match self.orig.size_hint() { size @ (0, Some(0)) => size, (0, _) => (0, None), _ => (usize::max_value(), None), } } } impl FusedStream for Cycle where St: Clone + Stream, { fn is_terminated(&self) -> bool { // the cycle stream is either empty or infinite if let (0, Some(0)) = self.size_hint() { true } else { false } } } futures-util-0.3.30/src/stream/stream/enumerate.rs000064400000000000000000000030721046102023000202710ustar 00000000000000use core::pin::Pin; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`enumerate`](super::StreamExt::enumerate) method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct Enumerate { #[pin] stream: St, count: usize, } } impl Enumerate { pub(super) fn new(stream: St) -> Self { Self { stream, count: 0 } } delegate_access_inner!(stream, St, ()); } impl FusedStream for Enumerate { fn is_terminated(&self) -> bool { self.stream.is_terminated() } } impl Stream for Enumerate { type Item = (usize, St::Item); fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); match ready!(this.stream.poll_next(cx)) { Some(item) => { let prev_count = *this.count; *this.count += 1; Poll::Ready(Some((prev_count, item))) } None => Poll::Ready(None), } } fn size_hint(&self) -> (usize, Option) { self.stream.size_hint() } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for Enumerate where S: Stream + Sink, { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/stream/filter.rs000064400000000000000000000064701046102023000175760ustar 00000000000000use crate::fns::FnMut1; use core::fmt; use core::pin::Pin; use futures_core::future::Future; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`filter`](super::StreamExt::filter) method. #[must_use = "streams do nothing unless polled"] pub struct Filter where St: Stream, { #[pin] stream: St, f: F, #[pin] pending_fut: Option, pending_item: Option, } } impl fmt::Debug for Filter where St: Stream + fmt::Debug, St::Item: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Filter") .field("stream", &self.stream) .field("pending_fut", &self.pending_fut) .field("pending_item", &self.pending_item) .finish() } } #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 impl Filter where St: Stream, F: for<'a> FnMut1<&'a St::Item, Output = Fut>, Fut: Future, { pub(super) fn new(stream: St, f: F) -> Self { Self { stream, f, pending_fut: None, pending_item: None } } delegate_access_inner!(stream, St, ()); } impl FusedStream for Filter where St: Stream + FusedStream, F: FnMut(&St::Item) -> Fut, Fut: Future, { fn is_terminated(&self) -> bool { self.pending_fut.is_none() && self.stream.is_terminated() } } #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 impl Stream for Filter where St: Stream, F: for<'a> FnMut1<&'a St::Item, Output = Fut>, Fut: Future, { type Item = St::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); Poll::Ready(loop { if let Some(fut) = this.pending_fut.as_mut().as_pin_mut() { let res = ready!(fut.poll(cx)); this.pending_fut.set(None); if res { break this.pending_item.take(); } *this.pending_item = None; } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { this.pending_fut.set(Some(this.f.call_mut(&item))); *this.pending_item = Some(item); } else { break None; } }) } fn size_hint(&self) -> (usize, Option) { let pending_len = usize::from(self.pending_item.is_some()); let (_, upper) = self.stream.size_hint(); let upper = match upper { Some(x) => x.checked_add(pending_len), None => None, }; (0, upper) // can't know a lower bound, due to the predicate } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for Filter where S: Stream + Sink, F: FnMut(&S::Item) -> Fut, Fut: Future, { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/stream/filter_map.rs000064400000000000000000000057711046102023000204360ustar 00000000000000use crate::fns::FnMut1; use core::fmt; use core::pin::Pin; use futures_core::future::Future; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`filter_map`](super::StreamExt::filter_map) method. #[must_use = "streams do nothing unless polled"] pub struct FilterMap { #[pin] stream: St, f: F, #[pin] pending: Option, } } impl fmt::Debug for FilterMap where St: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("FilterMap") .field("stream", &self.stream) .field("pending", &self.pending) .finish() } } impl FilterMap where St: Stream, F: FnMut(St::Item) -> Fut, Fut: Future, { pub(super) fn new(stream: St, f: F) -> Self { Self { stream, f, pending: None } } delegate_access_inner!(stream, St, ()); } impl FusedStream for FilterMap where St: Stream + FusedStream, F: FnMut1, Fut: Future>, { fn is_terminated(&self) -> bool { self.pending.is_none() && self.stream.is_terminated() } } impl Stream for FilterMap where St: Stream, F: FnMut1, Fut: Future>, { type Item = T; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); Poll::Ready(loop { if let Some(p) = this.pending.as_mut().as_pin_mut() { // We have an item in progress, poll that until it's done let item = ready!(p.poll(cx)); this.pending.set(None); if item.is_some() { break item; } } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { // No item in progress, but the stream is still going this.pending.set(Some(this.f.call_mut(item))); } else { // The stream is done break None; } }) } fn size_hint(&self) -> (usize, Option) { let pending_len = usize::from(self.pending.is_some()); let (_, upper) = self.stream.size_hint(); let upper = match upper { Some(x) => x.checked_add(pending_len), None => None, }; (0, upper) // can't know a lower bound, due to the predicate } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for FilterMap where S: Stream + Sink, F: FnMut1, Fut: Future, { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/stream/flatten.rs000064400000000000000000000034471046102023000177470ustar 00000000000000use core::pin::Pin; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`flatten`](super::StreamExt::flatten) method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct Flatten { #[pin] stream: St, #[pin] next: Option, } } impl Flatten { pub(super) fn new(stream: St) -> Self { Self { stream, next: None } } delegate_access_inner!(stream, St, ()); } impl FusedStream for Flatten where St: FusedStream, St::Item: Stream, { fn is_terminated(&self) -> bool { self.next.is_none() && self.stream.is_terminated() } } impl Stream for Flatten where St: Stream, St::Item: Stream, { type Item = ::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); Poll::Ready(loop { if let Some(s) = this.next.as_mut().as_pin_mut() { if let Some(item) = ready!(s.poll_next(cx)) { break Some(item); } else { this.next.set(None); } } else if let Some(s) = ready!(this.stream.as_mut().poll_next(cx)) { this.next.set(Some(s)); } else { break None; } }) } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for Flatten where S: Stream + Sink, { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/stream/flatten_unordered.rs000064400000000000000000000443101046102023000220100ustar 00000000000000use alloc::sync::Arc; use core::{ cell::UnsafeCell, convert::identity, fmt, marker::PhantomData, num::NonZeroUsize, pin::Pin, sync::atomic::{AtomicU8, Ordering}, }; use pin_project_lite::pin_project; use futures_core::{ future::Future, ready, stream::{FusedStream, Stream}, task::{Context, Poll, Waker}, }; #[cfg(feature = "sink")] use futures_sink::Sink; use futures_task::{waker, ArcWake}; use crate::stream::FuturesUnordered; /// Stream for the [`flatten_unordered`](super::StreamExt::flatten_unordered) /// method. pub type FlattenUnordered = FlattenUnorderedWithFlowController; /// There is nothing to poll and stream isn't being polled/waking/woken at the moment. const NONE: u8 = 0; /// Inner streams need to be polled. const NEED_TO_POLL_INNER_STREAMS: u8 = 1; /// The base stream needs to be polled. const NEED_TO_POLL_STREAM: u8 = 0b10; /// Both base stream and inner streams need to be polled. const NEED_TO_POLL_ALL: u8 = NEED_TO_POLL_INNER_STREAMS | NEED_TO_POLL_STREAM; /// The current stream is being polled at the moment. const POLLING: u8 = 0b100; /// Stream is being woken at the moment. const WAKING: u8 = 0b1000; /// The stream was waked and will be polled. const WOKEN: u8 = 0b10000; /// Internal polling state of the stream. #[derive(Clone, Debug)] struct SharedPollState { state: Arc, } impl SharedPollState { /// Constructs new `SharedPollState` with the given state. fn new(value: u8) -> SharedPollState { SharedPollState { state: Arc::new(AtomicU8::new(value)) } } /// Attempts to start polling, returning stored state in case of success. /// Returns `None` if either waker is waking at the moment. fn start_polling( &self, ) -> Option<(u8, PollStateBomb<'_, impl FnOnce(&SharedPollState) -> u8>)> { let value = self .state .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |value| { if value & WAKING == NONE { Some(POLLING) } else { None } }) .ok()?; let bomb = PollStateBomb::new(self, SharedPollState::reset); Some((value, bomb)) } /// Attempts to start the waking process and performs bitwise or with the given value. /// /// If some waker is already in progress or stream is already woken/being polled, waking process won't start, however /// state will be disjuncted with the given value. fn start_waking( &self, to_poll: u8, ) -> Option<(u8, PollStateBomb<'_, impl FnOnce(&SharedPollState) -> u8>)> { let value = self .state .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |value| { let mut next_value = value | to_poll; if value & (WOKEN | POLLING) == NONE { next_value |= WAKING; } if next_value != value { Some(next_value) } else { None } }) .ok()?; // Only start the waking process if we're not in the polling/waking phase and the stream isn't woken already if value & (WOKEN | POLLING | WAKING) == NONE { let bomb = PollStateBomb::new(self, SharedPollState::stop_waking); Some((value, bomb)) } else { None } } /// Sets current state to /// - `!POLLING` allowing to use wakers /// - `WOKEN` if the state was changed during `POLLING` phase as waker will be called, /// or `will_be_woken` flag supplied /// - `!WAKING` as /// * Wakers called during the `POLLING` phase won't propagate their calls /// * `POLLING` phase can't start if some of the wakers are active /// So no wrapped waker can touch the inner waker's cell, it's safe to poll again. fn stop_polling(&self, to_poll: u8, will_be_woken: bool) -> u8 { self.state .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |mut value| { let mut next_value = to_poll; value &= NEED_TO_POLL_ALL; if value != NONE || will_be_woken { next_value |= WOKEN; } next_value |= value; Some(next_value & !POLLING & !WAKING) }) .unwrap() } /// Toggles state to non-waking, allowing to start polling. fn stop_waking(&self) -> u8 { let value = self .state .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |value| { let next_value = value & !WAKING | WOKEN; if next_value != value { Some(next_value) } else { None } }) .unwrap_or_else(identity); debug_assert!(value & (WOKEN | POLLING | WAKING) == WAKING); value } /// Resets current state allowing to poll the stream and wake up wakers. fn reset(&self) -> u8 { self.state.swap(NEED_TO_POLL_ALL, Ordering::SeqCst) } } /// Used to execute some function on the given state when dropped. struct PollStateBomb<'a, F: FnOnce(&SharedPollState) -> u8> { state: &'a SharedPollState, drop: Option, } impl<'a, F: FnOnce(&SharedPollState) -> u8> PollStateBomb<'a, F> { /// Constructs new bomb with the given state. fn new(state: &'a SharedPollState, drop: F) -> Self { Self { state, drop: Some(drop) } } /// Deactivates bomb, forces it to not call provided function when dropped. fn deactivate(mut self) { self.drop.take(); } } impl u8> Drop for PollStateBomb<'_, F> { fn drop(&mut self) { if let Some(drop) = self.drop.take() { (drop)(self.state); } } } /// Will update state with the provided value on `wake_by_ref` call /// and then, if there is a need, call `inner_waker`. struct WrappedWaker { inner_waker: UnsafeCell>, poll_state: SharedPollState, need_to_poll: u8, } unsafe impl Send for WrappedWaker {} unsafe impl Sync for WrappedWaker {} impl WrappedWaker { /// Replaces given waker's inner_waker for polling stream/futures which will /// update poll state on `wake_by_ref` call. Use only if you need several /// contexts. /// /// ## Safety /// /// This function will modify waker's `inner_waker` via `UnsafeCell`, so /// it should be used only during `POLLING` phase by one thread at the time. unsafe fn replace_waker(self_arc: &mut Arc, cx: &Context<'_>) { *self_arc.inner_waker.get() = cx.waker().clone().into(); } /// Attempts to start the waking process for the waker with the given value. /// If succeeded, then the stream isn't yet woken and not being polled at the moment. fn start_waking(&self) -> Option<(u8, PollStateBomb<'_, impl FnOnce(&SharedPollState) -> u8>)> { self.poll_state.start_waking(self.need_to_poll) } } impl ArcWake for WrappedWaker { fn wake_by_ref(self_arc: &Arc) { if let Some((_, state_bomb)) = self_arc.start_waking() { // Safety: now state is not `POLLING` let waker_opt = unsafe { self_arc.inner_waker.get().as_ref().unwrap() }; if let Some(inner_waker) = waker_opt.clone() { // Stop waking to allow polling stream drop(state_bomb); // Wake up inner waker inner_waker.wake(); } } } } pin_project! { /// Future which polls optional inner stream. /// /// If it's `Some`, it will attempt to call `poll_next` on it, /// returning `Some((item, next_item_fut))` in case of `Poll::Ready(Some(...))` /// or `None` in case of `Poll::Ready(None)`. /// /// If `poll_next` will return `Poll::Pending`, it will be forwarded to /// the future and current task will be notified by waker. #[must_use = "futures do nothing unless you `.await` or poll them"] struct PollStreamFut { #[pin] stream: Option, } } impl PollStreamFut { /// Constructs new `PollStreamFut` using given `stream`. fn new(stream: impl Into>) -> Self { Self { stream: stream.into() } } } impl Future for PollStreamFut { type Output = Option<(St::Item, PollStreamFut)>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut stream = self.project().stream; let item = if let Some(stream) = stream.as_mut().as_pin_mut() { ready!(stream.poll_next(cx)) } else { None }; let next_item_fut = PollStreamFut::new(stream.get_mut().take()); let out = item.map(|item| (item, next_item_fut)); Poll::Ready(out) } } pin_project! { /// Stream for the [`flatten_unordered`](super::StreamExt::flatten_unordered) /// method with ability to specify flow controller. #[project = FlattenUnorderedWithFlowControllerProj] #[must_use = "streams do nothing unless polled"] pub struct FlattenUnorderedWithFlowController where St: Stream { #[pin] inner_streams: FuturesUnordered>, #[pin] stream: St, poll_state: SharedPollState, limit: Option, is_stream_done: bool, inner_streams_waker: Arc, stream_waker: Arc, flow_controller: PhantomData } } impl fmt::Debug for FlattenUnorderedWithFlowController where St: Stream + fmt::Debug, St::Item: Stream + fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("FlattenUnorderedWithFlowController") .field("poll_state", &self.poll_state) .field("inner_streams", &self.inner_streams) .field("limit", &self.limit) .field("stream", &self.stream) .field("is_stream_done", &self.is_stream_done) .field("flow_controller", &self.flow_controller) .finish() } } impl FlattenUnorderedWithFlowController where St: Stream, Fc: FlowController::Item>, St::Item: Stream + Unpin, { pub(crate) fn new( stream: St, limit: Option, ) -> FlattenUnorderedWithFlowController { let poll_state = SharedPollState::new(NEED_TO_POLL_STREAM); FlattenUnorderedWithFlowController { inner_streams: FuturesUnordered::new(), stream, is_stream_done: false, limit: limit.and_then(NonZeroUsize::new), inner_streams_waker: Arc::new(WrappedWaker { inner_waker: UnsafeCell::new(None), poll_state: poll_state.clone(), need_to_poll: NEED_TO_POLL_INNER_STREAMS, }), stream_waker: Arc::new(WrappedWaker { inner_waker: UnsafeCell::new(None), poll_state: poll_state.clone(), need_to_poll: NEED_TO_POLL_STREAM, }), poll_state, flow_controller: PhantomData, } } delegate_access_inner!(stream, St, ()); } /// Returns the next flow step based on the received item. pub trait FlowController { /// Handles an item producing `FlowStep` describing the next flow step. fn next_step(item: I) -> FlowStep; } impl FlowController for () { fn next_step(item: I) -> FlowStep { FlowStep::Continue(item) } } /// Describes the next flow step. #[derive(Debug, Clone)] pub enum FlowStep { /// Just yields an item and continues standard flow. Continue(C), /// Immediately returns an underlying item from the function. Return(R), } impl FlattenUnorderedWithFlowControllerProj<'_, St, Fc> where St: Stream, { /// Checks if current `inner_streams` bucket size is greater than optional limit. fn is_exceeded_limit(&self) -> bool { self.limit.map_or(false, |limit| self.inner_streams.len() >= limit.get()) } } impl FusedStream for FlattenUnorderedWithFlowController where St: FusedStream, Fc: FlowController::Item>, St::Item: Stream + Unpin, { fn is_terminated(&self) -> bool { self.stream.is_terminated() && self.inner_streams.is_empty() } } impl Stream for FlattenUnorderedWithFlowController where St: Stream, Fc: FlowController::Item>, St::Item: Stream + Unpin, { type Item = ::Item; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut next_item = None; let mut need_to_poll_next = NONE; let mut this = self.as_mut().project(); // Attempt to start polling, in case some waker is holding the lock, wait in loop let (mut poll_state_value, state_bomb) = loop { if let Some(value) = this.poll_state.start_polling() { break value; } }; // Safety: now state is `POLLING`. unsafe { WrappedWaker::replace_waker(this.stream_waker, cx); WrappedWaker::replace_waker(this.inner_streams_waker, cx) }; if poll_state_value & NEED_TO_POLL_STREAM != NONE { let mut stream_waker = None; // Here we need to poll the base stream. // // To improve performance, we will attempt to place as many items as we can // to the `FuturesUnordered` bucket before polling inner streams loop { if this.is_exceeded_limit() || *this.is_stream_done { // We either exceeded the limit or the stream is exhausted if !*this.is_stream_done { // The stream needs to be polled in the next iteration need_to_poll_next |= NEED_TO_POLL_STREAM; } break; } else { let mut cx = Context::from_waker( stream_waker.get_or_insert_with(|| waker(this.stream_waker.clone())), ); match this.stream.as_mut().poll_next(&mut cx) { Poll::Ready(Some(item)) => { let next_item_fut = match Fc::next_step(item) { // Propagates an item immediately (the main use-case is for errors) FlowStep::Return(item) => { need_to_poll_next |= NEED_TO_POLL_STREAM | (poll_state_value & NEED_TO_POLL_INNER_STREAMS); poll_state_value &= !NEED_TO_POLL_INNER_STREAMS; next_item = Some(item); break; } // Yields an item and continues processing (normal case) FlowStep::Continue(inner_stream) => { PollStreamFut::new(inner_stream) } }; // Add new stream to the inner streams bucket this.inner_streams.as_mut().push(next_item_fut); // Inner streams must be polled afterward poll_state_value |= NEED_TO_POLL_INNER_STREAMS; } Poll::Ready(None) => { // Mark the base stream as done *this.is_stream_done = true; } Poll::Pending => { break; } } } } } if poll_state_value & NEED_TO_POLL_INNER_STREAMS != NONE { let inner_streams_waker = waker(this.inner_streams_waker.clone()); let mut cx = Context::from_waker(&inner_streams_waker); match this.inner_streams.as_mut().poll_next(&mut cx) { Poll::Ready(Some(Some((item, next_item_fut)))) => { // Push next inner stream item future to the list of inner streams futures this.inner_streams.as_mut().push(next_item_fut); // Take the received item next_item = Some(item); // On the next iteration, inner streams must be polled again need_to_poll_next |= NEED_TO_POLL_INNER_STREAMS; } Poll::Ready(Some(None)) => { // On the next iteration, inner streams must be polled again need_to_poll_next |= NEED_TO_POLL_INNER_STREAMS; } _ => {} } } // We didn't have any `poll_next` panic, so it's time to deactivate the bomb state_bomb.deactivate(); // Call the waker at the end of polling if let mut force_wake = // we need to poll the stream and didn't reach the limit yet need_to_poll_next & NEED_TO_POLL_STREAM != NONE && !this.is_exceeded_limit() // or we need to poll the inner streams again || need_to_poll_next & NEED_TO_POLL_INNER_STREAMS != NONE; // Stop polling and swap the latest state poll_state_value = this.poll_state.stop_polling(need_to_poll_next, force_wake); // If state was changed during `POLLING` phase, we also need to manually call a waker force_wake |= poll_state_value & NEED_TO_POLL_ALL != NONE; let is_done = *this.is_stream_done && this.inner_streams.is_empty(); if next_item.is_some() || is_done { Poll::Ready(next_item) } else { if force_wake { cx.waker().wake_by_ref(); } Poll::Pending } } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for FlattenUnorderedWithFlowController where St: Stream + Sink, { type Error = St::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/stream/fold.rs000064400000000000000000000046361046102023000172370ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; use futures_core::stream::Stream; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`fold`](super::StreamExt::fold) method. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Fold { #[pin] stream: St, f: F, accum: Option, #[pin] future: Option, } } impl fmt::Debug for Fold where St: fmt::Debug, Fut: fmt::Debug, T: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Fold") .field("stream", &self.stream) .field("accum", &self.accum) .field("future", &self.future) .finish() } } impl Fold where St: Stream, F: FnMut(T, St::Item) -> Fut, Fut: Future, { pub(super) fn new(stream: St, f: F, t: T) -> Self { Self { stream, f, accum: Some(t), future: None } } } impl FusedFuture for Fold where St: Stream, F: FnMut(T, St::Item) -> Fut, Fut: Future, { fn is_terminated(&self) -> bool { self.accum.is_none() && self.future.is_none() } } impl Future for Fold where St: Stream, F: FnMut(T, St::Item) -> Fut, Fut: Future, { type Output = T; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.project(); Poll::Ready(loop { if let Some(fut) = this.future.as_mut().as_pin_mut() { // we're currently processing a future to produce a new accum value *this.accum = Some(ready!(fut.poll(cx))); this.future.set(None); } else if this.accum.is_some() { // we're waiting on a new item from the stream let res = ready!(this.stream.as_mut().poll_next(cx)); let a = this.accum.take().unwrap(); if let Some(item) = res { this.future.set(Some((this.f)(a, item))); } else { break a; } } else { panic!("Fold polled after completion") } }) } } futures-util-0.3.30/src/stream/stream/for_each.rs000064400000000000000000000037001046102023000200500ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`for_each`](super::StreamExt::for_each) method. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct ForEach { #[pin] stream: St, f: F, #[pin] future: Option, } } impl fmt::Debug for ForEach where St: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ForEach") .field("stream", &self.stream) .field("future", &self.future) .finish() } } impl ForEach where St: Stream, F: FnMut(St::Item) -> Fut, Fut: Future, { pub(super) fn new(stream: St, f: F) -> Self { Self { stream, f, future: None } } } impl FusedFuture for ForEach where St: FusedStream, F: FnMut(St::Item) -> Fut, Fut: Future, { fn is_terminated(&self) -> bool { self.future.is_none() && self.stream.is_terminated() } } impl Future for ForEach where St: Stream, F: FnMut(St::Item) -> Fut, Fut: Future, { type Output = (); fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { let mut this = self.project(); loop { if let Some(fut) = this.future.as_mut().as_pin_mut() { ready!(fut.poll(cx)); this.future.set(None); } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { this.future.set(Some((this.f)(item))); } else { break; } } Poll::Ready(()) } } futures-util-0.3.30/src/stream/stream/for_each_concurrent.rs000064400000000000000000000070061046102023000223150ustar 00000000000000use crate::stream::{FuturesUnordered, StreamExt}; use core::fmt; use core::num::NonZeroUsize; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::stream::Stream; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`for_each_concurrent`](super::StreamExt::for_each_concurrent) /// method. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct ForEachConcurrent { #[pin] stream: Option, f: F, futures: FuturesUnordered, limit: Option, } } impl fmt::Debug for ForEachConcurrent where St: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ForEachConcurrent") .field("stream", &self.stream) .field("futures", &self.futures) .field("limit", &self.limit) .finish() } } impl ForEachConcurrent where St: Stream, F: FnMut(St::Item) -> Fut, Fut: Future, { pub(super) fn new(stream: St, limit: Option, f: F) -> Self { Self { stream: Some(stream), // Note: `limit` = 0 gets ignored. limit: limit.and_then(NonZeroUsize::new), f, futures: FuturesUnordered::new(), } } } impl FusedFuture for ForEachConcurrent where St: Stream, F: FnMut(St::Item) -> Fut, Fut: Future, { fn is_terminated(&self) -> bool { self.stream.is_none() && self.futures.is_empty() } } impl Future for ForEachConcurrent where St: Stream, F: FnMut(St::Item) -> Fut, Fut: Future, { type Output = (); fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { let mut this = self.project(); loop { let mut made_progress_this_iter = false; // Check if we've already created a number of futures greater than `limit` if this.limit.map(|limit| limit.get() > this.futures.len()).unwrap_or(true) { let mut stream_completed = false; let elem = if let Some(stream) = this.stream.as_mut().as_pin_mut() { match stream.poll_next(cx) { Poll::Ready(Some(elem)) => { made_progress_this_iter = true; Some(elem) } Poll::Ready(None) => { stream_completed = true; None } Poll::Pending => None, } } else { None }; if stream_completed { this.stream.set(None); } if let Some(elem) = elem { this.futures.push((this.f)(elem)); } } match this.futures.poll_next_unpin(cx) { Poll::Ready(Some(())) => made_progress_this_iter = true, Poll::Ready(None) => { if this.stream.is_none() { return Poll::Ready(()); } } Poll::Pending => {} } if !made_progress_this_iter { return Poll::Pending; } } } } futures-util-0.3.30/src/stream/stream/forward.rs000064400000000000000000000044051046102023000177510ustar 00000000000000use crate::stream::Fuse; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; use futures_core::stream::Stream; use futures_core::task::{Context, Poll}; use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Future for the [`forward`](super::StreamExt::forward) method. #[project = ForwardProj] #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Forward { #[pin] sink: Option, #[pin] stream: Fuse, buffered_item: Option, } } impl Forward { pub(crate) fn new(stream: St, sink: Si) -> Self { Self { sink: Some(sink), stream: Fuse::new(stream), buffered_item: None } } } impl FusedFuture for Forward where Si: Sink, St: Stream>, { fn is_terminated(&self) -> bool { self.sink.is_none() } } impl Future for Forward where Si: Sink, St: Stream>, { type Output = Result<(), E>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let ForwardProj { mut sink, mut stream, buffered_item } = self.project(); let mut si = sink.as_mut().as_pin_mut().expect("polled `Forward` after completion"); loop { // If we've got an item buffered already, we need to write it to the // sink before we can do anything else if buffered_item.is_some() { ready!(si.as_mut().poll_ready(cx))?; si.as_mut().start_send(buffered_item.take().unwrap())?; } match stream.as_mut().poll_next(cx)? { Poll::Ready(Some(item)) => { *buffered_item = Some(item); } Poll::Ready(None) => { ready!(si.poll_close(cx))?; sink.set(None); return Poll::Ready(Ok(())); } Poll::Pending => { ready!(si.poll_flush(cx))?; return Poll::Pending; } } } } } futures-util-0.3.30/src/stream/stream/fuse.rs000064400000000000000000000034571046102023000172550ustar 00000000000000use core::pin::Pin; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`fuse`](super::StreamExt::fuse) method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct Fuse { #[pin] stream: St, done: bool, } } impl Fuse { pub(super) fn new(stream: St) -> Self { Self { stream, done: false } } /// Returns whether the underlying stream has finished or not. /// /// If this method returns `true`, then all future calls to poll are /// guaranteed to return `None`. If this returns `false`, then the /// underlying stream is still in use. pub fn is_done(&self) -> bool { self.done } delegate_access_inner!(stream, St, ()); } impl FusedStream for Fuse { fn is_terminated(&self) -> bool { self.done } } impl Stream for Fuse { type Item = S::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); if *this.done { return Poll::Ready(None); } let item = ready!(this.stream.poll_next(cx)); if item.is_none() { *this.done = true; } Poll::Ready(item) } fn size_hint(&self) -> (usize, Option) { if self.done { (0, Some(0)) } else { self.stream.size_hint() } } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl, Item> Sink for Fuse { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/stream/into_future.rs000064400000000000000000000066141046102023000206540ustar 00000000000000use crate::stream::StreamExt; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; use futures_core::stream::Stream; use futures_core::task::{Context, Poll}; /// Future for the [`into_future`](super::StreamExt::into_future) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct StreamFuture { stream: Option, } impl StreamFuture { pub(super) fn new(stream: St) -> Self { Self { stream: Some(stream) } } /// Acquires a reference to the underlying stream that this combinator is /// pulling from. /// /// This method returns an `Option` to account for the fact that `StreamFuture`'s /// implementation of `Future::poll` consumes the underlying stream during polling /// in order to return it to the caller of `Future::poll` if the stream yielded /// an element. pub fn get_ref(&self) -> Option<&St> { self.stream.as_ref() } /// Acquires a mutable reference to the underlying stream that this /// combinator is pulling from. /// /// Note that care must be taken to avoid tampering with the state of the /// stream which may otherwise confuse this combinator. /// /// This method returns an `Option` to account for the fact that `StreamFuture`'s /// implementation of `Future::poll` consumes the underlying stream during polling /// in order to return it to the caller of `Future::poll` if the stream yielded /// an element. pub fn get_mut(&mut self) -> Option<&mut St> { self.stream.as_mut() } /// Acquires a pinned mutable reference to the underlying stream that this /// combinator is pulling from. /// /// Note that care must be taken to avoid tampering with the state of the /// stream which may otherwise confuse this combinator. /// /// This method returns an `Option` to account for the fact that `StreamFuture`'s /// implementation of `Future::poll` consumes the underlying stream during polling /// in order to return it to the caller of `Future::poll` if the stream yielded /// an element. pub fn get_pin_mut(self: Pin<&mut Self>) -> Option> { self.get_mut().stream.as_mut().map(Pin::new) } /// Consumes this combinator, returning the underlying stream. /// /// Note that this may discard intermediate state of this combinator, so /// care should be taken to avoid losing resources when this is called. /// /// This method returns an `Option` to account for the fact that `StreamFuture`'s /// implementation of `Future::poll` consumes the underlying stream during polling /// in order to return it to the caller of `Future::poll` if the stream yielded /// an element. pub fn into_inner(self) -> Option { self.stream } } impl FusedFuture for StreamFuture { fn is_terminated(&self) -> bool { self.stream.is_none() } } impl Future for StreamFuture { type Output = (Option, St); fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let item = { let s = self.stream.as_mut().expect("polling StreamFuture twice"); ready!(s.poll_next_unpin(cx)) }; let stream = self.stream.take().unwrap(); Poll::Ready((item, stream)) } } futures-util-0.3.30/src/stream/stream/map.rs000064400000000000000000000032711046102023000170620ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; use crate::fns::FnMut1; pin_project! { /// Stream for the [`map`](super::StreamExt::map) method. #[must_use = "streams do nothing unless polled"] pub struct Map { #[pin] stream: St, f: F, } } impl fmt::Debug for Map where St: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Map").field("stream", &self.stream).finish() } } impl Map { pub(crate) fn new(stream: St, f: F) -> Self { Self { stream, f } } delegate_access_inner!(stream, St, ()); } impl FusedStream for Map where St: FusedStream, F: FnMut1, { fn is_terminated(&self) -> bool { self.stream.is_terminated() } } impl Stream for Map where St: Stream, F: FnMut1, { type Item = F::Output; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); let res = ready!(this.stream.as_mut().poll_next(cx)); Poll::Ready(res.map(|x| this.f.call_mut(x))) } fn size_hint(&self) -> (usize, Option) { self.stream.size_hint() } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for Map where St: Stream + Sink, F: FnMut1, { type Error = St::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/stream/mod.rs000064400000000000000000001630501046102023000170660ustar 00000000000000//! Streams //! //! This module contains a number of functions for working with `Stream`s, //! including the `StreamExt` trait which adds methods to `Stream` types. use crate::future::{assert_future, Either}; use crate::stream::assert_stream; #[cfg(feature = "alloc")] use alloc::boxed::Box; #[cfg(feature = "alloc")] use alloc::vec::Vec; use core::pin::Pin; #[cfg(feature = "sink")] use futures_core::stream::TryStream; #[cfg(feature = "alloc")] use futures_core::stream::{BoxStream, LocalBoxStream}; use futures_core::{ future::Future, stream::{FusedStream, Stream}, task::{Context, Poll}, }; #[cfg(feature = "sink")] use futures_sink::Sink; use crate::fns::{inspect_fn, InspectFn}; mod chain; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::chain::Chain; mod collect; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::collect::Collect; mod unzip; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::unzip::Unzip; mod concat; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::concat::Concat; mod count; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::count::Count; mod cycle; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::cycle::Cycle; mod enumerate; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::enumerate::Enumerate; mod filter; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::filter::Filter; mod filter_map; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::filter_map::FilterMap; mod flatten; delegate_all!( /// Stream for the [`flatten`](StreamExt::flatten) method. Flatten( flatten::Flatten ): Debug + Sink + Stream + FusedStream + AccessInner[St, (.)] + New[|x: St| flatten::Flatten::new(x)] where St: Stream ); mod fold; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::fold::Fold; mod any; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::any::Any; mod all; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::all::All; #[cfg(feature = "sink")] mod forward; #[cfg(feature = "sink")] delegate_all!( /// Future for the [`forward`](super::StreamExt::forward) method. #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] Forward( forward::Forward ): Debug + Future + FusedFuture + New[|x: St, y: Si| forward::Forward::new(x, y)] where St: TryStream ); mod for_each; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::for_each::ForEach; mod fuse; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::fuse::Fuse; mod into_future; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::into_future::StreamFuture; delegate_all!( /// Stream for the [`inspect`](StreamExt::inspect) method. Inspect( map::Map> ): Debug + Sink + Stream + FusedStream + AccessInner[St, (.)] + New[|x: St, f: F| map::Map::new(x, inspect_fn(f))] ); mod map; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::map::Map; delegate_all!( /// Stream for the [`flat_map`](StreamExt::flat_map) method. FlatMap( flatten::Flatten, U> ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + New[|x: St, f: F| flatten::Flatten::new(Map::new(x, f))] ); mod next; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::next::Next; mod select_next_some; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::select_next_some::SelectNextSome; mod peek; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::peek::{NextIf, NextIfEq, Peek, PeekMut, Peekable}; mod skip; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::skip::Skip; mod skip_while; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::skip_while::SkipWhile; mod take; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::take::Take; mod take_while; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::take_while::TakeWhile; mod take_until; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::take_until::TakeUntil; mod then; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::then::Then; mod zip; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::zip::Zip; #[cfg(feature = "alloc")] mod chunks; #[cfg(feature = "alloc")] #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::chunks::Chunks; #[cfg(feature = "alloc")] mod ready_chunks; #[cfg(feature = "alloc")] #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::ready_chunks::ReadyChunks; mod scan; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::scan::Scan; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] mod buffer_unordered; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::buffer_unordered::BufferUnordered; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] mod buffered; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::buffered::Buffered; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] pub(crate) mod flatten_unordered; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] #[allow(unreachable_pub)] pub use self::flatten_unordered::FlattenUnordered; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] delegate_all!( /// Stream for the [`flat_map_unordered`](StreamExt::flat_map_unordered) method. FlatMapUnordered( FlattenUnordered> ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + New[|x: St, limit: Option, f: F| FlattenUnordered::new(Map::new(x, f), limit)] where St: Stream, U: Stream, U: Unpin, F: FnMut(St::Item) -> U ); #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] mod for_each_concurrent; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::for_each_concurrent::ForEachConcurrent; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "sink")] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] #[cfg(feature = "alloc")] mod split; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "sink")] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] #[cfg(feature = "alloc")] #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::split::{ReuniteError, SplitSink, SplitStream}; #[cfg(feature = "std")] mod catch_unwind; #[cfg(feature = "std")] #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::catch_unwind::CatchUnwind; impl StreamExt for T where T: Stream {} /// An extension trait for `Stream`s that provides a variety of convenient /// combinator functions. pub trait StreamExt: Stream { /// Creates a future that resolves to the next item in the stream. /// /// Note that because `next` doesn't take ownership over the stream, /// the [`Stream`] type must be [`Unpin`]. If you want to use `next` with a /// [`!Unpin`](Unpin) stream, you'll first have to pin the stream. This can /// be done by boxing the stream using [`Box::pin`] or /// pinning it to the stack using the `pin_mut!` macro from the `pin_utils` /// crate. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let mut stream = stream::iter(1..=3); /// /// assert_eq!(stream.next().await, Some(1)); /// assert_eq!(stream.next().await, Some(2)); /// assert_eq!(stream.next().await, Some(3)); /// assert_eq!(stream.next().await, None); /// # }); /// ``` fn next(&mut self) -> Next<'_, Self> where Self: Unpin, { assert_future::, _>(Next::new(self)) } /// Converts this stream into a future of `(next_item, tail_of_stream)`. /// If the stream terminates, then the next item is [`None`]. /// /// The returned future can be used to compose streams and futures together /// by placing everything into the "world of futures". /// /// Note that because `into_future` moves the stream, the [`Stream`] type /// must be [`Unpin`]. If you want to use `into_future` with a /// [`!Unpin`](Unpin) stream, you'll first have to pin the stream. This can /// be done by boxing the stream using [`Box::pin`] or /// pinning it to the stack using the `pin_mut!` macro from the `pin_utils` /// crate. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::iter(1..=3); /// /// let (item, stream) = stream.into_future().await; /// assert_eq!(Some(1), item); /// /// let (item, stream) = stream.into_future().await; /// assert_eq!(Some(2), item); /// # }); /// ``` fn into_future(self) -> StreamFuture where Self: Sized + Unpin, { assert_future::<(Option, Self), _>(StreamFuture::new(self)) } /// Maps this stream's items to a different type, returning a new stream of /// the resulting type. /// /// The provided closure is executed over all elements of this stream as /// they are made available. It is executed inline with calls to /// [`poll_next`](Stream::poll_next). /// /// Note that this function consumes the stream passed into it and returns a /// wrapped version of it, similar to the existing `map` methods in the /// standard library. /// /// See [`StreamExt::then`](Self::then) if you want to use a closure that /// returns a future instead of a value. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::iter(1..=3); /// let stream = stream.map(|x| x + 3); /// /// assert_eq!(vec![4, 5, 6], stream.collect::>().await); /// # }); /// ``` fn map(self, f: F) -> Map where F: FnMut(Self::Item) -> T, Self: Sized, { assert_stream::(Map::new(self, f)) } /// Creates a stream which gives the current iteration count as well as /// the next value. /// /// The stream returned yields pairs `(i, val)`, where `i` is the /// current index of iteration and `val` is the value returned by the /// stream. /// /// `enumerate()` keeps its count as a [`usize`]. If you want to count by a /// different sized integer, the [`zip`](StreamExt::zip) function provides similar /// functionality. /// /// # Overflow Behavior /// /// The method does no guarding against overflows, so enumerating more than /// [`prim@usize::max_value()`] elements either produces the wrong result or panics. If /// debug assertions are enabled, a panic is guaranteed. /// /// # Panics /// /// The returned stream might panic if the to-be-returned index would /// overflow a [`usize`]. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::iter(vec!['a', 'b', 'c']); /// /// let mut stream = stream.enumerate(); /// /// assert_eq!(stream.next().await, Some((0, 'a'))); /// assert_eq!(stream.next().await, Some((1, 'b'))); /// assert_eq!(stream.next().await, Some((2, 'c'))); /// assert_eq!(stream.next().await, None); /// # }); /// ``` fn enumerate(self) -> Enumerate where Self: Sized, { assert_stream::<(usize, Self::Item), _>(Enumerate::new(self)) } /// Filters the values produced by this stream according to the provided /// asynchronous predicate. /// /// As values of this stream are made available, the provided predicate `f` /// will be run against them. If the predicate returns a `Future` which /// resolves to `true`, then the stream will yield the value, but if the /// predicate returns a `Future` which resolves to `false`, then the value /// will be discarded and the next value will be produced. /// /// Note that this function consumes the stream passed into it and returns a /// wrapped version of it, similar to the existing `filter` methods in the /// standard library. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::iter(1..=10); /// let events = stream.filter(|x| future::ready(x % 2 == 0)); /// /// assert_eq!(vec![2, 4, 6, 8, 10], events.collect::>().await); /// # }); /// ``` fn filter(self, f: F) -> Filter where F: FnMut(&Self::Item) -> Fut, Fut: Future, Self: Sized, { assert_stream::(Filter::new(self, f)) } /// Filters the values produced by this stream while simultaneously mapping /// them to a different type according to the provided asynchronous closure. /// /// As values of this stream are made available, the provided function will /// be run on them. If the future returned by the predicate `f` resolves to /// [`Some(item)`](Some) then the stream will yield the value `item`, but if /// it resolves to [`None`] then the next value will be produced. /// /// Note that this function consumes the stream passed into it and returns a /// wrapped version of it, similar to the existing `filter_map` methods in /// the standard library. /// /// # Examples /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::iter(1..=10); /// let events = stream.filter_map(|x| async move { /// if x % 2 == 0 { Some(x + 1) } else { None } /// }); /// /// assert_eq!(vec![3, 5, 7, 9, 11], events.collect::>().await); /// # }); /// ``` fn filter_map(self, f: F) -> FilterMap where F: FnMut(Self::Item) -> Fut, Fut: Future>, Self: Sized, { assert_stream::(FilterMap::new(self, f)) } /// Computes from this stream's items new items of a different type using /// an asynchronous closure. /// /// The provided closure `f` will be called with an `Item` once a value is /// ready, it returns a future which will then be run to completion /// to produce the next value on this stream. /// /// Note that this function consumes the stream passed into it and returns a /// wrapped version of it. /// /// See [`StreamExt::map`](Self::map) if you want to use a closure that /// returns a value instead of a future. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::iter(1..=3); /// let stream = stream.then(|x| async move { x + 3 }); /// /// assert_eq!(vec![4, 5, 6], stream.collect::>().await); /// # }); /// ``` fn then(self, f: F) -> Then where F: FnMut(Self::Item) -> Fut, Fut: Future, Self: Sized, { assert_stream::(Then::new(self, f)) } /// Transforms a stream into a collection, returning a /// future representing the result of that computation. /// /// The returned future will be resolved when the stream terminates. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::channel::mpsc; /// use futures::stream::StreamExt; /// use std::thread; /// /// let (tx, rx) = mpsc::unbounded(); /// /// thread::spawn(move || { /// for i in 1..=5 { /// tx.unbounded_send(i).unwrap(); /// } /// }); /// /// let output = rx.collect::>().await; /// assert_eq!(output, vec![1, 2, 3, 4, 5]); /// # }); /// ``` fn collect>(self) -> Collect where Self: Sized, { assert_future::(Collect::new(self)) } /// Converts a stream of pairs into a future, which /// resolves to pair of containers. /// /// `unzip()` produces a future, which resolves to two /// collections: one from the left elements of the pairs, /// and one from the right elements. /// /// The returned future will be resolved when the stream terminates. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::channel::mpsc; /// use futures::stream::StreamExt; /// use std::thread; /// /// let (tx, rx) = mpsc::unbounded(); /// /// thread::spawn(move || { /// tx.unbounded_send((1, 2)).unwrap(); /// tx.unbounded_send((3, 4)).unwrap(); /// tx.unbounded_send((5, 6)).unwrap(); /// }); /// /// let (o1, o2): (Vec<_>, Vec<_>) = rx.unzip().await; /// assert_eq!(o1, vec![1, 3, 5]); /// assert_eq!(o2, vec![2, 4, 6]); /// # }); /// ``` fn unzip(self) -> Unzip where FromA: Default + Extend, FromB: Default + Extend, Self: Sized + Stream, { assert_future::<(FromA, FromB), _>(Unzip::new(self)) } /// Concatenate all items of a stream into a single extendable /// destination, returning a future representing the end result. /// /// This combinator will extend the first item with the contents /// of all the subsequent results of the stream. If the stream is /// empty, the default value will be returned. /// /// Works with all collections that implement the /// [`Extend`](std::iter::Extend) trait. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::channel::mpsc; /// use futures::stream::StreamExt; /// use std::thread; /// /// let (tx, rx) = mpsc::unbounded(); /// /// thread::spawn(move || { /// for i in (0..3).rev() { /// let n = i * 3; /// tx.unbounded_send(vec![n + 1, n + 2, n + 3]).unwrap(); /// } /// }); /// /// let result = rx.concat().await; /// /// assert_eq!(result, vec![7, 8, 9, 4, 5, 6, 1, 2, 3]); /// # }); /// ``` fn concat(self) -> Concat where Self: Sized, Self::Item: Extend<<::Item as IntoIterator>::Item> + IntoIterator + Default, { assert_future::(Concat::new(self)) } /// Drives the stream to completion, counting the number of items. /// /// # Overflow Behavior /// /// The method does no guarding against overflows, so counting elements of a /// stream with more than [`usize::MAX`] elements either produces the wrong /// result or panics. If debug assertions are enabled, a panic is guaranteed. /// /// # Panics /// /// This function might panic if the iterator has more than [`usize::MAX`] /// elements. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::iter(1..=10); /// let count = stream.count().await; /// /// assert_eq!(count, 10); /// # }); /// ``` fn count(self) -> Count where Self: Sized, { assert_future::(Count::new(self)) } /// Repeats a stream endlessly. /// /// The stream never terminates. Note that you likely want to avoid /// usage of `collect` or such on the returned stream as it will exhaust /// available memory as it tries to just fill up all RAM. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// let a = [1, 2, 3]; /// let mut s = stream::iter(a.iter()).cycle(); /// /// assert_eq!(s.next().await, Some(&1)); /// assert_eq!(s.next().await, Some(&2)); /// assert_eq!(s.next().await, Some(&3)); /// assert_eq!(s.next().await, Some(&1)); /// assert_eq!(s.next().await, Some(&2)); /// assert_eq!(s.next().await, Some(&3)); /// assert_eq!(s.next().await, Some(&1)); /// # }); /// ``` fn cycle(self) -> Cycle where Self: Sized + Clone, { assert_stream::(Cycle::new(self)) } /// Execute an accumulating asynchronous computation over a stream, /// collecting all the values into one final result. /// /// This combinator will accumulate all values returned by this stream /// according to the closure provided. The initial state is also provided to /// this method and then is returned again by each execution of the closure. /// Once the entire stream has been exhausted the returned future will /// resolve to this value. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let number_stream = stream::iter(0..6); /// let sum = number_stream.fold(0, |acc, x| async move { acc + x }); /// assert_eq!(sum.await, 15); /// # }); /// ``` fn fold(self, init: T, f: F) -> Fold where F: FnMut(T, Self::Item) -> Fut, Fut: Future, Self: Sized, { assert_future::(Fold::new(self, f, init)) } /// Execute predicate over asynchronous stream, and return `true` if any element in stream satisfied a predicate. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let number_stream = stream::iter(0..10); /// let contain_three = number_stream.any(|i| async move { i == 3 }); /// assert_eq!(contain_three.await, true); /// # }); /// ``` fn any(self, f: F) -> Any where F: FnMut(Self::Item) -> Fut, Fut: Future, Self: Sized, { assert_future::(Any::new(self, f)) } /// Execute predicate over asynchronous stream, and return `true` if all element in stream satisfied a predicate. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let number_stream = stream::iter(0..10); /// let less_then_twenty = number_stream.all(|i| async move { i < 20 }); /// assert_eq!(less_then_twenty.await, true); /// # }); /// ``` fn all(self, f: F) -> All where F: FnMut(Self::Item) -> Fut, Fut: Future, Self: Sized, { assert_future::(All::new(self, f)) } /// Flattens a stream of streams into just one continuous stream. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::channel::mpsc; /// use futures::stream::StreamExt; /// use std::thread; /// /// let (tx1, rx1) = mpsc::unbounded(); /// let (tx2, rx2) = mpsc::unbounded(); /// let (tx3, rx3) = mpsc::unbounded(); /// /// thread::spawn(move || { /// tx1.unbounded_send(1).unwrap(); /// tx1.unbounded_send(2).unwrap(); /// }); /// thread::spawn(move || { /// tx2.unbounded_send(3).unwrap(); /// tx2.unbounded_send(4).unwrap(); /// }); /// thread::spawn(move || { /// tx3.unbounded_send(rx1).unwrap(); /// tx3.unbounded_send(rx2).unwrap(); /// }); /// /// let output = rx3.flatten().collect::>().await; /// assert_eq!(output, vec![1, 2, 3, 4]); /// # }); /// ``` fn flatten(self) -> Flatten where Self::Item: Stream, Self: Sized, { assert_stream::<::Item, _>(Flatten::new(self)) } /// Flattens a stream of streams into just one continuous stream. Polls /// inner streams produced by the base stream concurrently. /// /// The only argument is an optional limit on the number of concurrently /// polled streams. If this limit is not `None`, no more than `limit` streams /// will be polled at the same time. The `limit` argument is of type /// `Into>`, and so can be provided as either `None`, /// `Some(10)`, or just `10`. Note: a limit of zero is interpreted as /// no limit at all, and will have the same result as passing in `None`. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::channel::mpsc; /// use futures::stream::StreamExt; /// use std::thread; /// /// let (tx1, rx1) = mpsc::unbounded(); /// let (tx2, rx2) = mpsc::unbounded(); /// let (tx3, rx3) = mpsc::unbounded(); /// /// thread::spawn(move || { /// tx1.unbounded_send(1).unwrap(); /// tx1.unbounded_send(2).unwrap(); /// }); /// thread::spawn(move || { /// tx2.unbounded_send(3).unwrap(); /// tx2.unbounded_send(4).unwrap(); /// }); /// thread::spawn(move || { /// tx3.unbounded_send(rx1).unwrap(); /// tx3.unbounded_send(rx2).unwrap(); /// }); /// /// let mut output = rx3.flatten_unordered(None).collect::>().await; /// output.sort(); /// /// assert_eq!(output, vec![1, 2, 3, 4]); /// # }); /// ``` #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] fn flatten_unordered(self, limit: impl Into>) -> FlattenUnordered where Self::Item: Stream + Unpin, Self: Sized, { assert_stream::<::Item, _>(FlattenUnordered::new(self, limit.into())) } /// Maps a stream like [`StreamExt::map`] but flattens nested `Stream`s. /// /// [`StreamExt::map`] is very useful, but if it produces a `Stream` instead, /// you would have to chain combinators like `.map(f).flatten()` while this /// combinator provides ability to write `.flat_map(f)` instead of chaining. /// /// The provided closure which produces inner streams is executed over all elements /// of stream as last inner stream is terminated and next stream item is available. /// /// Note that this function consumes the stream passed into it and returns a /// wrapped version of it, similar to the existing `flat_map` methods in the /// standard library. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::iter(1..=3); /// let stream = stream.flat_map(|x| stream::iter(vec![x + 3; x])); /// /// assert_eq!(vec![4, 5, 5, 6, 6, 6], stream.collect::>().await); /// # }); /// ``` fn flat_map(self, f: F) -> FlatMap where F: FnMut(Self::Item) -> U, U: Stream, Self: Sized, { assert_stream::(FlatMap::new(self, f)) } /// Maps a stream like [`StreamExt::map`] but flattens nested `Stream`s /// and polls them concurrently, yielding items in any order, as they made /// available. /// /// [`StreamExt::map`] is very useful, but if it produces `Stream`s /// instead, and you need to poll all of them concurrently, you would /// have to use something like `for_each_concurrent` and merge values /// by hand. This combinator provides ability to collect all values /// from concurrently polled streams into one stream. /// /// The first argument is an optional limit on the number of concurrently /// polled streams. If this limit is not `None`, no more than `limit` streams /// will be polled at the same time. The `limit` argument is of type /// `Into>`, and so can be provided as either `None`, /// `Some(10)`, or just `10`. Note: a limit of zero is interpreted as /// no limit at all, and will have the same result as passing in `None`. /// /// The provided closure which produces inner streams is executed over /// all elements of stream as next stream item is available and limit /// of concurrently processed streams isn't exceeded. /// /// Note that this function consumes the stream passed into it and /// returns a wrapped version of it. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::iter(1..5); /// let stream = stream.flat_map_unordered(1, |x| stream::iter(vec![x; x])); /// let mut values = stream.collect::>().await; /// values.sort(); /// /// assert_eq!(vec![1usize, 2, 2, 3, 3, 3, 4, 4, 4, 4], values); /// # }); /// ``` #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] fn flat_map_unordered( self, limit: impl Into>, f: F, ) -> FlatMapUnordered where U: Stream + Unpin, F: FnMut(Self::Item) -> U, Self: Sized, { assert_stream::(FlatMapUnordered::new(self, limit.into(), f)) } /// Combinator similar to [`StreamExt::fold`] that holds internal state /// and produces a new stream. /// /// Accepts initial state and closure which will be applied to each element /// of the stream until provided closure returns `None`. Once `None` is /// returned, stream will be terminated. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::iter(1..=10); /// /// let stream = stream.scan(0, |state, x| { /// *state += x; /// future::ready(if *state < 10 { Some(x) } else { None }) /// }); /// /// assert_eq!(vec![1, 2, 3], stream.collect::>().await); /// # }); /// ``` fn scan(self, initial_state: S, f: F) -> Scan where F: FnMut(&mut S, Self::Item) -> Fut, Fut: Future>, Self: Sized, { assert_stream::(Scan::new(self, initial_state, f)) } /// Skip elements on this stream while the provided asynchronous predicate /// resolves to `true`. /// /// This function, like `Iterator::skip_while`, will skip elements on the /// stream until the predicate `f` resolves to `false`. Once one element /// returns `false`, all future elements will be returned from the underlying /// stream. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::iter(1..=10); /// /// let stream = stream.skip_while(|x| future::ready(*x <= 5)); /// /// assert_eq!(vec![6, 7, 8, 9, 10], stream.collect::>().await); /// # }); /// ``` fn skip_while(self, f: F) -> SkipWhile where F: FnMut(&Self::Item) -> Fut, Fut: Future, Self: Sized, { assert_stream::(SkipWhile::new(self, f)) } /// Take elements from this stream while the provided asynchronous predicate /// resolves to `true`. /// /// This function, like `Iterator::take_while`, will take elements from the /// stream until the predicate `f` resolves to `false`. Once one element /// returns `false`, it will always return that the stream is done. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::iter(1..=10); /// /// let stream = stream.take_while(|x| future::ready(*x <= 5)); /// /// assert_eq!(vec![1, 2, 3, 4, 5], stream.collect::>().await); /// # }); /// ``` fn take_while(self, f: F) -> TakeWhile where F: FnMut(&Self::Item) -> Fut, Fut: Future, Self: Sized, { assert_stream::(TakeWhile::new(self, f)) } /// Take elements from this stream until the provided future resolves. /// /// This function will take elements from the stream until the provided /// stopping future `fut` resolves. Once the `fut` future becomes ready, /// this stream combinator will always return that the stream is done. /// /// The stopping future may return any type. Once the stream is stopped /// the result of the stopping future may be accessed with `TakeUntil::take_result()`. /// The stream may also be resumed with `TakeUntil::take_future()`. /// See the documentation of [`TakeUntil`] for more information. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// use futures::stream::{self, StreamExt}; /// use futures::task::Poll; /// /// let stream = stream::iter(1..=10); /// /// let mut i = 0; /// let stop_fut = future::poll_fn(|_cx| { /// i += 1; /// if i <= 5 { /// Poll::Pending /// } else { /// Poll::Ready(()) /// } /// }); /// /// let stream = stream.take_until(stop_fut); /// /// assert_eq!(vec![1, 2, 3, 4, 5], stream.collect::>().await); /// # }); /// ``` fn take_until(self, fut: Fut) -> TakeUntil where Fut: Future, Self: Sized, { assert_stream::(TakeUntil::new(self, fut)) } /// Runs this stream to completion, executing the provided asynchronous /// closure for each element on the stream. /// /// The closure provided will be called for each item this stream produces, /// yielding a future. That future will then be executed to completion /// before moving on to the next item. /// /// The returned value is a `Future` where the `Output` type is `()`; it is /// executed entirely for its side effects. /// /// To process each item in the stream and produce another stream instead /// of a single future, use `then` instead. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// use futures::stream::{self, StreamExt}; /// /// let mut x = 0; /// /// { /// let fut = stream::repeat(1).take(3).for_each(|item| { /// x += item; /// future::ready(()) /// }); /// fut.await; /// } /// /// assert_eq!(x, 3); /// # }); /// ``` fn for_each(self, f: F) -> ForEach where F: FnMut(Self::Item) -> Fut, Fut: Future, Self: Sized, { assert_future::<(), _>(ForEach::new(self, f)) } /// Runs this stream to completion, executing the provided asynchronous /// closure for each element on the stream concurrently as elements become /// available. /// /// This is similar to [`StreamExt::for_each`], but the futures /// produced by the closure are run concurrently (but not in parallel-- /// this combinator does not introduce any threads). /// /// The closure provided will be called for each item this stream produces, /// yielding a future. That future will then be executed to completion /// concurrently with the other futures produced by the closure. /// /// The first argument is an optional limit on the number of concurrent /// futures. If this limit is not `None`, no more than `limit` futures /// will be run concurrently. The `limit` argument is of type /// `Into>`, and so can be provided as either `None`, /// `Some(10)`, or just `10`. Note: a limit of zero is interpreted as /// no limit at all, and will have the same result as passing in `None`. /// /// This method is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::channel::oneshot; /// use futures::stream::{self, StreamExt}; /// /// let (tx1, rx1) = oneshot::channel(); /// let (tx2, rx2) = oneshot::channel(); /// let (tx3, rx3) = oneshot::channel(); /// /// let fut = stream::iter(vec![rx1, rx2, rx3]).for_each_concurrent( /// /* limit */ 2, /// |rx| async move { /// rx.await.unwrap(); /// } /// ); /// tx1.send(()).unwrap(); /// tx2.send(()).unwrap(); /// tx3.send(()).unwrap(); /// fut.await; /// # }) /// ``` #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] fn for_each_concurrent( self, limit: impl Into>, f: F, ) -> ForEachConcurrent where F: FnMut(Self::Item) -> Fut, Fut: Future, Self: Sized, { assert_future::<(), _>(ForEachConcurrent::new(self, limit.into(), f)) } /// Creates a new stream of at most `n` items of the underlying stream. /// /// Once `n` items have been yielded from this stream then it will always /// return that the stream is done. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::iter(1..=10).take(3); /// /// assert_eq!(vec![1, 2, 3], stream.collect::>().await); /// # }); /// ``` fn take(self, n: usize) -> Take where Self: Sized, { assert_stream::(Take::new(self, n)) } /// Creates a new stream which skips `n` items of the underlying stream. /// /// Once `n` items have been skipped from this stream then it will always /// return the remaining items on this stream. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::iter(1..=10).skip(5); /// /// assert_eq!(vec![6, 7, 8, 9, 10], stream.collect::>().await); /// # }); /// ``` fn skip(self, n: usize) -> Skip where Self: Sized, { assert_stream::(Skip::new(self, n)) } /// Fuse a stream such that [`poll_next`](Stream::poll_next) will never /// again be called once it has finished. This method can be used to turn /// any `Stream` into a `FusedStream`. /// /// Normally, once a stream has returned [`None`] from /// [`poll_next`](Stream::poll_next) any further calls could exhibit bad /// behavior such as block forever, panic, never return, etc. If it is known /// that [`poll_next`](Stream::poll_next) may be called after stream /// has already finished, then this method can be used to ensure that it has /// defined semantics. /// /// The [`poll_next`](Stream::poll_next) method of a `fuse`d stream /// is guaranteed to return [`None`] after the underlying stream has /// finished. /// /// # Examples /// /// ``` /// use futures::executor::block_on_stream; /// use futures::stream::{self, StreamExt}; /// use futures::task::Poll; /// /// let mut x = 0; /// let stream = stream::poll_fn(|_| { /// x += 1; /// match x { /// 0..=2 => Poll::Ready(Some(x)), /// 3 => Poll::Ready(None), /// _ => panic!("should not happen") /// } /// }).fuse(); /// /// let mut iter = block_on_stream(stream); /// assert_eq!(Some(1), iter.next()); /// assert_eq!(Some(2), iter.next()); /// assert_eq!(None, iter.next()); /// assert_eq!(None, iter.next()); /// // ... /// ``` fn fuse(self) -> Fuse where Self: Sized, { assert_stream::(Fuse::new(self)) } /// Borrows a stream, rather than consuming it. /// /// This is useful to allow applying stream adaptors while still retaining /// ownership of the original stream. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let mut stream = stream::iter(1..5); /// /// let sum = stream.by_ref() /// .take(2) /// .fold(0, |a, b| async move { a + b }) /// .await; /// assert_eq!(sum, 3); /// /// // You can use the stream again /// let sum = stream.take(2) /// .fold(0, |a, b| async move { a + b }) /// .await; /// assert_eq!(sum, 7); /// # }); /// ``` fn by_ref(&mut self) -> &mut Self { self } /// Catches unwinding panics while polling the stream. /// /// Caught panic (if any) will be the last element of the resulting stream. /// /// In general, panics within a stream can propagate all the way out to the /// task level. This combinator makes it possible to halt unwinding within /// the stream itself. It's most commonly used within task executors. This /// method should not be used for error handling. /// /// Note that this method requires the `UnwindSafe` bound from the standard /// library. This isn't always applied automatically, and the standard /// library provides an `AssertUnwindSafe` wrapper type to apply it /// after-the fact. To assist using this method, the [`Stream`] trait is /// also implemented for `AssertUnwindSafe` where `St` implements /// [`Stream`]. /// /// This method is only available when the `std` feature of this /// library is activated, and it is activated by default. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::iter(vec![Some(10), None, Some(11)]); /// // Panic on second element /// let stream_panicking = stream.map(|o| o.unwrap()); /// // Collect all the results /// let stream = stream_panicking.catch_unwind(); /// /// let results: Vec> = stream.collect().await; /// match results[0] { /// Ok(10) => {} /// _ => panic!("unexpected result!"), /// } /// assert!(results[1].is_err()); /// assert_eq!(results.len(), 2); /// # }); /// ``` #[cfg(feature = "std")] fn catch_unwind(self) -> CatchUnwind where Self: Sized + std::panic::UnwindSafe, { assert_stream(CatchUnwind::new(self)) } /// Wrap the stream in a Box, pinning it. /// /// This method is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. #[cfg(feature = "alloc")] fn boxed<'a>(self) -> BoxStream<'a, Self::Item> where Self: Sized + Send + 'a, { assert_stream::(Box::pin(self)) } /// Wrap the stream in a Box, pinning it. /// /// Similar to `boxed`, but without the `Send` requirement. /// /// This method is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. #[cfg(feature = "alloc")] fn boxed_local<'a>(self) -> LocalBoxStream<'a, Self::Item> where Self: Sized + 'a, { assert_stream::(Box::pin(self)) } /// An adaptor for creating a buffered list of pending futures. /// /// If this stream's item can be converted into a future, then this adaptor /// will buffer up to at most `n` futures and then return the outputs in the /// same order as the underlying stream. No more than `n` futures will be /// buffered at any point in time, and less than `n` may also be buffered /// depending on the state of each future. /// /// The returned stream will be a stream of each future's output. /// /// This method is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] fn buffered(self, n: usize) -> Buffered where Self::Item: Future, Self: Sized, { assert_stream::<::Output, _>(Buffered::new(self, n)) } /// An adaptor for creating a buffered list of pending futures (unordered). /// /// If this stream's item can be converted into a future, then this adaptor /// will buffer up to `n` futures and then return the outputs in the order /// in which they complete. No more than `n` futures will be buffered at /// any point in time, and less than `n` may also be buffered depending on /// the state of each future. /// /// The returned stream will be a stream of each future's output. /// /// This method is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::channel::oneshot; /// use futures::stream::{self, StreamExt}; /// /// let (send_one, recv_one) = oneshot::channel(); /// let (send_two, recv_two) = oneshot::channel(); /// /// let stream_of_futures = stream::iter(vec![recv_one, recv_two]); /// let mut buffered = stream_of_futures.buffer_unordered(10); /// /// send_two.send(2i32)?; /// assert_eq!(buffered.next().await, Some(Ok(2i32))); /// /// send_one.send(1i32)?; /// assert_eq!(buffered.next().await, Some(Ok(1i32))); /// /// assert_eq!(buffered.next().await, None); /// # Ok::<(), i32>(()) }).unwrap(); /// ``` #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] fn buffer_unordered(self, n: usize) -> BufferUnordered where Self::Item: Future, Self: Sized, { assert_stream::<::Output, _>(BufferUnordered::new(self, n)) } /// An adapter for zipping two streams together. /// /// The zipped stream waits for both streams to produce an item, and then /// returns that pair. If either stream ends then the zipped stream will /// also end. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let stream1 = stream::iter(1..=3); /// let stream2 = stream::iter(5..=10); /// /// let vec = stream1.zip(stream2) /// .collect::>() /// .await; /// assert_eq!(vec![(1, 5), (2, 6), (3, 7)], vec); /// # }); /// ``` /// fn zip(self, other: St) -> Zip where St: Stream, Self: Sized, { assert_stream::<(Self::Item, St::Item), _>(Zip::new(self, other)) } /// Adapter for chaining two streams. /// /// The resulting stream emits elements from the first stream, and when /// first stream reaches the end, emits the elements from the second stream. /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let stream1 = stream::iter(vec![Ok(10), Err(false)]); /// let stream2 = stream::iter(vec![Err(true), Ok(20)]); /// /// let stream = stream1.chain(stream2); /// /// let result: Vec<_> = stream.collect().await; /// assert_eq!(result, vec![ /// Ok(10), /// Err(false), /// Err(true), /// Ok(20), /// ]); /// # }); /// ``` fn chain(self, other: St) -> Chain where St: Stream, Self: Sized, { assert_stream::(Chain::new(self, other)) } /// Creates a new stream which exposes a `peek` method. /// /// Calling `peek` returns a reference to the next item in the stream. fn peekable(self) -> Peekable where Self: Sized, { assert_stream::(Peekable::new(self)) } /// An adaptor for chunking up items of the stream inside a vector. /// /// This combinator will attempt to pull items from this stream and buffer /// them into a local vector. At most `capacity` items will get buffered /// before they're yielded from the returned stream. /// /// Note that the vectors returned from this iterator may not always have /// `capacity` elements. If the underlying stream ended and only a partial /// vector was created, it'll be returned. Additionally if an error happens /// from the underlying stream then the currently buffered items will be /// yielded. /// /// This method is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. /// /// # Panics /// /// This method will panic if `capacity` is zero. #[cfg(feature = "alloc")] fn chunks(self, capacity: usize) -> Chunks where Self: Sized, { assert_stream::, _>(Chunks::new(self, capacity)) } /// An adaptor for chunking up ready items of the stream inside a vector. /// /// This combinator will attempt to pull ready items from this stream and /// buffer them into a local vector. At most `capacity` items will get /// buffered before they're yielded from the returned stream. If underlying /// stream returns `Poll::Pending`, and collected chunk is not empty, it will /// be immediately returned. /// /// If the underlying stream ended and only a partial vector was created, /// it will be returned. /// /// This method is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. /// /// # Panics /// /// This method will panic if `capacity` is zero. #[cfg(feature = "alloc")] fn ready_chunks(self, capacity: usize) -> ReadyChunks where Self: Sized, { assert_stream::, _>(ReadyChunks::new(self, capacity)) } /// A future that completes after the given stream has been fully processed /// into the sink and the sink has been flushed and closed. /// /// This future will drive the stream to keep producing items until it is /// exhausted, sending each item to the sink. It will complete once the /// stream is exhausted, the sink has received and flushed all items, and /// the sink is closed. Note that neither the original stream nor provided /// sink will be output by this future. Pass the sink by `Pin<&mut S>` /// (for example, via `forward(&mut sink)` inside an `async` fn/block) in /// order to preserve access to the `Sink`. If the stream produces an error, /// that error will be returned by this future without flushing/closing the sink. #[cfg(feature = "sink")] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] fn forward(self, sink: S) -> Forward where S: Sink, Self: TryStream + Sized, // Self: TryStream + Sized + Stream::Ok, ::Error>>, { // TODO: type mismatch resolving `::Item == std::result::Result<::Ok, ::Error>` // assert_future::, _>(Forward::new(self, sink)) Forward::new(self, sink) } /// Splits this `Stream + Sink` object into separate `Sink` and `Stream` /// objects. /// /// This can be useful when you want to split ownership between tasks, or /// allow direct interaction between the two objects (e.g. via /// `Sink::send_all`). /// /// This method is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. #[cfg(feature = "sink")] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] fn split(self) -> (SplitSink, SplitStream) where Self: Sink + Sized, { let (sink, stream) = split::split(self); ( crate::sink::assert_sink::(sink), assert_stream::(stream), ) } /// Do something with each item of this stream, afterwards passing it on. /// /// This is similar to the `Iterator::inspect` method in the standard /// library where it allows easily inspecting each value as it passes /// through the stream, for example to debug what's going on. fn inspect(self, f: F) -> Inspect where F: FnMut(&Self::Item), Self: Sized, { assert_stream::(Inspect::new(self, f)) } /// Wrap this stream in an `Either` stream, making it the left-hand variant /// of that `Either`. /// /// This can be used in combination with the `right_stream` method to write `if` /// statements that evaluate to different streams in different branches. fn left_stream(self) -> Either where B: Stream, Self: Sized, { assert_stream::(Either::Left(self)) } /// Wrap this stream in an `Either` stream, making it the right-hand variant /// of that `Either`. /// /// This can be used in combination with the `left_stream` method to write `if` /// statements that evaluate to different streams in different branches. fn right_stream(self) -> Either where B: Stream, Self: Sized, { assert_stream::(Either::Right(self)) } /// A convenience method for calling [`Stream::poll_next`] on [`Unpin`] /// stream types. fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll> where Self: Unpin, { Pin::new(self).poll_next(cx) } /// Returns a [`Future`] that resolves when the next item in this stream is /// ready. /// /// This is similar to the [`next`][StreamExt::next] method, but it won't /// resolve to [`None`] if used on an empty [`Stream`]. Instead, the /// returned future type will return `true` from /// [`FusedFuture::is_terminated`][] when the [`Stream`] is empty, allowing /// [`select_next_some`][StreamExt::select_next_some] to be easily used with /// the [`select!`] macro. /// /// If the future is polled after this [`Stream`] is empty it will panic. /// Using the future with a [`FusedFuture`][]-aware primitive like the /// [`select!`] macro will prevent this. /// /// [`FusedFuture`]: futures_core::future::FusedFuture /// [`FusedFuture::is_terminated`]: futures_core::future::FusedFuture::is_terminated /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::{future, select}; /// use futures::stream::{StreamExt, FuturesUnordered}; /// /// let mut fut = future::ready(1); /// let mut async_tasks = FuturesUnordered::new(); /// let mut total = 0; /// loop { /// select! { /// num = fut => { /// // First, the `ready` future completes. /// total += num; /// // Then we spawn a new task onto `async_tasks`, /// async_tasks.push(async { 5 }); /// }, /// // On the next iteration of the loop, the task we spawned /// // completes. /// num = async_tasks.select_next_some() => { /// total += num; /// } /// // Finally, both the `ready` future and `async_tasks` have /// // finished, so we enter the `complete` branch. /// complete => break, /// } /// } /// assert_eq!(total, 6); /// # }); /// ``` /// /// [`select!`]: crate::select fn select_next_some(&mut self) -> SelectNextSome<'_, Self> where Self: Unpin + FusedStream, { assert_future::(SelectNextSome::new(self)) } } futures-util-0.3.30/src/stream/stream/next.rs000064400000000000000000000017101046102023000172570ustar 00000000000000use crate::stream::StreamExt; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; /// Future for the [`next`](super::StreamExt::next) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Next<'a, St: ?Sized> { stream: &'a mut St, } impl Unpin for Next<'_, St> {} impl<'a, St: ?Sized + Stream + Unpin> Next<'a, St> { pub(super) fn new(stream: &'a mut St) -> Self { Self { stream } } } impl FusedFuture for Next<'_, St> { fn is_terminated(&self) -> bool { self.stream.is_terminated() } } impl Future for Next<'_, St> { type Output = Option; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { self.stream.poll_next_unpin(cx) } } futures-util-0.3.30/src/stream/stream/peek.rs000064400000000000000000000310101046102023000172210ustar 00000000000000use crate::fns::FnOnce1; use crate::stream::{Fuse, StreamExt}; use core::fmt; use core::marker::PhantomData; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// A `Stream` that implements a `peek` method. /// /// The `peek` method can be used to retrieve a reference /// to the next `Stream::Item` if available. A subsequent /// call to `poll` will return the owned item. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct Peekable { #[pin] stream: Fuse, peeked: Option, } } impl Peekable { pub(super) fn new(stream: St) -> Self { Self { stream: stream.fuse(), peeked: None } } delegate_access_inner!(stream, St, (.)); /// Produces a future which retrieves a reference to the next item /// in the stream, or `None` if the underlying stream terminates. pub fn peek(self: Pin<&mut Self>) -> Peek<'_, St> { Peek { inner: Some(self) } } /// Peek retrieves a reference to the next item in the stream. /// /// This method polls the underlying stream and return either a reference /// to the next item if the stream is ready or passes through any errors. pub fn poll_peek(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); Poll::Ready(loop { if this.peeked.is_some() { break this.peeked.as_ref(); } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { *this.peeked = Some(item); } else { break None; } }) } /// Produces a future which retrieves a mutable reference to the next item /// in the stream, or `None` if the underlying stream terminates. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// use futures::pin_mut; /// /// let stream = stream::iter(vec![1, 2, 3]).peekable(); /// pin_mut!(stream); /// /// assert_eq!(stream.as_mut().peek_mut().await, Some(&mut 1)); /// assert_eq!(stream.as_mut().next().await, Some(1)); /// /// // Peek into the stream and modify the value which will be returned next /// if let Some(p) = stream.as_mut().peek_mut().await { /// if *p == 2 { /// *p = 5; /// } /// } /// /// assert_eq!(stream.collect::>().await, vec![5, 3]); /// # }); /// ``` pub fn peek_mut(self: Pin<&mut Self>) -> PeekMut<'_, St> { PeekMut { inner: Some(self) } } /// Peek retrieves a mutable reference to the next item in the stream. pub fn poll_peek_mut( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll> { let mut this = self.project(); Poll::Ready(loop { if this.peeked.is_some() { break this.peeked.as_mut(); } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { *this.peeked = Some(item); } else { break None; } }) } /// Creates a future which will consume and return the next value of this /// stream if a condition is true. /// /// If `func` returns `true` for the next value of this stream, consume and /// return it. Otherwise, return `None`. /// /// # Examples /// /// Consume a number if it's equal to 0. /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// use futures::pin_mut; /// /// let stream = stream::iter(0..5).peekable(); /// pin_mut!(stream); /// // The first item of the stream is 0; consume it. /// assert_eq!(stream.as_mut().next_if(|&x| x == 0).await, Some(0)); /// // The next item returned is now 1, so `consume` will return `false`. /// assert_eq!(stream.as_mut().next_if(|&x| x == 0).await, None); /// // `next_if` saves the value of the next item if it was not equal to `expected`. /// assert_eq!(stream.next().await, Some(1)); /// # }); /// ``` /// /// Consume any number less than 10. /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// use futures::pin_mut; /// /// let stream = stream::iter(1..20).peekable(); /// pin_mut!(stream); /// // Consume all numbers less than 10 /// while stream.as_mut().next_if(|&x| x < 10).await.is_some() {} /// // The next value returned will be 10 /// assert_eq!(stream.next().await, Some(10)); /// # }); /// ``` pub fn next_if(self: Pin<&mut Self>, func: F) -> NextIf<'_, St, F> where F: FnOnce(&St::Item) -> bool, { NextIf { inner: Some((self, func)) } } /// Creates a future which will consume and return the next item if it is /// equal to `expected`. /// /// # Example /// /// Consume a number if it's equal to 0. /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// use futures::pin_mut; /// /// let stream = stream::iter(0..5).peekable(); /// pin_mut!(stream); /// // The first item of the stream is 0; consume it. /// assert_eq!(stream.as_mut().next_if_eq(&0).await, Some(0)); /// // The next item returned is now 1, so `consume` will return `false`. /// assert_eq!(stream.as_mut().next_if_eq(&0).await, None); /// // `next_if_eq` saves the value of the next item if it was not equal to `expected`. /// assert_eq!(stream.next().await, Some(1)); /// # }); /// ``` pub fn next_if_eq<'a, T>(self: Pin<&'a mut Self>, expected: &'a T) -> NextIfEq<'a, St, T> where T: ?Sized, St::Item: PartialEq, { NextIfEq { inner: NextIf { inner: Some((self, NextIfEqFn { expected, _next: PhantomData })) }, } } } impl FusedStream for Peekable { fn is_terminated(&self) -> bool { self.peeked.is_none() && self.stream.is_terminated() } } impl Stream for Peekable { type Item = S::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); if let Some(item) = this.peeked.take() { return Poll::Ready(Some(item)); } this.stream.poll_next(cx) } fn size_hint(&self) -> (usize, Option) { let peek_len = usize::from(self.peeked.is_some()); let (lower, upper) = self.stream.size_hint(); let lower = lower.saturating_add(peek_len); let upper = match upper { Some(x) => x.checked_add(peek_len), None => None, }; (lower, upper) } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for Peekable where S: Sink + Stream, { type Error = S::Error; delegate_sink!(stream, Item); } pin_project! { /// Future for the [`Peekable::peek`](self::Peekable::peek) method. #[must_use = "futures do nothing unless polled"] pub struct Peek<'a, St: Stream> { inner: Option>>, } } impl fmt::Debug for Peek<'_, St> where St: Stream + fmt::Debug, St::Item: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Peek").field("inner", &self.inner).finish() } } impl FusedFuture for Peek<'_, St> { fn is_terminated(&self) -> bool { self.inner.is_none() } } impl<'a, St> Future for Peek<'a, St> where St: Stream, { type Output = Option<&'a St::Item>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let inner = self.project().inner; if let Some(peekable) = inner { ready!(peekable.as_mut().poll_peek(cx)); inner.take().unwrap().poll_peek(cx) } else { panic!("Peek polled after completion") } } } pin_project! { /// Future for the [`Peekable::peek_mut`](self::Peekable::peek_mut) method. #[must_use = "futures do nothing unless polled"] pub struct PeekMut<'a, St: Stream> { inner: Option>>, } } impl fmt::Debug for PeekMut<'_, St> where St: Stream + fmt::Debug, St::Item: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("PeekMut").field("inner", &self.inner).finish() } } impl FusedFuture for PeekMut<'_, St> { fn is_terminated(&self) -> bool { self.inner.is_none() } } impl<'a, St> Future for PeekMut<'a, St> where St: Stream, { type Output = Option<&'a mut St::Item>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let inner = self.project().inner; if let Some(peekable) = inner { ready!(peekable.as_mut().poll_peek_mut(cx)); inner.take().unwrap().poll_peek_mut(cx) } else { panic!("PeekMut polled after completion") } } } pin_project! { /// Future for the [`Peekable::next_if`](self::Peekable::next_if) method. #[must_use = "futures do nothing unless polled"] pub struct NextIf<'a, St: Stream, F> { inner: Option<(Pin<&'a mut Peekable>, F)>, } } impl fmt::Debug for NextIf<'_, St, F> where St: Stream + fmt::Debug, St::Item: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("NextIf").field("inner", &self.inner.as_ref().map(|(s, _f)| s)).finish() } } #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 impl FusedFuture for NextIf<'_, St, F> where St: Stream, F: for<'a> FnOnce1<&'a St::Item, Output = bool>, { fn is_terminated(&self) -> bool { self.inner.is_none() } } #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058 impl Future for NextIf<'_, St, F> where St: Stream, F: for<'a> FnOnce1<&'a St::Item, Output = bool>, { type Output = Option; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let inner = self.project().inner; if let Some((peekable, _)) = inner { let res = ready!(peekable.as_mut().poll_next(cx)); let (peekable, func) = inner.take().unwrap(); match res { Some(ref matched) if func.call_once(matched) => Poll::Ready(res), other => { let peekable = peekable.project(); // Since we called `self.next()`, we consumed `self.peeked`. assert!(peekable.peeked.is_none()); *peekable.peeked = other; Poll::Ready(None) } } } else { panic!("NextIf polled after completion") } } } pin_project! { /// Future for the [`Peekable::next_if_eq`](self::Peekable::next_if_eq) method. #[must_use = "futures do nothing unless polled"] pub struct NextIfEq<'a, St: Stream, T: ?Sized> { #[pin] inner: NextIf<'a, St, NextIfEqFn<'a, T, St::Item>>, } } impl fmt::Debug for NextIfEq<'_, St, T> where St: Stream + fmt::Debug, St::Item: fmt::Debug, T: ?Sized, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("NextIfEq") .field("inner", &self.inner.inner.as_ref().map(|(s, _f)| s)) .finish() } } impl FusedFuture for NextIfEq<'_, St, T> where St: Stream, T: ?Sized, St::Item: PartialEq, { fn is_terminated(&self) -> bool { self.inner.is_terminated() } } impl Future for NextIfEq<'_, St, T> where St: Stream, T: ?Sized, St::Item: PartialEq, { type Output = Option; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { self.project().inner.poll(cx) } } struct NextIfEqFn<'a, T: ?Sized, Item> { expected: &'a T, _next: PhantomData, } impl FnOnce1<&Item> for NextIfEqFn<'_, T, Item> where T: ?Sized, Item: PartialEq, { type Output = bool; fn call_once(self, next: &Item) -> Self::Output { next == self.expected } } futures-util-0.3.30/src/stream/stream/ready_chunks.rs000064400000000000000000000054521046102023000207670ustar 00000000000000use crate::stream::{Fuse, StreamExt}; use alloc::vec::Vec; use core::pin::Pin; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`ready_chunks`](super::StreamExt::ready_chunks) method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct ReadyChunks { #[pin] stream: Fuse, cap: usize, // https://github.com/rust-lang/futures-rs/issues/1475 } } impl ReadyChunks { pub(super) fn new(stream: St, capacity: usize) -> Self { assert!(capacity > 0); Self { stream: stream.fuse(), cap: capacity } } delegate_access_inner!(stream, St, (.)); } impl Stream for ReadyChunks { type Item = Vec; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); let mut items: Vec = Vec::new(); loop { match this.stream.as_mut().poll_next(cx) { // Flush all collected data if underlying stream doesn't contain // more ready values Poll::Pending => { return if items.is_empty() { Poll::Pending } else { Poll::Ready(Some(items)) } } // Push the ready item into the buffer and check whether it is full. // If so, replace our buffer with a new and empty one and return // the full one. Poll::Ready(Some(item)) => { if items.is_empty() { items.reserve(*this.cap); } items.push(item); if items.len() >= *this.cap { return Poll::Ready(Some(items)); } } // Since the underlying stream ran out of values, return what we // have buffered, if we have anything. Poll::Ready(None) => { let last = if items.is_empty() { None } else { Some(items) }; return Poll::Ready(last); } } } } fn size_hint(&self) -> (usize, Option) { let (lower, upper) = self.stream.size_hint(); let lower = lower / self.cap; (lower, upper) } } impl FusedStream for ReadyChunks { fn is_terminated(&self) -> bool { self.stream.is_terminated() } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for ReadyChunks where S: Stream + Sink, { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/stream/scan.rs000064400000000000000000000065261046102023000172370ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::Future; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; struct StateFn { state: S, f: F, } pin_project! { /// Stream for the [`scan`](super::StreamExt::scan) method. #[must_use = "streams do nothing unless polled"] pub struct Scan { #[pin] stream: St, state_f: Option>, #[pin] future: Option, } } impl fmt::Debug for Scan where St: Stream + fmt::Debug, St::Item: fmt::Debug, S: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Scan") .field("stream", &self.stream) .field("state", &self.state_f.as_ref().map(|s| &s.state)) .field("future", &self.future) .field("done_taking", &self.is_done_taking()) .finish() } } impl Scan { /// Checks if internal state is `None`. fn is_done_taking(&self) -> bool { self.state_f.is_none() } } impl Scan where St: Stream, F: FnMut(&mut S, St::Item) -> Fut, Fut: Future>, { pub(super) fn new(stream: St, initial_state: S, f: F) -> Self { Self { stream, state_f: Some(StateFn { state: initial_state, f }), future: None } } delegate_access_inner!(stream, St, ()); } impl Stream for Scan where St: Stream, F: FnMut(&mut S, St::Item) -> Fut, Fut: Future>, { type Item = B; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { if self.is_done_taking() { return Poll::Ready(None); } let mut this = self.project(); Poll::Ready(loop { if let Some(fut) = this.future.as_mut().as_pin_mut() { let item = ready!(fut.poll(cx)); this.future.set(None); if item.is_none() { *this.state_f = None; } break item; } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { let state_f = this.state_f.as_mut().unwrap(); this.future.set(Some((state_f.f)(&mut state_f.state, item))) } else { break None; } }) } fn size_hint(&self) -> (usize, Option) { if self.is_done_taking() { (0, Some(0)) } else { self.stream.size_hint() // can't know a lower bound, due to the predicate } } } impl FusedStream for Scan where St: FusedStream, F: FnMut(&mut S, St::Item) -> Fut, Fut: Future>, { fn is_terminated(&self) -> bool { self.is_done_taking() || self.future.is_none() && self.stream.is_terminated() } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for Scan where St: Stream + Sink, { type Error = St::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/stream/select_next_some.rs000064400000000000000000000023741046102023000216500ustar 00000000000000use crate::stream::StreamExt; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; use futures_core::stream::FusedStream; use futures_core::task::{Context, Poll}; /// Future for the [`select_next_some`](super::StreamExt::select_next_some) /// method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct SelectNextSome<'a, St: ?Sized> { stream: &'a mut St, } impl<'a, St: ?Sized> SelectNextSome<'a, St> { pub(super) fn new(stream: &'a mut St) -> Self { Self { stream } } } impl FusedFuture for SelectNextSome<'_, St> { fn is_terminated(&self) -> bool { self.stream.is_terminated() } } impl Future for SelectNextSome<'_, St> { type Output = St::Item; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { assert!(!self.stream.is_terminated(), "SelectNextSome polled after terminated"); if let Some(item) = ready!(self.stream.poll_next_unpin(cx)) { Poll::Ready(item) } else { debug_assert!(self.stream.is_terminated()); cx.waker().wake_by_ref(); Poll::Pending } } } futures-util-0.3.30/src/stream/stream/skip.rs000064400000000000000000000032761046102023000172600ustar 00000000000000use core::pin::Pin; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`skip`](super::StreamExt::skip) method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct Skip { #[pin] stream: St, remaining: usize, } } impl Skip { pub(super) fn new(stream: St, n: usize) -> Self { Self { stream, remaining: n } } delegate_access_inner!(stream, St, ()); } impl FusedStream for Skip { fn is_terminated(&self) -> bool { self.stream.is_terminated() } } impl Stream for Skip { type Item = St::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); while *this.remaining > 0 { if ready!(this.stream.as_mut().poll_next(cx)).is_some() { *this.remaining -= 1; } else { return Poll::Ready(None); } } this.stream.poll_next(cx) } fn size_hint(&self) -> (usize, Option) { let (lower, upper) = self.stream.size_hint(); let lower = lower.saturating_sub(self.remaining); let upper = upper.map(|x| x.saturating_sub(self.remaining)); (lower, upper) } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for Skip where S: Stream + Sink, { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/stream/skip_while.rs000064400000000000000000000067121046102023000204460ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::Future; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`skip_while`](super::StreamExt::skip_while) method. #[must_use = "streams do nothing unless polled"] pub struct SkipWhile where St: Stream { #[pin] stream: St, f: F, #[pin] pending_fut: Option, pending_item: Option, done_skipping: bool, } } impl fmt::Debug for SkipWhile where St: Stream + fmt::Debug, St::Item: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("SkipWhile") .field("stream", &self.stream) .field("pending_fut", &self.pending_fut) .field("pending_item", &self.pending_item) .field("done_skipping", &self.done_skipping) .finish() } } impl SkipWhile where St: Stream, F: FnMut(&St::Item) -> Fut, Fut: Future, { pub(super) fn new(stream: St, f: F) -> Self { Self { stream, f, pending_fut: None, pending_item: None, done_skipping: false } } delegate_access_inner!(stream, St, ()); } impl FusedStream for SkipWhile where St: FusedStream, F: FnMut(&St::Item) -> Fut, Fut: Future, { fn is_terminated(&self) -> bool { self.pending_item.is_none() && self.stream.is_terminated() } } impl Stream for SkipWhile where St: Stream, F: FnMut(&St::Item) -> Fut, Fut: Future, { type Item = St::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); if *this.done_skipping { return this.stream.poll_next(cx); } Poll::Ready(loop { if let Some(fut) = this.pending_fut.as_mut().as_pin_mut() { let skipped = ready!(fut.poll(cx)); let item = this.pending_item.take(); this.pending_fut.set(None); if !skipped { *this.done_skipping = true; break item; } } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { this.pending_fut.set(Some((this.f)(&item))); *this.pending_item = Some(item); } else { break None; } }) } fn size_hint(&self) -> (usize, Option) { if self.done_skipping { self.stream.size_hint() } else { let pending_len = usize::from(self.pending_item.is_some()); let (_, upper) = self.stream.size_hint(); let upper = match upper { Some(x) => x.checked_add(pending_len), None => None, }; (0, upper) // can't know a lower bound, due to the predicate } } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for SkipWhile where S: Stream + Sink, F: FnMut(&S::Item) -> Fut, Fut: Future, { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/stream/split.rs000064400000000000000000000156221046102023000174430ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::ready; use futures_core::stream::Stream; use futures_core::task::{Context, Poll}; use futures_sink::Sink; use crate::lock::BiLock; /// A `Stream` part of the split pair #[derive(Debug)] #[must_use = "streams do nothing unless polled"] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] pub struct SplitStream(BiLock); impl Unpin for SplitStream {} impl SplitStream { /// Returns `true` if the `SplitStream` and `SplitSink` originate from the same call to `StreamExt::split`. pub fn is_pair_of(&self, other: &SplitSink) -> bool { other.is_pair_of(&self) } } impl SplitStream { /// Attempts to put the two "halves" of a split `Stream + Sink` back /// together. Succeeds only if the `SplitStream` and `SplitSink` are /// a matching pair originating from the same call to `StreamExt::split`. pub fn reunite(self, other: SplitSink) -> Result> where S: Sink, { other.reunite(self) } } impl Stream for SplitStream { type Item = S::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { ready!(self.0.poll_lock(cx)).as_pin_mut().poll_next(cx) } } #[allow(non_snake_case)] fn SplitSink, Item>(lock: BiLock) -> SplitSink { SplitSink { lock, slot: None } } /// A `Sink` part of the split pair #[derive(Debug)] #[must_use = "sinks do nothing unless polled"] #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] pub struct SplitSink { lock: BiLock, slot: Option, } impl Unpin for SplitSink {} impl + Unpin, Item> SplitSink { /// Attempts to put the two "halves" of a split `Stream + Sink` back /// together. Succeeds only if the `SplitStream` and `SplitSink` are /// a matching pair originating from the same call to `StreamExt::split`. pub fn reunite(self, other: SplitStream) -> Result> { self.lock.reunite(other.0).map_err(|err| ReuniteError(SplitSink(err.0), SplitStream(err.1))) } } impl SplitSink { /// Returns `true` if the `SplitStream` and `SplitSink` originate from the same call to `StreamExt::split`. pub fn is_pair_of(&self, other: &SplitStream) -> bool { self.lock.is_pair_of(&other.0) } } impl, Item> SplitSink { fn poll_flush_slot( mut inner: Pin<&mut S>, slot: &mut Option, cx: &mut Context<'_>, ) -> Poll> { if slot.is_some() { ready!(inner.as_mut().poll_ready(cx))?; Poll::Ready(inner.start_send(slot.take().unwrap())) } else { Poll::Ready(Ok(())) } } fn poll_lock_and_flush_slot( mut self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll> { let this = &mut *self; let mut inner = ready!(this.lock.poll_lock(cx)); Self::poll_flush_slot(inner.as_pin_mut(), &mut this.slot, cx) } } impl, Item> Sink for SplitSink { type Error = S::Error; fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { loop { if self.slot.is_none() { return Poll::Ready(Ok(())); } ready!(self.as_mut().poll_lock_and_flush_slot(cx))?; } } fn start_send(mut self: Pin<&mut Self>, item: Item) -> Result<(), S::Error> { self.slot = Some(item); Ok(()) } fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = &mut *self; let mut inner = ready!(this.lock.poll_lock(cx)); ready!(Self::poll_flush_slot(inner.as_pin_mut(), &mut this.slot, cx))?; inner.as_pin_mut().poll_flush(cx) } fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = &mut *self; let mut inner = ready!(this.lock.poll_lock(cx)); ready!(Self::poll_flush_slot(inner.as_pin_mut(), &mut this.slot, cx))?; inner.as_pin_mut().poll_close(cx) } } pub(super) fn split, Item>(s: S) -> (SplitSink, SplitStream) { let (a, b) = BiLock::new(s); let read = SplitStream(a); let write = SplitSink(b); (write, read) } /// Error indicating a `SplitSink` and `SplitStream` were not two halves /// of a `Stream + Split`, and thus could not be `reunite`d. #[cfg_attr(docsrs, doc(cfg(feature = "sink")))] pub struct ReuniteError(pub SplitSink, pub SplitStream); impl fmt::Debug for ReuniteError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("ReuniteError").field(&"...").finish() } } impl fmt::Display for ReuniteError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "tried to reunite a SplitStream and SplitSink that don't form a pair") } } #[cfg(feature = "std")] impl std::error::Error for ReuniteError {} #[cfg(test)] mod tests { use super::*; use crate::{sink::Sink, stream::StreamExt}; use core::marker::PhantomData; struct NopStream { phantom: PhantomData, } impl Stream for NopStream { type Item = Item; fn poll_next(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { todo!() } } impl Sink for NopStream { type Error = (); fn poll_ready( self: Pin<&mut Self>, _cx: &mut Context<'_>, ) -> Poll> { todo!() } fn start_send(self: Pin<&mut Self>, _item: Item) -> Result<(), Self::Error> { todo!() } fn poll_flush( self: Pin<&mut Self>, _cx: &mut Context<'_>, ) -> Poll> { todo!() } fn poll_close( self: Pin<&mut Self>, _cx: &mut Context<'_>, ) -> Poll> { todo!() } } #[test] fn test_pairing() { let s1 = NopStream::<()> { phantom: PhantomData }; let (sink1, stream1) = s1.split(); assert!(sink1.is_pair_of(&stream1)); assert!(stream1.is_pair_of(&sink1)); let s2 = NopStream::<()> { phantom: PhantomData }; let (sink2, stream2) = s2.split(); assert!(sink2.is_pair_of(&stream2)); assert!(stream2.is_pair_of(&sink2)); assert!(!sink1.is_pair_of(&stream2)); assert!(!stream1.is_pair_of(&sink2)); assert!(!sink2.is_pair_of(&stream1)); assert!(!stream2.is_pair_of(&sink1)); } } futures-util-0.3.30/src/stream/stream/take.rs000064400000000000000000000037031046102023000172310ustar 00000000000000use core::cmp; use core::pin::Pin; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`take`](super::StreamExt::take) method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct Take { #[pin] stream: St, remaining: usize, } } impl Take { pub(super) fn new(stream: St, n: usize) -> Self { Self { stream, remaining: n } } delegate_access_inner!(stream, St, ()); } impl Stream for Take where St: Stream, { type Item = St::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { if self.remaining == 0 { Poll::Ready(None) } else { let this = self.project(); let next = ready!(this.stream.poll_next(cx)); if next.is_some() { *this.remaining -= 1; } else { *this.remaining = 0; } Poll::Ready(next) } } fn size_hint(&self) -> (usize, Option) { if self.remaining == 0 { return (0, Some(0)); } let (lower, upper) = self.stream.size_hint(); let lower = cmp::min(lower, self.remaining); let upper = match upper { Some(x) if x < self.remaining => Some(x), _ => Some(self.remaining), }; (lower, upper) } } impl FusedStream for Take where St: FusedStream, { fn is_terminated(&self) -> bool { self.remaining == 0 || self.stream.is_terminated() } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for Take where S: Stream + Sink, { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/stream/take_until.rs000064400000000000000000000112171046102023000204430ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::Future; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; // FIXME: docs, tests pin_project! { /// Stream for the [`take_until`](super::StreamExt::take_until) method. #[must_use = "streams do nothing unless polled"] pub struct TakeUntil { #[pin] stream: St, // Contains the inner Future on start and None once the inner Future is resolved // or taken out by the user. #[pin] fut: Option, // Contains fut's return value once fut is resolved fut_result: Option, // Whether the future was taken out by the user. free: bool, } } impl fmt::Debug for TakeUntil where St: Stream + fmt::Debug, St::Item: fmt::Debug, Fut: Future + fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TakeUntil").field("stream", &self.stream).field("fut", &self.fut).finish() } } impl TakeUntil where St: Stream, Fut: Future, { pub(super) fn new(stream: St, fut: Fut) -> Self { Self { stream, fut: Some(fut), fut_result: None, free: false } } delegate_access_inner!(stream, St, ()); /// Extract the stopping future out of the combinator. /// The future is returned only if it isn't resolved yet, ie. if the stream isn't stopped yet. /// Taking out the future means the combinator will be yielding /// elements from the wrapped stream without ever stopping it. pub fn take_future(&mut self) -> Option { if self.fut.is_some() { self.free = true; } self.fut.take() } /// Once the stopping future is resolved, this method can be used /// to extract the value returned by the stopping future. /// /// This may be used to retrieve arbitrary data from the stopping /// future, for example a reason why the stream was stopped. /// /// This method will return `None` if the future isn't resolved yet, /// or if the result was already taken out. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// use futures::stream::{self, StreamExt}; /// use futures::task::Poll; /// /// let stream = stream::iter(1..=10); /// /// let mut i = 0; /// let stop_fut = future::poll_fn(|_cx| { /// i += 1; /// if i <= 5 { /// Poll::Pending /// } else { /// Poll::Ready("reason") /// } /// }); /// /// let mut stream = stream.take_until(stop_fut); /// let _ = stream.by_ref().collect::>().await; /// /// let result = stream.take_result().unwrap(); /// assert_eq!(result, "reason"); /// # }); /// ``` pub fn take_result(&mut self) -> Option { self.fut_result.take() } /// Whether the stream was stopped yet by the stopping future /// being resolved. pub fn is_stopped(&self) -> bool { !self.free && self.fut.is_none() } } impl Stream for TakeUntil where St: Stream, Fut: Future, { type Item = St::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); if let Some(f) = this.fut.as_mut().as_pin_mut() { if let Poll::Ready(result) = f.poll(cx) { this.fut.set(None); *this.fut_result = Some(result); } } if !*this.free && this.fut.is_none() { // Future resolved, inner stream stopped Poll::Ready(None) } else { // Future either not resolved yet or taken out by the user let item = ready!(this.stream.poll_next(cx)); if item.is_none() { this.fut.set(None); } Poll::Ready(item) } } fn size_hint(&self) -> (usize, Option) { if self.is_stopped() { return (0, Some(0)); } self.stream.size_hint() } } impl FusedStream for TakeUntil where St: Stream, Fut: Future, { fn is_terminated(&self) -> bool { self.is_stopped() } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for TakeUntil where S: Stream + Sink, Fut: Future, { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/stream/take_while.rs000064400000000000000000000066021046102023000204220ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::Future; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`take_while`](super::StreamExt::take_while) method. #[must_use = "streams do nothing unless polled"] pub struct TakeWhile { #[pin] stream: St, f: F, #[pin] pending_fut: Option, pending_item: Option, done_taking: bool, } } impl fmt::Debug for TakeWhile where St: Stream + fmt::Debug, St::Item: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TakeWhile") .field("stream", &self.stream) .field("pending_fut", &self.pending_fut) .field("pending_item", &self.pending_item) .field("done_taking", &self.done_taking) .finish() } } impl TakeWhile where St: Stream, F: FnMut(&St::Item) -> Fut, Fut: Future, { pub(super) fn new(stream: St, f: F) -> Self { Self { stream, f, pending_fut: None, pending_item: None, done_taking: false } } delegate_access_inner!(stream, St, ()); } impl Stream for TakeWhile where St: Stream, F: FnMut(&St::Item) -> Fut, Fut: Future, { type Item = St::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { if self.done_taking { return Poll::Ready(None); } let mut this = self.project(); Poll::Ready(loop { if let Some(fut) = this.pending_fut.as_mut().as_pin_mut() { let take = ready!(fut.poll(cx)); let item = this.pending_item.take(); this.pending_fut.set(None); if take { break item; } else { *this.done_taking = true; break None; } } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { this.pending_fut.set(Some((this.f)(&item))); *this.pending_item = Some(item); } else { break None; } }) } fn size_hint(&self) -> (usize, Option) { if self.done_taking { return (0, Some(0)); } let pending_len = usize::from(self.pending_item.is_some()); let (_, upper) = self.stream.size_hint(); let upper = match upper { Some(x) => x.checked_add(pending_len), None => None, }; (0, upper) // can't know a lower bound, due to the predicate } } impl FusedStream for TakeWhile where St: FusedStream, F: FnMut(&St::Item) -> Fut, Fut: Future, { fn is_terminated(&self) -> bool { self.done_taking || self.pending_item.is_none() && self.stream.is_terminated() } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for TakeWhile where S: Stream + Sink, { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/stream/then.rs000064400000000000000000000050331046102023000172410ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::Future; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`then`](super::StreamExt::then) method. #[must_use = "streams do nothing unless polled"] pub struct Then { #[pin] stream: St, #[pin] future: Option, f: F, } } impl fmt::Debug for Then where St: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Then").field("stream", &self.stream).field("future", &self.future).finish() } } impl Then where St: Stream, F: FnMut(St::Item) -> Fut, { pub(super) fn new(stream: St, f: F) -> Self { Self { stream, future: None, f } } delegate_access_inner!(stream, St, ()); } impl FusedStream for Then where St: FusedStream, F: FnMut(St::Item) -> Fut, Fut: Future, { fn is_terminated(&self) -> bool { self.future.is_none() && self.stream.is_terminated() } } impl Stream for Then where St: Stream, F: FnMut(St::Item) -> Fut, Fut: Future, { type Item = Fut::Output; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); Poll::Ready(loop { if let Some(fut) = this.future.as_mut().as_pin_mut() { let item = ready!(fut.poll(cx)); this.future.set(None); break Some(item); } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { this.future.set(Some((this.f)(item))); } else { break None; } }) } fn size_hint(&self) -> (usize, Option) { let future_len = usize::from(self.future.is_some()); let (lower, upper) = self.stream.size_hint(); let lower = lower.saturating_add(future_len); let upper = match upper { Some(x) => x.checked_add(future_len), None => None, }; (lower, upper) } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for Then where S: Sink, { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/stream/unzip.rs000064400000000000000000000034151046102023000174520ustar 00000000000000use core::mem; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`unzip`](super::StreamExt::unzip) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Unzip { #[pin] stream: St, left: FromA, right: FromB, } } impl Unzip { fn finish(self: Pin<&mut Self>) -> (FromA, FromB) { let this = self.project(); (mem::take(this.left), mem::take(this.right)) } pub(super) fn new(stream: St) -> Self { Self { stream, left: Default::default(), right: Default::default() } } } impl FusedFuture for Unzip where St: FusedStream, FromA: Default + Extend, FromB: Default + Extend, { fn is_terminated(&self) -> bool { self.stream.is_terminated() } } impl Future for Unzip where St: Stream, FromA: Default + Extend, FromB: Default + Extend, { type Output = (FromA, FromB); fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<(FromA, FromB)> { let mut this = self.as_mut().project(); loop { match ready!(this.stream.as_mut().poll_next(cx)) { Some(e) => { this.left.extend(Some(e.0)); this.right.extend(Some(e.1)); } None => return Poll::Ready(self.finish()), } } } } futures-util-0.3.30/src/stream/stream/zip.rs000064400000000000000000000105031046102023000171030ustar 00000000000000use crate::stream::{Fuse, StreamExt}; use core::cmp; use core::pin::Pin; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`zip`](super::StreamExt::zip) method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct Zip { #[pin] stream1: Fuse, #[pin] stream2: Fuse, queued1: Option, queued2: Option, } } impl Zip { pub(super) fn new(stream1: St1, stream2: St2) -> Self { Self { stream1: stream1.fuse(), stream2: stream2.fuse(), queued1: None, queued2: None } } /// Acquires a reference to the underlying streams that this combinator is /// pulling from. pub fn get_ref(&self) -> (&St1, &St2) { (self.stream1.get_ref(), self.stream2.get_ref()) } /// Acquires a mutable reference to the underlying streams that this /// combinator is pulling from. /// /// Note that care must be taken to avoid tampering with the state of the /// stream which may otherwise confuse this combinator. pub fn get_mut(&mut self) -> (&mut St1, &mut St2) { (self.stream1.get_mut(), self.stream2.get_mut()) } /// Acquires a pinned mutable reference to the underlying streams that this /// combinator is pulling from. /// /// Note that care must be taken to avoid tampering with the state of the /// stream which may otherwise confuse this combinator. pub fn get_pin_mut(self: Pin<&mut Self>) -> (Pin<&mut St1>, Pin<&mut St2>) { let this = self.project(); (this.stream1.get_pin_mut(), this.stream2.get_pin_mut()) } /// Consumes this combinator, returning the underlying streams. /// /// Note that this may discard intermediate state of this combinator, so /// care should be taken to avoid losing resources when this is called. pub fn into_inner(self) -> (St1, St2) { (self.stream1.into_inner(), self.stream2.into_inner()) } } impl FusedStream for Zip where St1: Stream, St2: Stream, { fn is_terminated(&self) -> bool { self.stream1.is_terminated() && self.stream2.is_terminated() } } impl Stream for Zip where St1: Stream, St2: Stream, { type Item = (St1::Item, St2::Item); fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); if this.queued1.is_none() { match this.stream1.as_mut().poll_next(cx) { Poll::Ready(Some(item1)) => *this.queued1 = Some(item1), Poll::Ready(None) | Poll::Pending => {} } } if this.queued2.is_none() { match this.stream2.as_mut().poll_next(cx) { Poll::Ready(Some(item2)) => *this.queued2 = Some(item2), Poll::Ready(None) | Poll::Pending => {} } } if this.queued1.is_some() && this.queued2.is_some() { let pair = (this.queued1.take().unwrap(), this.queued2.take().unwrap()); Poll::Ready(Some(pair)) } else if this.stream1.is_done() || this.stream2.is_done() { Poll::Ready(None) } else { Poll::Pending } } fn size_hint(&self) -> (usize, Option) { let queued1_len = usize::from(self.queued1.is_some()); let queued2_len = usize::from(self.queued2.is_some()); let (stream1_lower, stream1_upper) = self.stream1.size_hint(); let (stream2_lower, stream2_upper) = self.stream2.size_hint(); let stream1_lower = stream1_lower.saturating_add(queued1_len); let stream2_lower = stream2_lower.saturating_add(queued2_len); let lower = cmp::min(stream1_lower, stream2_lower); let upper = match (stream1_upper, stream2_upper) { (Some(x), Some(y)) => { let x = x.saturating_add(queued1_len); let y = y.saturating_add(queued2_len); Some(cmp::min(x, y)) } (Some(x), None) => x.checked_add(queued1_len), (None, Some(y)) => y.checked_add(queued2_len), (None, None) => None, }; (lower, upper) } } futures-util-0.3.30/src/stream/try_stream/and_then.rs000064400000000000000000000053471046102023000207710ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::TryFuture; use futures_core::ready; use futures_core::stream::{FusedStream, Stream, TryStream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`and_then`](super::TryStreamExt::and_then) method. #[must_use = "streams do nothing unless polled"] pub struct AndThen { #[pin] stream: St, #[pin] future: Option, f: F, } } impl fmt::Debug for AndThen where St: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("AndThen") .field("stream", &self.stream) .field("future", &self.future) .finish() } } impl AndThen where St: TryStream, F: FnMut(St::Ok) -> Fut, Fut: TryFuture, { pub(super) fn new(stream: St, f: F) -> Self { Self { stream, future: None, f } } delegate_access_inner!(stream, St, ()); } impl Stream for AndThen where St: TryStream, F: FnMut(St::Ok) -> Fut, Fut: TryFuture, { type Item = Result; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); Poll::Ready(loop { if let Some(fut) = this.future.as_mut().as_pin_mut() { let item = ready!(fut.try_poll(cx)); this.future.set(None); break Some(item); } else if let Some(item) = ready!(this.stream.as_mut().try_poll_next(cx)?) { this.future.set(Some((this.f)(item))); } else { break None; } }) } fn size_hint(&self) -> (usize, Option) { let future_len = usize::from(self.future.is_some()); let (lower, upper) = self.stream.size_hint(); let lower = lower.saturating_add(future_len); let upper = match upper { Some(x) => x.checked_add(future_len), None => None, }; (lower, upper) } } impl FusedStream for AndThen where St: TryStream + FusedStream, F: FnMut(St::Ok) -> Fut, Fut: TryFuture, { fn is_terminated(&self) -> bool { self.future.is_none() && self.stream.is_terminated() } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for AndThen where S: Sink, { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/try_stream/into_async_read.rs000064400000000000000000000120111046102023000223340ustar 00000000000000use core::pin::Pin; use futures_core::ready; use futures_core::stream::TryStream; use futures_core::task::{Context, Poll}; use futures_io::{AsyncBufRead, AsyncRead, AsyncWrite}; use pin_project_lite::pin_project; use std::cmp; use std::io::{Error, Result}; pin_project! { /// Reader for the [`into_async_read`](super::TryStreamExt::into_async_read) method. #[derive(Debug)] #[must_use = "readers do nothing unless polled"] #[cfg_attr(docsrs, doc(cfg(feature = "io")))] pub struct IntoAsyncRead where St: TryStream, St::Ok: AsRef<[u8]>, { #[pin] stream: St, state: ReadState, } } #[derive(Debug)] enum ReadState> { Ready { chunk: T, chunk_start: usize }, PendingChunk, Eof, } impl IntoAsyncRead where St: TryStream, St::Ok: AsRef<[u8]>, { pub(super) fn new(stream: St) -> Self { Self { stream, state: ReadState::PendingChunk } } } impl AsyncRead for IntoAsyncRead where St: TryStream, St::Ok: AsRef<[u8]>, { fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll> { let mut this = self.project(); loop { match this.state { ReadState::Ready { chunk, chunk_start } => { let chunk = chunk.as_ref(); let len = cmp::min(buf.len(), chunk.len() - *chunk_start); buf[..len].copy_from_slice(&chunk[*chunk_start..*chunk_start + len]); *chunk_start += len; if chunk.len() == *chunk_start { *this.state = ReadState::PendingChunk; } return Poll::Ready(Ok(len)); } ReadState::PendingChunk => match ready!(this.stream.as_mut().try_poll_next(cx)) { Some(Ok(chunk)) => { if !chunk.as_ref().is_empty() { *this.state = ReadState::Ready { chunk, chunk_start: 0 }; } } Some(Err(err)) => { *this.state = ReadState::Eof; return Poll::Ready(Err(err)); } None => { *this.state = ReadState::Eof; return Poll::Ready(Ok(0)); } }, ReadState::Eof => { return Poll::Ready(Ok(0)); } } } } } impl AsyncWrite for IntoAsyncRead where St: TryStream + AsyncWrite, St::Ok: AsRef<[u8]>, { fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll> { let this = self.project(); this.stream.poll_write(cx, buf) } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); this.stream.poll_flush(cx) } fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); this.stream.poll_close(cx) } } impl AsyncBufRead for IntoAsyncRead where St: TryStream, St::Ok: AsRef<[u8]>, { fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); while let ReadState::PendingChunk = this.state { match ready!(this.stream.as_mut().try_poll_next(cx)) { Some(Ok(chunk)) => { if !chunk.as_ref().is_empty() { *this.state = ReadState::Ready { chunk, chunk_start: 0 }; } } Some(Err(err)) => { *this.state = ReadState::Eof; return Poll::Ready(Err(err)); } None => { *this.state = ReadState::Eof; return Poll::Ready(Ok(&[])); } } } if let &mut ReadState::Ready { ref chunk, chunk_start } = this.state { let chunk = chunk.as_ref(); return Poll::Ready(Ok(&chunk[chunk_start..])); } // To get to this point we must be in ReadState::Eof Poll::Ready(Ok(&[])) } fn consume(self: Pin<&mut Self>, amount: usize) { let this = self.project(); // https://github.com/rust-lang/futures-rs/pull/1556#discussion_r281644295 if amount == 0 { return; } if let ReadState::Ready { chunk, chunk_start } = this.state { *chunk_start += amount; debug_assert!(*chunk_start <= chunk.as_ref().len()); if *chunk_start >= chunk.as_ref().len() { *this.state = ReadState::PendingChunk; } } else { debug_assert!(false, "Attempted to consume from IntoAsyncRead without chunk"); } } } futures-util-0.3.30/src/stream/try_stream/into_stream.rs000064400000000000000000000024351046102023000215300ustar 00000000000000use core::pin::Pin; use futures_core::stream::{FusedStream, Stream, TryStream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`into_stream`](super::TryStreamExt::into_stream) method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct IntoStream { #[pin] stream: St, } } impl IntoStream { #[inline] pub(super) fn new(stream: St) -> Self { Self { stream } } delegate_access_inner!(stream, St, ()); } impl FusedStream for IntoStream { fn is_terminated(&self) -> bool { self.stream.is_terminated() } } impl Stream for IntoStream { type Item = Result; #[inline] fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.project().stream.try_poll_next(cx) } fn size_hint(&self) -> (usize, Option) { self.stream.size_hint() } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl, Item> Sink for IntoStream { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/try_stream/mod.rs000064400000000000000000001316441046102023000177700ustar 00000000000000//! Streams //! //! This module contains a number of functions for working with `Streams`s //! that return `Result`s, allowing for short-circuiting computations. #[cfg(feature = "compat")] use crate::compat::Compat; use crate::fns::{ inspect_err_fn, inspect_ok_fn, into_fn, map_err_fn, map_ok_fn, InspectErrFn, InspectOkFn, IntoFn, MapErrFn, MapOkFn, }; use crate::future::assert_future; use crate::stream::assert_stream; use crate::stream::{Inspect, Map}; #[cfg(feature = "alloc")] use alloc::vec::Vec; use core::pin::Pin; use futures_core::{ future::{Future, TryFuture}, stream::TryStream, task::{Context, Poll}, }; mod and_then; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::and_then::AndThen; delegate_all!( /// Stream for the [`err_into`](super::TryStreamExt::err_into) method. ErrInto( MapErr> ): Debug + Sink + Stream + FusedStream + AccessInner[St, (.)] + New[|x: St| MapErr::new(x, into_fn())] ); delegate_all!( /// Stream for the [`inspect_ok`](super::TryStreamExt::inspect_ok) method. InspectOk( Inspect, InspectOkFn> ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + New[|x: St, f: F| Inspect::new(IntoStream::new(x), inspect_ok_fn(f))] ); delegate_all!( /// Stream for the [`inspect_err`](super::TryStreamExt::inspect_err) method. InspectErr( Inspect, InspectErrFn> ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + New[|x: St, f: F| Inspect::new(IntoStream::new(x), inspect_err_fn(f))] ); mod into_stream; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::into_stream::IntoStream; delegate_all!( /// Stream for the [`map_ok`](super::TryStreamExt::map_ok) method. MapOk( Map, MapOkFn> ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + New[|x: St, f: F| Map::new(IntoStream::new(x), map_ok_fn(f))] ); delegate_all!( /// Stream for the [`map_err`](super::TryStreamExt::map_err) method. MapErr( Map, MapErrFn> ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + New[|x: St, f: F| Map::new(IntoStream::new(x), map_err_fn(f))] ); mod or_else; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::or_else::OrElse; mod try_next; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_next::TryNext; mod try_for_each; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_for_each::TryForEach; mod try_filter; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_filter::TryFilter; mod try_filter_map; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_filter_map::TryFilterMap; mod try_flatten; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_flatten::TryFlatten; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] mod try_flatten_unordered; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_flatten_unordered::TryFlattenUnordered; mod try_collect; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_collect::TryCollect; mod try_concat; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_concat::TryConcat; #[cfg(feature = "alloc")] mod try_chunks; #[cfg(feature = "alloc")] #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_chunks::{TryChunks, TryChunksError}; #[cfg(feature = "alloc")] mod try_ready_chunks; #[cfg(feature = "alloc")] #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_ready_chunks::{TryReadyChunks, TryReadyChunksError}; mod try_fold; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_fold::TryFold; mod try_unfold; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_unfold::{try_unfold, TryUnfold}; mod try_skip_while; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_skip_while::TrySkipWhile; mod try_take_while; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_take_while::TryTakeWhile; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] mod try_buffer_unordered; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_buffer_unordered::TryBufferUnordered; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] mod try_buffered; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_buffered::TryBuffered; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] mod try_for_each_concurrent; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_for_each_concurrent::TryForEachConcurrent; #[cfg(feature = "io")] #[cfg(feature = "std")] mod into_async_read; #[cfg(feature = "io")] #[cfg_attr(docsrs, doc(cfg(feature = "io")))] #[cfg(feature = "std")] #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::into_async_read::IntoAsyncRead; mod try_all; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_all::TryAll; mod try_any; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use self::try_any::TryAny; impl TryStreamExt for S {} /// Adapters specific to `Result`-returning streams pub trait TryStreamExt: TryStream { /// Wraps the current stream in a new stream which converts the error type /// into the one provided. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, TryStreamExt}; /// /// let mut stream = /// stream::iter(vec![Ok(()), Err(5i32)]) /// .err_into::(); /// /// assert_eq!(stream.try_next().await, Ok(Some(()))); /// assert_eq!(stream.try_next().await, Err(5i64)); /// # }) /// ``` fn err_into(self) -> ErrInto where Self: Sized, Self::Error: Into, { assert_stream::, _>(ErrInto::new(self)) } /// Wraps the current stream in a new stream which maps the success value /// using the provided closure. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, TryStreamExt}; /// /// let mut stream = /// stream::iter(vec![Ok(5), Err(0)]) /// .map_ok(|x| x + 2); /// /// assert_eq!(stream.try_next().await, Ok(Some(7))); /// assert_eq!(stream.try_next().await, Err(0)); /// # }) /// ``` fn map_ok(self, f: F) -> MapOk where Self: Sized, F: FnMut(Self::Ok) -> T, { assert_stream::, _>(MapOk::new(self, f)) } /// Wraps the current stream in a new stream which maps the error value /// using the provided closure. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, TryStreamExt}; /// /// let mut stream = /// stream::iter(vec![Ok(5), Err(0)]) /// .map_err(|x| x + 2); /// /// assert_eq!(stream.try_next().await, Ok(Some(5))); /// assert_eq!(stream.try_next().await, Err(2)); /// # }) /// ``` fn map_err(self, f: F) -> MapErr where Self: Sized, F: FnMut(Self::Error) -> E, { assert_stream::, _>(MapErr::new(self, f)) } /// Chain on a computation for when a value is ready, passing the successful /// results to the provided closure `f`. /// /// This function can be used to run a unit of work when the next successful /// value on a stream is ready. The closure provided will be yielded a value /// when ready, and the returned future will then be run to completion to /// produce the next value on this stream. /// /// Any errors produced by this stream will not be passed to the closure, /// and will be passed through. /// /// The returned value of the closure must implement the `TryFuture` trait /// and can represent some more work to be done before the composed stream /// is finished. /// /// Note that this function consumes the receiving stream and returns a /// wrapped version of it. /// /// To process the entire stream and return a single future representing /// success or error, use `try_for_each` instead. /// /// # Examples /// /// ``` /// use futures::channel::mpsc; /// use futures::future; /// use futures::stream::TryStreamExt; /// /// let (_tx, rx) = mpsc::channel::>(1); /// /// let rx = rx.and_then(|result| { /// future::ok(if result % 2 == 0 { /// Some(result) /// } else { /// None /// }) /// }); /// ``` fn and_then(self, f: F) -> AndThen where F: FnMut(Self::Ok) -> Fut, Fut: TryFuture, Self: Sized, { assert_stream::, _>(AndThen::new(self, f)) } /// Chain on a computation for when an error happens, passing the /// erroneous result to the provided closure `f`. /// /// This function can be used to run a unit of work and attempt to recover from /// an error if one happens. The closure provided will be yielded an error /// when one appears, and the returned future will then be run to completion /// to produce the next value on this stream. /// /// Any successful values produced by this stream will not be passed to the /// closure, and will be passed through. /// /// The returned value of the closure must implement the [`TryFuture`](futures_core::future::TryFuture) trait /// and can represent some more work to be done before the composed stream /// is finished. /// /// Note that this function consumes the receiving stream and returns a /// wrapped version of it. fn or_else(self, f: F) -> OrElse where F: FnMut(Self::Error) -> Fut, Fut: TryFuture, Self: Sized, { assert_stream::, _>(OrElse::new(self, f)) } /// Do something with the success value of this stream, afterwards passing /// it on. /// /// This is similar to the `StreamExt::inspect` method where it allows /// easily inspecting the success value as it passes through the stream, for /// example to debug what's going on. fn inspect_ok(self, f: F) -> InspectOk where F: FnMut(&Self::Ok), Self: Sized, { assert_stream::, _>(InspectOk::new(self, f)) } /// Do something with the error value of this stream, afterwards passing it on. /// /// This is similar to the `StreamExt::inspect` method where it allows /// easily inspecting the error value as it passes through the stream, for /// example to debug what's going on. fn inspect_err(self, f: F) -> InspectErr where F: FnMut(&Self::Error), Self: Sized, { assert_stream::, _>(InspectErr::new(self, f)) } /// Wraps a [`TryStream`] into a type that implements /// [`Stream`](futures_core::stream::Stream) /// /// [`TryStream`]s currently do not implement the /// [`Stream`](futures_core::stream::Stream) trait because of limitations /// of the compiler. /// /// # Examples /// /// ``` /// use futures::stream::{Stream, TryStream, TryStreamExt}; /// /// # type T = i32; /// # type E = (); /// fn make_try_stream() -> impl TryStream { // ... } /// # futures::stream::empty() /// # } /// fn take_stream(stream: impl Stream>) { /* ... */ } /// /// take_stream(make_try_stream().into_stream()); /// ``` fn into_stream(self) -> IntoStream where Self: Sized, { assert_stream::, _>(IntoStream::new(self)) } /// Creates a future that attempts to resolve the next item in the stream. /// If an error is encountered before the next item, the error is returned /// instead. /// /// This is similar to the `Stream::next` combinator, but returns a /// `Result, E>` rather than an `Option>`, making /// for easy use with the `?` operator. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, TryStreamExt}; /// /// let mut stream = stream::iter(vec![Ok(()), Err(())]); /// /// assert_eq!(stream.try_next().await, Ok(Some(()))); /// assert_eq!(stream.try_next().await, Err(())); /// # }) /// ``` fn try_next(&mut self) -> TryNext<'_, Self> where Self: Unpin, { assert_future::, Self::Error>, _>(TryNext::new(self)) } /// Attempts to run this stream to completion, executing the provided /// asynchronous closure for each element on the stream. /// /// The provided closure will be called for each item this stream produces, /// yielding a future. That future will then be executed to completion /// before moving on to the next item. /// /// The returned value is a [`Future`](futures_core::future::Future) where the /// [`Output`](futures_core::future::Future::Output) type is /// `Result<(), Self::Error>`. If any of the intermediate /// futures or the stream returns an error, this future will return /// immediately with an error. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// use futures::stream::{self, TryStreamExt}; /// /// let mut x = 0i32; /// /// { /// let fut = stream::repeat(Ok(1)).try_for_each(|item| { /// x += item; /// future::ready(if x == 3 { Err(()) } else { Ok(()) }) /// }); /// assert_eq!(fut.await, Err(())); /// } /// /// assert_eq!(x, 3); /// # }) /// ``` fn try_for_each(self, f: F) -> TryForEach where F: FnMut(Self::Ok) -> Fut, Fut: TryFuture, Self: Sized, { assert_future::, _>(TryForEach::new(self, f)) } /// Skip elements on this stream while the provided asynchronous predicate /// resolves to `true`. /// /// This function is similar to /// [`StreamExt::skip_while`](crate::stream::StreamExt::skip_while) but exits /// early if an error occurs. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// use futures::stream::{self, TryStreamExt}; /// /// let stream = stream::iter(vec![Ok::(1), Ok(3), Ok(2)]); /// let stream = stream.try_skip_while(|x| future::ready(Ok(*x < 3))); /// /// let output: Result, i32> = stream.try_collect().await; /// assert_eq!(output, Ok(vec![3, 2])); /// # }) /// ``` fn try_skip_while(self, f: F) -> TrySkipWhile where F: FnMut(&Self::Ok) -> Fut, Fut: TryFuture, Self: Sized, { assert_stream::, _>(TrySkipWhile::new(self, f)) } /// Take elements on this stream while the provided asynchronous predicate /// resolves to `true`. /// /// This function is similar to /// [`StreamExt::take_while`](crate::stream::StreamExt::take_while) but exits /// early if an error occurs. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// use futures::stream::{self, TryStreamExt}; /// /// let stream = stream::iter(vec![Ok::(1), Ok(2), Ok(3), Ok(2)]); /// let stream = stream.try_take_while(|x| future::ready(Ok(*x < 3))); /// /// let output: Result, i32> = stream.try_collect().await; /// assert_eq!(output, Ok(vec![1, 2])); /// # }) /// ``` fn try_take_while(self, f: F) -> TryTakeWhile where F: FnMut(&Self::Ok) -> Fut, Fut: TryFuture, Self: Sized, { assert_stream::, _>(TryTakeWhile::new(self, f)) } /// Attempts to run this stream to completion, executing the provided asynchronous /// closure for each element on the stream concurrently as elements become /// available, exiting as soon as an error occurs. /// /// This is similar to /// [`StreamExt::for_each_concurrent`](crate::stream::StreamExt::for_each_concurrent), /// but will resolve to an error immediately if the underlying stream or the provided /// closure return an error. /// /// This method is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::channel::oneshot; /// use futures::stream::{self, StreamExt, TryStreamExt}; /// /// let (tx1, rx1) = oneshot::channel(); /// let (tx2, rx2) = oneshot::channel(); /// let (_tx3, rx3) = oneshot::channel(); /// /// let stream = stream::iter(vec![rx1, rx2, rx3]); /// let fut = stream.map(Ok).try_for_each_concurrent( /// /* limit */ 2, /// |rx| async move { /// let res: Result<(), oneshot::Canceled> = rx.await; /// res /// } /// ); /// /// tx1.send(()).unwrap(); /// // Drop the second sender so that `rx2` resolves to `Canceled`. /// drop(tx2); /// /// // The final result is an error because the second future /// // resulted in an error. /// assert_eq!(Err(oneshot::Canceled), fut.await); /// # }) /// ``` #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] fn try_for_each_concurrent( self, limit: impl Into>, f: F, ) -> TryForEachConcurrent where F: FnMut(Self::Ok) -> Fut, Fut: Future>, Self: Sized, { assert_future::, _>(TryForEachConcurrent::new( self, limit.into(), f, )) } /// Attempt to transform a stream into a collection, /// returning a future representing the result of that computation. /// /// This combinator will collect all successful results of this stream and /// collect them into the specified collection type. If an error happens then all /// collected elements will be dropped and the error will be returned. /// /// The returned future will be resolved when the stream terminates. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::channel::mpsc; /// use futures::stream::TryStreamExt; /// use std::thread; /// /// let (tx, rx) = mpsc::unbounded(); /// /// thread::spawn(move || { /// for i in 1..=5 { /// tx.unbounded_send(Ok(i)).unwrap(); /// } /// tx.unbounded_send(Err(6)).unwrap(); /// }); /// /// let output: Result, i32> = rx.try_collect().await; /// assert_eq!(output, Err(6)); /// # }) /// ``` fn try_collect>(self) -> TryCollect where Self: Sized, { assert_future::, _>(TryCollect::new(self)) } /// An adaptor for chunking up successful items of the stream inside a vector. /// /// This combinator will attempt to pull successful items from this stream and buffer /// them into a local vector. At most `capacity` items will get buffered /// before they're yielded from the returned stream. /// /// Note that the vectors returned from this iterator may not always have /// `capacity` elements. If the underlying stream ended and only a partial /// vector was created, it'll be returned. Additionally if an error happens /// from the underlying stream then the currently buffered items will be /// yielded. /// /// This method is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. /// /// This function is similar to /// [`StreamExt::chunks`](crate::stream::StreamExt::chunks) but exits /// early if an error occurs. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, TryChunksError, TryStreamExt}; /// /// let stream = stream::iter(vec![Ok::(1), Ok(2), Ok(3), Err(4), Ok(5), Ok(6)]); /// let mut stream = stream.try_chunks(2); /// /// assert_eq!(stream.try_next().await, Ok(Some(vec![1, 2]))); /// assert_eq!(stream.try_next().await, Err(TryChunksError(vec![3], 4))); /// assert_eq!(stream.try_next().await, Ok(Some(vec![5, 6]))); /// # }) /// ``` /// /// # Panics /// /// This method will panic if `capacity` is zero. #[cfg(feature = "alloc")] fn try_chunks(self, capacity: usize) -> TryChunks where Self: Sized, { assert_stream::, TryChunksError>, _>( TryChunks::new(self, capacity), ) } /// An adaptor for chunking up successful, ready items of the stream inside a vector. /// /// This combinator will attempt to pull successful items from this stream and buffer /// them into a local vector. At most `capacity` items will get buffered /// before they're yielded from the returned stream. If the underlying stream /// returns `Poll::Pending`, and the collected chunk is not empty, it will /// be immidiatly returned. /// /// Note that the vectors returned from this iterator may not always have /// `capacity` elements. If the underlying stream ended and only a partial /// vector was created, it'll be returned. Additionally if an error happens /// from the underlying stream then the currently buffered items will be /// yielded. /// /// This method is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. /// /// This function is similar to /// [`StreamExt::ready_chunks`](crate::stream::StreamExt::ready_chunks) but exits /// early if an error occurs. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, TryReadyChunksError, TryStreamExt}; /// /// let stream = stream::iter(vec![Ok::(1), Ok(2), Ok(3), Err(4), Ok(5), Ok(6)]); /// let mut stream = stream.try_ready_chunks(2); /// /// assert_eq!(stream.try_next().await, Ok(Some(vec![1, 2]))); /// assert_eq!(stream.try_next().await, Err(TryReadyChunksError(vec![3], 4))); /// assert_eq!(stream.try_next().await, Ok(Some(vec![5, 6]))); /// # }) /// ``` /// /// # Panics /// /// This method will panic if `capacity` is zero. #[cfg(feature = "alloc")] fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks where Self: Sized, { assert_stream::, TryReadyChunksError>, _>( TryReadyChunks::new(self, capacity), ) } /// Attempt to filter the values produced by this stream according to the /// provided asynchronous closure. /// /// As values of this stream are made available, the provided predicate `f` /// will be run on them. If the predicate returns a `Future` which resolves /// to `true`, then the stream will yield the value, but if the predicate /// return a `Future` which resolves to `false`, then the value will be /// discarded and the next value will be produced. /// /// All errors are passed through without filtering in this combinator. /// /// Note that this function consumes the stream passed into it and returns a /// wrapped version of it, similar to the existing `filter` methods in /// the standard library. /// /// # Examples /// ``` /// # futures::executor::block_on(async { /// use futures::future; /// use futures::stream::{self, StreamExt, TryStreamExt}; /// /// let stream = stream::iter(vec![Ok(1i32), Ok(2i32), Ok(3i32), Err("error")]); /// let mut evens = stream.try_filter(|x| { /// future::ready(x % 2 == 0) /// }); /// /// assert_eq!(evens.next().await, Some(Ok(2))); /// assert_eq!(evens.next().await, Some(Err("error"))); /// # }) /// ``` fn try_filter(self, f: F) -> TryFilter where Fut: Future, F: FnMut(&Self::Ok) -> Fut, Self: Sized, { assert_stream::, _>(TryFilter::new(self, f)) } /// Attempt to filter the values produced by this stream while /// simultaneously mapping them to a different type according to the /// provided asynchronous closure. /// /// As values of this stream are made available, the provided function will /// be run on them. If the future returned by the predicate `f` resolves to /// [`Some(item)`](Some) then the stream will yield the value `item`, but if /// it resolves to [`None`] then the next value will be produced. /// /// All errors are passed through without filtering in this combinator. /// /// Note that this function consumes the stream passed into it and returns a /// wrapped version of it, similar to the existing `filter_map` methods in /// the standard library. /// /// # Examples /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt, TryStreamExt}; /// use futures::pin_mut; /// /// let stream = stream::iter(vec![Ok(1i32), Ok(6i32), Err("error")]); /// let halves = stream.try_filter_map(|x| async move { /// let ret = if x % 2 == 0 { Some(x / 2) } else { None }; /// Ok(ret) /// }); /// /// pin_mut!(halves); /// assert_eq!(halves.next().await, Some(Ok(3))); /// assert_eq!(halves.next().await, Some(Err("error"))); /// # }) /// ``` fn try_filter_map(self, f: F) -> TryFilterMap where Fut: TryFuture, Error = Self::Error>, F: FnMut(Self::Ok) -> Fut, Self: Sized, { assert_stream::, _>(TryFilterMap::new(self, f)) } /// Flattens a stream of streams into just one continuous stream. Produced streams /// will be polled concurrently and any errors will be passed through without looking at them. /// If the underlying base stream returns an error, it will be **immediately** propagated. /// /// The only argument is an optional limit on the number of concurrently /// polled streams. If this limit is not `None`, no more than `limit` streams /// will be polled at the same time. The `limit` argument is of type /// `Into>`, and so can be provided as either `None`, /// `Some(10)`, or just `10`. Note: a limit of zero is interpreted as /// no limit at all, and will have the same result as passing in `None`. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::channel::mpsc; /// use futures::stream::{StreamExt, TryStreamExt}; /// use std::thread; /// /// let (tx1, rx1) = mpsc::unbounded(); /// let (tx2, rx2) = mpsc::unbounded(); /// let (tx3, rx3) = mpsc::unbounded(); /// /// thread::spawn(move || { /// tx1.unbounded_send(Ok(1)).unwrap(); /// }); /// thread::spawn(move || { /// tx2.unbounded_send(Ok(2)).unwrap(); /// tx2.unbounded_send(Err(3)).unwrap(); /// tx2.unbounded_send(Ok(4)).unwrap(); /// }); /// thread::spawn(move || { /// tx3.unbounded_send(Ok(rx1)).unwrap(); /// tx3.unbounded_send(Ok(rx2)).unwrap(); /// tx3.unbounded_send(Err(5)).unwrap(); /// }); /// /// let stream = rx3.try_flatten_unordered(None); /// let mut values: Vec<_> = stream.collect().await; /// values.sort(); /// /// assert_eq!(values, vec![Ok(1), Ok(2), Ok(4), Err(3), Err(5)]); /// # }); /// ``` #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] fn try_flatten_unordered(self, limit: impl Into>) -> TryFlattenUnordered where Self::Ok: TryStream + Unpin, ::Error: From, Self: Sized, { assert_stream::::Ok, ::Error>, _>( TryFlattenUnordered::new(self, limit), ) } /// Flattens a stream of streams into just one continuous stream. /// /// If this stream's elements are themselves streams then this combinator /// will flatten out the entire stream to one long chain of elements. Any /// errors are passed through without looking at them, but otherwise each /// individual stream will get exhausted before moving on to the next. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::channel::mpsc; /// use futures::stream::{StreamExt, TryStreamExt}; /// use std::thread; /// /// let (tx1, rx1) = mpsc::unbounded(); /// let (tx2, rx2) = mpsc::unbounded(); /// let (tx3, rx3) = mpsc::unbounded(); /// /// thread::spawn(move || { /// tx1.unbounded_send(Ok(1)).unwrap(); /// }); /// thread::spawn(move || { /// tx2.unbounded_send(Ok(2)).unwrap(); /// tx2.unbounded_send(Err(3)).unwrap(); /// tx2.unbounded_send(Ok(4)).unwrap(); /// }); /// thread::spawn(move || { /// tx3.unbounded_send(Ok(rx1)).unwrap(); /// tx3.unbounded_send(Ok(rx2)).unwrap(); /// tx3.unbounded_send(Err(5)).unwrap(); /// }); /// /// let mut stream = rx3.try_flatten(); /// assert_eq!(stream.next().await, Some(Ok(1))); /// assert_eq!(stream.next().await, Some(Ok(2))); /// assert_eq!(stream.next().await, Some(Err(3))); /// assert_eq!(stream.next().await, Some(Ok(4))); /// assert_eq!(stream.next().await, Some(Err(5))); /// assert_eq!(stream.next().await, None); /// # }); /// ``` fn try_flatten(self) -> TryFlatten where Self::Ok: TryStream, ::Error: From, Self: Sized, { assert_stream::::Ok, ::Error>, _>( TryFlatten::new(self), ) } /// Attempt to execute an accumulating asynchronous computation over a /// stream, collecting all the values into one final result. /// /// This combinator will accumulate all values returned by this stream /// according to the closure provided. The initial state is also provided to /// this method and then is returned again by each execution of the closure. /// Once the entire stream has been exhausted the returned future will /// resolve to this value. /// /// This method is similar to [`fold`](crate::stream::StreamExt::fold), but will /// exit early if an error is encountered in either the stream or the /// provided closure. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, TryStreamExt}; /// /// let number_stream = stream::iter(vec![Ok::(1), Ok(2)]); /// let sum = number_stream.try_fold(0, |acc, x| async move { Ok(acc + x) }); /// assert_eq!(sum.await, Ok(3)); /// /// let number_stream_with_err = stream::iter(vec![Ok::(1), Err(2), Ok(1)]); /// let sum = number_stream_with_err.try_fold(0, |acc, x| async move { Ok(acc + x) }); /// assert_eq!(sum.await, Err(2)); /// # }) /// ``` fn try_fold(self, init: T, f: F) -> TryFold where F: FnMut(T, Self::Ok) -> Fut, Fut: TryFuture, Self: Sized, { assert_future::, _>(TryFold::new(self, f, init)) } /// Attempt to concatenate all items of a stream into a single /// extendable destination, returning a future representing the end result. /// /// This combinator will extend the first item with the contents of all /// the subsequent successful results of the stream. If the stream is empty, /// the default value will be returned. /// /// Works with all collections that implement the [`Extend`](std::iter::Extend) trait. /// /// This method is similar to [`concat`](crate::stream::StreamExt::concat), but will /// exit early if an error is encountered in the stream. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::channel::mpsc; /// use futures::stream::TryStreamExt; /// use std::thread; /// /// let (tx, rx) = mpsc::unbounded::, ()>>(); /// /// thread::spawn(move || { /// for i in (0..3).rev() { /// let n = i * 3; /// tx.unbounded_send(Ok(vec![n + 1, n + 2, n + 3])).unwrap(); /// } /// }); /// /// let result = rx.try_concat().await; /// /// assert_eq!(result, Ok(vec![7, 8, 9, 4, 5, 6, 1, 2, 3])); /// # }); /// ``` fn try_concat(self) -> TryConcat where Self: Sized, Self::Ok: Extend<<::Ok as IntoIterator>::Item> + IntoIterator + Default, { assert_future::, _>(TryConcat::new(self)) } /// Attempt to execute several futures from a stream concurrently (unordered). /// /// This stream's `Ok` type must be a [`TryFuture`](futures_core::future::TryFuture) with an `Error` type /// that matches the stream's `Error` type. /// /// This adaptor will buffer up to `n` futures and then return their /// outputs in the order in which they complete. If the underlying stream /// returns an error, it will be immediately propagated. /// /// The returned stream will be a stream of results, each containing either /// an error or a future's output. An error can be produced either by the /// underlying stream itself or by one of the futures it yielded. /// /// This method is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. /// /// # Examples /// /// Results are returned in the order of completion: /// ``` /// # futures::executor::block_on(async { /// use futures::channel::oneshot; /// use futures::stream::{self, StreamExt, TryStreamExt}; /// /// let (send_one, recv_one) = oneshot::channel(); /// let (send_two, recv_two) = oneshot::channel(); /// /// let stream_of_futures = stream::iter(vec![Ok(recv_one), Ok(recv_two)]); /// /// let mut buffered = stream_of_futures.try_buffer_unordered(10); /// /// send_two.send(2i32)?; /// assert_eq!(buffered.next().await, Some(Ok(2i32))); /// /// send_one.send(1i32)?; /// assert_eq!(buffered.next().await, Some(Ok(1i32))); /// /// assert_eq!(buffered.next().await, None); /// # Ok::<(), i32>(()) }).unwrap(); /// ``` /// /// Errors from the underlying stream itself are propagated: /// ``` /// # futures::executor::block_on(async { /// use futures::channel::mpsc; /// use futures::stream::{StreamExt, TryStreamExt}; /// /// let (sink, stream_of_futures) = mpsc::unbounded(); /// let mut buffered = stream_of_futures.try_buffer_unordered(10); /// /// sink.unbounded_send(Ok(async { Ok(7i32) }))?; /// assert_eq!(buffered.next().await, Some(Ok(7i32))); /// /// sink.unbounded_send(Err("error in the stream"))?; /// assert_eq!(buffered.next().await, Some(Err("error in the stream"))); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered where Self::Ok: TryFuture, Self: Sized, { assert_stream::::Ok, Self::Error>, _>( TryBufferUnordered::new(self, n), ) } /// Attempt to execute several futures from a stream concurrently. /// /// This stream's `Ok` type must be a [`TryFuture`](futures_core::future::TryFuture) with an `Error` type /// that matches the stream's `Error` type. /// /// This adaptor will buffer up to `n` futures and then return their /// outputs in the same order as the underlying stream. If the underlying stream returns an error, it will /// be immediately propagated. /// /// The returned stream will be a stream of results, each containing either /// an error or a future's output. An error can be produced either by the /// underlying stream itself or by one of the futures it yielded. /// /// This method is only available when the `std` or `alloc` feature of this /// library is activated, and it is activated by default. /// /// # Examples /// /// Results are returned in the order of addition: /// ``` /// # futures::executor::block_on(async { /// use futures::channel::oneshot; /// use futures::future::lazy; /// use futures::stream::{self, StreamExt, TryStreamExt}; /// /// let (send_one, recv_one) = oneshot::channel(); /// let (send_two, recv_two) = oneshot::channel(); /// /// let mut buffered = lazy(move |cx| { /// let stream_of_futures = stream::iter(vec![Ok(recv_one), Ok(recv_two)]); /// /// let mut buffered = stream_of_futures.try_buffered(10); /// /// assert!(buffered.try_poll_next_unpin(cx).is_pending()); /// /// send_two.send(2i32)?; /// assert!(buffered.try_poll_next_unpin(cx).is_pending()); /// Ok::<_, i32>(buffered) /// }).await?; /// /// send_one.send(1i32)?; /// assert_eq!(buffered.next().await, Some(Ok(1i32))); /// assert_eq!(buffered.next().await, Some(Ok(2i32))); /// /// assert_eq!(buffered.next().await, None); /// # Ok::<(), i32>(()) }).unwrap(); /// ``` /// /// Errors from the underlying stream itself are propagated: /// ``` /// # futures::executor::block_on(async { /// use futures::channel::mpsc; /// use futures::stream::{StreamExt, TryStreamExt}; /// /// let (sink, stream_of_futures) = mpsc::unbounded(); /// let mut buffered = stream_of_futures.try_buffered(10); /// /// sink.unbounded_send(Ok(async { Ok(7i32) }))?; /// assert_eq!(buffered.next().await, Some(Ok(7i32))); /// /// sink.unbounded_send(Err("error in the stream"))?; /// assert_eq!(buffered.next().await, Some(Err("error in the stream"))); /// # Ok::<(), Box>(()) }).unwrap(); /// ``` #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] fn try_buffered(self, n: usize) -> TryBuffered where Self::Ok: TryFuture, Self: Sized, { assert_stream::::Ok, Self::Error>, _>(TryBuffered::new( self, n, )) } // TODO: false positive warning from rustdoc. Verify once #43466 settles // /// A convenience method for calling [`TryStream::try_poll_next`] on [`Unpin`] /// stream types. fn try_poll_next_unpin( &mut self, cx: &mut Context<'_>, ) -> Poll>> where Self: Unpin, { Pin::new(self).try_poll_next(cx) } /// Wraps a [`TryStream`] into a stream compatible with libraries using /// futures 0.1 `Stream`. Requires the `compat` feature to be enabled. /// ``` /// # if cfg!(miri) { return; } // Miri does not support epoll /// use futures::future::{FutureExt, TryFutureExt}; /// # let (tx, rx) = futures::channel::oneshot::channel(); /// /// let future03 = async { /// println!("Running on the pool"); /// tx.send(42).unwrap(); /// }; /// /// let future01 = future03 /// .unit_error() // Make it a TryFuture /// .boxed() // Make it Unpin /// .compat(); /// /// tokio::run(future01); /// # assert_eq!(42, futures::executor::block_on(rx).unwrap()); /// ``` #[cfg(feature = "compat")] #[cfg_attr(docsrs, doc(cfg(feature = "compat")))] fn compat(self) -> Compat where Self: Sized + Unpin, { Compat::new(self) } /// Adapter that converts this stream into an [`AsyncBufRead`](crate::io::AsyncBufRead). /// /// This method is only available when the `std` feature of this /// library is activated, and it is activated by default. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, TryStreamExt}; /// use futures::io::AsyncReadExt; /// /// let stream = stream::iter([Ok(vec![1, 2, 3]), Ok(vec![4, 5])]); /// let mut reader = stream.into_async_read(); /// /// let mut buf = Vec::new(); /// reader.read_to_end(&mut buf).await.unwrap(); /// assert_eq!(buf, [1, 2, 3, 4, 5]); /// # }) /// ``` #[cfg(feature = "io")] #[cfg_attr(docsrs, doc(cfg(feature = "io")))] #[cfg(feature = "std")] fn into_async_read(self) -> IntoAsyncRead where Self: Sized + TryStreamExt, Self::Ok: AsRef<[u8]>, { crate::io::assert_read(IntoAsyncRead::new(self)) } /// Attempt to execute a predicate over an asynchronous stream and evaluate if all items /// satisfy the predicate. Exits early if an `Err` is encountered or if an `Ok` item is found /// that does not satisfy the predicate. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt, TryStreamExt}; /// use std::convert::Infallible; /// /// let number_stream = stream::iter(1..10).map(Ok::<_, Infallible>); /// let positive = number_stream.try_all(|i| async move { i > 0 }); /// assert_eq!(positive.await, Ok(true)); /// /// let stream_with_errors = stream::iter([Ok(1), Err("err"), Ok(3)]); /// let positive = stream_with_errors.try_all(|i| async move { i > 0 }); /// assert_eq!(positive.await, Err("err")); /// # }); /// ``` fn try_all(self, f: F) -> TryAll where Self: Sized, F: FnMut(Self::Ok) -> Fut, Fut: Future, { assert_future::, _>(TryAll::new(self, f)) } /// Attempt to execute a predicate over an asynchronous stream and evaluate if any items /// satisfy the predicate. Exits early if an `Err` is encountered or if an `Ok` item is found /// that satisfies the predicate. /// /// # Examples /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt, TryStreamExt}; /// use std::convert::Infallible; /// /// let number_stream = stream::iter(0..10).map(Ok::<_, Infallible>); /// let contain_three = number_stream.try_any(|i| async move { i == 3 }); /// assert_eq!(contain_three.await, Ok(true)); /// /// let stream_with_errors = stream::iter([Ok(1), Err("err"), Ok(3)]); /// let contain_three = stream_with_errors.try_any(|i| async move { i == 3 }); /// assert_eq!(contain_three.await, Err("err")); /// # }); /// ``` fn try_any(self, f: F) -> TryAny where Self: Sized, F: FnMut(Self::Ok) -> Fut, Fut: Future, { assert_future::, _>(TryAny::new(self, f)) } } futures-util-0.3.30/src/stream/try_stream/or_else.rs000064400000000000000000000055361046102023000206410ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::TryFuture; use futures_core::ready; use futures_core::stream::{FusedStream, Stream, TryStream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`or_else`](super::TryStreamExt::or_else) method. #[must_use = "streams do nothing unless polled"] pub struct OrElse { #[pin] stream: St, #[pin] future: Option, f: F, } } impl fmt::Debug for OrElse where St: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("OrElse") .field("stream", &self.stream) .field("future", &self.future) .finish() } } impl OrElse where St: TryStream, F: FnMut(St::Error) -> Fut, Fut: TryFuture, { pub(super) fn new(stream: St, f: F) -> Self { Self { stream, future: None, f } } delegate_access_inner!(stream, St, ()); } impl Stream for OrElse where St: TryStream, F: FnMut(St::Error) -> Fut, Fut: TryFuture, { type Item = Result; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); Poll::Ready(loop { if let Some(fut) = this.future.as_mut().as_pin_mut() { let item = ready!(fut.try_poll(cx)); this.future.set(None); break Some(item); } else { match ready!(this.stream.as_mut().try_poll_next(cx)) { Some(Ok(item)) => break Some(Ok(item)), Some(Err(e)) => { this.future.set(Some((this.f)(e))); } None => break None, } } }) } fn size_hint(&self) -> (usize, Option) { let future_len = usize::from(self.future.is_some()); let (lower, upper) = self.stream.size_hint(); let lower = lower.saturating_add(future_len); let upper = match upper { Some(x) => x.checked_add(future_len), None => None, }; (lower, upper) } } impl FusedStream for OrElse where St: TryStream + FusedStream, F: FnMut(St::Error) -> Fut, Fut: TryFuture, { fn is_terminated(&self) -> bool { self.future.is_none() && self.stream.is_terminated() } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for OrElse where S: Sink, { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/try_stream/try_all.rs000064400000000000000000000053171046102023000206540ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; use futures_core::stream::TryStream; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`try_all`](super::TryStreamExt::try_all) method. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct TryAll { #[pin] stream: St, f: F, done: bool, #[pin] future: Option, } } impl fmt::Debug for TryAll where St: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TryAll") .field("stream", &self.stream) .field("done", &self.done) .field("future", &self.future) .finish() } } impl TryAll where St: TryStream, F: FnMut(St::Ok) -> Fut, Fut: Future, { pub(super) fn new(stream: St, f: F) -> Self { Self { stream, f, done: false, future: None } } } impl FusedFuture for TryAll where St: TryStream, F: FnMut(St::Ok) -> Fut, Fut: Future, { fn is_terminated(&self) -> bool { self.done && self.future.is_none() } } impl Future for TryAll where St: TryStream, F: FnMut(St::Ok) -> Fut, Fut: Future, { type Output = Result; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); Poll::Ready(loop { if let Some(fut) = this.future.as_mut().as_pin_mut() { // we're currently processing a future to produce a new value let acc = ready!(fut.poll(cx)); this.future.set(None); if !acc { *this.done = true; break Ok(false); } // early exit } else if !*this.done { // we're waiting on a new item from the stream match ready!(this.stream.as_mut().try_poll_next(cx)) { Some(Ok(item)) => { this.future.set(Some((this.f)(item))); } Some(Err(err)) => { *this.done = true; break Err(err); } None => { *this.done = true; break Ok(true); } } } else { panic!("TryAll polled after completion") } }) } } futures-util-0.3.30/src/stream/try_stream/try_any.rs000064400000000000000000000053161046102023000206720ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; use futures_core::stream::TryStream; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`try_any`](super::TryStreamExt::try_any) method. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct TryAny { #[pin] stream: St, f: F, done: bool, #[pin] future: Option, } } impl fmt::Debug for TryAny where St: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TryAny") .field("stream", &self.stream) .field("done", &self.done) .field("future", &self.future) .finish() } } impl TryAny where St: TryStream, F: FnMut(St::Ok) -> Fut, Fut: Future, { pub(super) fn new(stream: St, f: F) -> Self { Self { stream, f, done: false, future: None } } } impl FusedFuture for TryAny where St: TryStream, F: FnMut(St::Ok) -> Fut, Fut: Future, { fn is_terminated(&self) -> bool { self.done && self.future.is_none() } } impl Future for TryAny where St: TryStream, F: FnMut(St::Ok) -> Fut, Fut: Future, { type Output = Result; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); Poll::Ready(loop { if let Some(fut) = this.future.as_mut().as_pin_mut() { // we're currently processing a future to produce a new value let acc = ready!(fut.poll(cx)); this.future.set(None); if acc { *this.done = true; break Ok(true); } // early exit } else if !*this.done { // we're waiting on a new item from the stream match ready!(this.stream.as_mut().try_poll_next(cx)) { Some(Ok(item)) => { this.future.set(Some((this.f)(item))); } Some(Err(err)) => { *this.done = true; break Err(err); } None => { *this.done = true; break Ok(false); } } } else { panic!("TryAny polled after completion") } }) } } futures-util-0.3.30/src/stream/try_stream/try_buffer_unordered.rs000064400000000000000000000050271046102023000234220ustar 00000000000000use crate::future::{IntoFuture, TryFutureExt}; use crate::stream::{Fuse, FuturesUnordered, IntoStream, StreamExt}; use core::pin::Pin; use futures_core::future::TryFuture; use futures_core::stream::{Stream, TryStream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the /// [`try_buffer_unordered`](super::TryStreamExt::try_buffer_unordered) method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct TryBufferUnordered where St: TryStream { #[pin] stream: Fuse>, in_progress_queue: FuturesUnordered>, max: usize, } } impl TryBufferUnordered where St: TryStream, St::Ok: TryFuture, { pub(super) fn new(stream: St, n: usize) -> Self { Self { stream: IntoStream::new(stream).fuse(), in_progress_queue: FuturesUnordered::new(), max: n, } } delegate_access_inner!(stream, St, (. .)); } impl Stream for TryBufferUnordered where St: TryStream, St::Ok: TryFuture, { type Item = Result<::Ok, St::Error>; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); // First up, try to spawn off as many futures as possible by filling up // our queue of futures. Propagate errors from the stream immediately. while this.in_progress_queue.len() < *this.max { match this.stream.as_mut().poll_next(cx)? { Poll::Ready(Some(fut)) => this.in_progress_queue.push(fut.into_future()), Poll::Ready(None) | Poll::Pending => break, } } // Attempt to pull the next value from the in_progress_queue match this.in_progress_queue.poll_next_unpin(cx) { x @ Poll::Pending | x @ Poll::Ready(Some(_)) => return x, Poll::Ready(None) => {} } // If more values are still coming from the stream, we're not done yet if this.stream.is_done() { Poll::Ready(None) } else { Poll::Pending } } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for TryBufferUnordered where S: TryStream + Sink, S::Ok: TryFuture, { type Error = E; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/try_stream/try_buffered.rs000064400000000000000000000050021046102023000216550ustar 00000000000000use crate::future::{IntoFuture, TryFutureExt}; use crate::stream::{Fuse, FuturesOrdered, IntoStream, StreamExt}; use core::pin::Pin; use futures_core::future::TryFuture; use futures_core::stream::{Stream, TryStream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`try_buffered`](super::TryStreamExt::try_buffered) method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct TryBuffered where St: TryStream, St::Ok: TryFuture, { #[pin] stream: Fuse>, in_progress_queue: FuturesOrdered>, max: usize, } } impl TryBuffered where St: TryStream, St::Ok: TryFuture, { pub(super) fn new(stream: St, n: usize) -> Self { Self { stream: IntoStream::new(stream).fuse(), in_progress_queue: FuturesOrdered::new(), max: n, } } delegate_access_inner!(stream, St, (. .)); } impl Stream for TryBuffered where St: TryStream, St::Ok: TryFuture, { type Item = Result<::Ok, St::Error>; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); // First up, try to spawn off as many futures as possible by filling up // our queue of futures. Propagate errors from the stream immediately. while this.in_progress_queue.len() < *this.max { match this.stream.as_mut().poll_next(cx)? { Poll::Ready(Some(fut)) => this.in_progress_queue.push_back(fut.into_future()), Poll::Ready(None) | Poll::Pending => break, } } // Attempt to pull the next value from the in_progress_queue match this.in_progress_queue.poll_next_unpin(cx) { x @ Poll::Pending | x @ Poll::Ready(Some(_)) => return x, Poll::Ready(None) => {} } // If more values are still coming from the stream, we're not done yet if this.stream.is_done() { Poll::Ready(None) } else { Poll::Pending } } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for TryBuffered where S: TryStream + Sink, S::Ok: TryFuture, { type Error = E; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/try_stream/try_chunks.rs000064400000000000000000000102641046102023000213740ustar 00000000000000use crate::stream::{Fuse, IntoStream, StreamExt}; use alloc::vec::Vec; use core::pin::Pin; use core::{fmt, mem}; use futures_core::ready; use futures_core::stream::{FusedStream, Stream, TryStream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`try_chunks`](super::TryStreamExt::try_chunks) method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct TryChunks { #[pin] stream: Fuse>, items: Vec, cap: usize, // https://github.com/rust-lang/futures-rs/issues/1475 } } impl TryChunks { pub(super) fn new(stream: St, capacity: usize) -> Self { assert!(capacity > 0); Self { stream: IntoStream::new(stream).fuse(), items: Vec::with_capacity(capacity), cap: capacity, } } fn take(self: Pin<&mut Self>) -> Vec { let cap = self.cap; mem::replace(self.project().items, Vec::with_capacity(cap)) } delegate_access_inner!(stream, St, (. .)); } type TryChunksStreamError = TryChunksError<::Ok, ::Error>; impl Stream for TryChunks { type Item = Result, TryChunksStreamError>; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.as_mut().project(); loop { match ready!(this.stream.as_mut().try_poll_next(cx)) { // Push the item into the buffer and check whether it is full. // If so, replace our buffer with a new and empty one and return // the full one. Some(item) => match item { Ok(item) => { this.items.push(item); if this.items.len() >= *this.cap { return Poll::Ready(Some(Ok(self.take()))); } } Err(e) => { return Poll::Ready(Some(Err(TryChunksError(self.take(), e)))); } }, // Since the underlying stream ran out of values, return what we // have buffered, if we have anything. None => { let last = if this.items.is_empty() { None } else { let full_buf = mem::take(this.items); Some(full_buf) }; return Poll::Ready(last.map(Ok)); } } } } fn size_hint(&self) -> (usize, Option) { let chunk_len = usize::from(!self.items.is_empty()); let (lower, upper) = self.stream.size_hint(); let lower = (lower / self.cap).saturating_add(chunk_len); let upper = match upper { Some(x) => x.checked_add(chunk_len), None => None, }; (lower, upper) } } impl FusedStream for TryChunks { fn is_terminated(&self) -> bool { self.stream.is_terminated() && self.items.is_empty() } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for TryChunks where S: TryStream + Sink, { type Error = >::Error; delegate_sink!(stream, Item); } /// Error indicating, that while chunk was collected inner stream produced an error. /// /// Contains all items that were collected before an error occurred, and the stream error itself. #[derive(PartialEq, Eq)] pub struct TryChunksError(pub Vec, pub E); impl fmt::Debug for TryChunksError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.1.fmt(f) } } impl fmt::Display for TryChunksError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.1.fmt(f) } } #[cfg(feature = "std")] impl std::error::Error for TryChunksError {} futures-util-0.3.30/src/stream/try_stream/try_collect.rs000064400000000000000000000025461046102023000215320ustar 00000000000000use core::mem; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::ready; use futures_core::stream::{FusedStream, TryStream}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`try_collect`](super::TryStreamExt::try_collect) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct TryCollect { #[pin] stream: St, items: C, } } impl TryCollect { pub(super) fn new(s: St) -> Self { Self { stream: s, items: Default::default() } } } impl FusedFuture for TryCollect where St: TryStream + FusedStream, C: Default + Extend, { fn is_terminated(&self) -> bool { self.stream.is_terminated() } } impl Future for TryCollect where St: TryStream, C: Default + Extend, { type Output = Result; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.project(); Poll::Ready(Ok(loop { match ready!(this.stream.as_mut().try_poll_next(cx)?) { Some(x) => this.items.extend(Some(x)), None => break mem::take(this.items), } })) } } futures-util-0.3.30/src/stream/try_stream/try_concat.rs000064400000000000000000000025761046102023000213570ustar 00000000000000use core::pin::Pin; use futures_core::future::Future; use futures_core::ready; use futures_core::stream::TryStream; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`try_concat`](super::TryStreamExt::try_concat) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct TryConcat { #[pin] stream: St, accum: Option, } } impl TryConcat where St: TryStream, St::Ok: Extend<::Item> + IntoIterator + Default, { pub(super) fn new(stream: St) -> Self { Self { stream, accum: None } } } impl Future for TryConcat where St: TryStream, St::Ok: Extend<::Item> + IntoIterator + Default, { type Output = Result; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.project(); Poll::Ready(Ok(loop { if let Some(x) = ready!(this.stream.as_mut().try_poll_next(cx)?) { if let Some(a) = this.accum { a.extend(x) } else { *this.accum = Some(x) } } else { break this.accum.take().unwrap_or_default(); } })) } } futures-util-0.3.30/src/stream/try_stream/try_filter.rs000064400000000000000000000060651046102023000213720ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::Future; use futures_core::ready; use futures_core::stream::{FusedStream, Stream, TryStream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`try_filter`](super::TryStreamExt::try_filter) /// method. #[must_use = "streams do nothing unless polled"] pub struct TryFilter where St: TryStream { #[pin] stream: St, f: F, #[pin] pending_fut: Option, pending_item: Option, } } impl fmt::Debug for TryFilter where St: TryStream + fmt::Debug, St::Ok: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TryFilter") .field("stream", &self.stream) .field("pending_fut", &self.pending_fut) .field("pending_item", &self.pending_item) .finish() } } impl TryFilter where St: TryStream, { pub(super) fn new(stream: St, f: F) -> Self { Self { stream, f, pending_fut: None, pending_item: None } } delegate_access_inner!(stream, St, ()); } impl FusedStream for TryFilter where St: TryStream + FusedStream, F: FnMut(&St::Ok) -> Fut, Fut: Future, { fn is_terminated(&self) -> bool { self.pending_fut.is_none() && self.stream.is_terminated() } } impl Stream for TryFilter where St: TryStream, Fut: Future, F: FnMut(&St::Ok) -> Fut, { type Item = Result; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); Poll::Ready(loop { if let Some(fut) = this.pending_fut.as_mut().as_pin_mut() { let res = ready!(fut.poll(cx)); this.pending_fut.set(None); if res { break this.pending_item.take().map(Ok); } *this.pending_item = None; } else if let Some(item) = ready!(this.stream.as_mut().try_poll_next(cx)?) { this.pending_fut.set(Some((this.f)(&item))); *this.pending_item = Some(item); } else { break None; } }) } fn size_hint(&self) -> (usize, Option) { let pending_len = usize::from(self.pending_fut.is_some()); let (_, upper) = self.stream.size_hint(); let upper = match upper { Some(x) => x.checked_add(pending_len), None => None, }; (0, upper) // can't know a lower bound, due to the predicate } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for TryFilter where S: TryStream + Sink, { type Error = E; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/try_stream/try_filter_map.rs000064400000000000000000000057561046102023000222350ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::TryFuture; use futures_core::ready; use futures_core::stream::{FusedStream, Stream, TryStream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`try_filter_map`](super::TryStreamExt::try_filter_map) /// method. #[must_use = "streams do nothing unless polled"] pub struct TryFilterMap { #[pin] stream: St, f: F, #[pin] pending: Option, } } impl fmt::Debug for TryFilterMap where St: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TryFilterMap") .field("stream", &self.stream) .field("pending", &self.pending) .finish() } } impl TryFilterMap { pub(super) fn new(stream: St, f: F) -> Self { Self { stream, f, pending: None } } delegate_access_inner!(stream, St, ()); } impl FusedStream for TryFilterMap where St: TryStream + FusedStream, Fut: TryFuture, Error = St::Error>, F: FnMut(St::Ok) -> Fut, { fn is_terminated(&self) -> bool { self.pending.is_none() && self.stream.is_terminated() } } impl Stream for TryFilterMap where St: TryStream, Fut: TryFuture, Error = St::Error>, F: FnMut(St::Ok) -> Fut, { type Item = Result; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); Poll::Ready(loop { if let Some(p) = this.pending.as_mut().as_pin_mut() { // We have an item in progress, poll that until it's done let res = ready!(p.try_poll(cx)); this.pending.set(None); let item = res?; if item.is_some() { break item.map(Ok); } } else if let Some(item) = ready!(this.stream.as_mut().try_poll_next(cx)?) { // No item in progress, but the stream is still going this.pending.set(Some((this.f)(item))); } else { // The stream is done break None; } }) } fn size_hint(&self) -> (usize, Option) { let pending_len = usize::from(self.pending.is_some()); let (_, upper) = self.stream.size_hint(); let upper = match upper { Some(x) => x.checked_add(pending_len), None => None, }; (0, upper) // can't know a lower bound, due to the predicate } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for TryFilterMap where S: Sink, { type Error = S::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/try_stream/try_flatten.rs000064400000000000000000000041611046102023000215350ustar 00000000000000use core::pin::Pin; use futures_core::ready; use futures_core::stream::{FusedStream, Stream, TryStream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`try_flatten`](super::TryStreamExt::try_flatten) method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct TryFlatten where St: TryStream, { #[pin] stream: St, #[pin] next: Option, } } impl TryFlatten where St: TryStream, St::Ok: TryStream, ::Error: From, { pub(super) fn new(stream: St) -> Self { Self { stream, next: None } } delegate_access_inner!(stream, St, ()); } impl FusedStream for TryFlatten where St: TryStream + FusedStream, St::Ok: TryStream, ::Error: From, { fn is_terminated(&self) -> bool { self.next.is_none() && self.stream.is_terminated() } } impl Stream for TryFlatten where St: TryStream, St::Ok: TryStream, ::Error: From, { type Item = Result<::Ok, ::Error>; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); Poll::Ready(loop { if let Some(s) = this.next.as_mut().as_pin_mut() { if let Some(item) = ready!(s.try_poll_next(cx)?) { break Some(Ok(item)); } else { this.next.set(None); } } else if let Some(s) = ready!(this.stream.as_mut().try_poll_next(cx)?) { this.next.set(Some(s)); } else { break None; } }) } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for TryFlatten where S: TryStream + Sink, { type Error = >::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/try_stream/try_flatten_unordered.rs000064400000000000000000000126771046102023000236170ustar 00000000000000use core::marker::PhantomData; use core::pin::Pin; use futures_core::ready; use futures_core::stream::{FusedStream, Stream, TryStream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; use crate::future::Either; use crate::stream::stream::flatten_unordered::{ FlattenUnorderedWithFlowController, FlowController, FlowStep, }; use crate::stream::IntoStream; use crate::TryStreamExt; delegate_all!( /// Stream for the [`try_flatten_unordered`](super::TryStreamExt::try_flatten_unordered) method. TryFlattenUnordered( FlattenUnorderedWithFlowController, PropagateBaseStreamError> ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + New[ |stream: St, limit: impl Into>| FlattenUnorderedWithFlowController::new( NestedTryStreamIntoEitherTryStream::new(stream), limit.into() ) ] where St: TryStream, St::Ok: TryStream, St::Ok: Unpin, ::Error: From ); pin_project! { /// Emits either successful streams or single-item streams containing the underlying errors. /// This's a wrapper for `FlattenUnordered` to reuse its logic over `TryStream`. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct NestedTryStreamIntoEitherTryStream where St: TryStream, St::Ok: TryStream, St::Ok: Unpin, ::Error: From { #[pin] stream: St } } impl NestedTryStreamIntoEitherTryStream where St: TryStream, St::Ok: TryStream + Unpin, ::Error: From, { fn new(stream: St) -> Self { Self { stream } } delegate_access_inner!(stream, St, ()); } /// Emits a single item immediately, then stream will be terminated. #[derive(Debug, Clone)] pub struct Single(Option); impl Single { /// Constructs new `Single` with the given value. fn new(val: T) -> Self { Self(Some(val)) } /// Attempts to take inner item immediately. Will always succeed if the stream isn't terminated. fn next_immediate(&mut self) -> Option { self.0.take() } } impl Unpin for Single {} impl Stream for Single { type Item = T; fn poll_next(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { Poll::Ready(self.0.take()) } fn size_hint(&self) -> (usize, Option) { self.0.as_ref().map_or((0, Some(0)), |_| (1, Some(1))) } } /// Immediately propagates errors occurred in the base stream. #[derive(Debug, Clone, Copy)] pub struct PropagateBaseStreamError(PhantomData); type BaseStreamItem = as Stream>::Item; type InnerStreamItem = as Stream>::Item; impl FlowController, InnerStreamItem> for PropagateBaseStreamError where St: TryStream, St::Ok: TryStream + Unpin, ::Error: From, { fn next_step(item: BaseStreamItem) -> FlowStep, InnerStreamItem> { match item { // A new successful inner stream received st @ Either::Left(_) => FlowStep::Continue(st), // An error encountered Either::Right(mut err) => FlowStep::Return(err.next_immediate().unwrap()), } } } type SingleStreamResult = Single::Ok, ::Error>>; impl Stream for NestedTryStreamIntoEitherTryStream where St: TryStream, St::Ok: TryStream + Unpin, ::Error: From, { // Item is either an inner stream or a stream containing a single error. // This will allow using `Either`'s `Stream` implementation as both branches are actually streams of `Result`'s. type Item = Either, SingleStreamResult>; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let item = ready!(self.project().stream.try_poll_next(cx)); let out = match item { Some(res) => match res { // Emit successful inner stream as is Ok(stream) => Either::Left(stream.into_stream()), // Wrap an error into a stream containing a single item err @ Err(_) => { let res = err.map(|_: St::Ok| unreachable!()).map_err(Into::into); Either::Right(Single::new(res)) } }, None => return Poll::Ready(None), }; Poll::Ready(Some(out)) } } impl FusedStream for NestedTryStreamIntoEitherTryStream where St: TryStream + FusedStream, St::Ok: TryStream + Unpin, ::Error: From, { fn is_terminated(&self) -> bool { self.stream.is_terminated() } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for NestedTryStreamIntoEitherTryStream where St: TryStream + Sink, St::Ok: TryStream + Unpin, ::Error: From<::Error>, { type Error = >::Error; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/try_stream/try_fold.rs000064400000000000000000000053261046102023000210300ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::{FusedFuture, Future, TryFuture}; use futures_core::ready; use futures_core::stream::TryStream; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`try_fold`](super::TryStreamExt::try_fold) method. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct TryFold { #[pin] stream: St, f: F, accum: Option, #[pin] future: Option, } } impl fmt::Debug for TryFold where St: fmt::Debug, Fut: fmt::Debug, T: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TryFold") .field("stream", &self.stream) .field("accum", &self.accum) .field("future", &self.future) .finish() } } impl TryFold where St: TryStream, F: FnMut(T, St::Ok) -> Fut, Fut: TryFuture, { pub(super) fn new(stream: St, f: F, t: T) -> Self { Self { stream, f, accum: Some(t), future: None } } } impl FusedFuture for TryFold where St: TryStream, F: FnMut(T, St::Ok) -> Fut, Fut: TryFuture, { fn is_terminated(&self) -> bool { self.accum.is_none() && self.future.is_none() } } impl Future for TryFold where St: TryStream, F: FnMut(T, St::Ok) -> Fut, Fut: TryFuture, { type Output = Result; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.project(); Poll::Ready(loop { if let Some(fut) = this.future.as_mut().as_pin_mut() { // we're currently processing a future to produce a new accum value let res = ready!(fut.try_poll(cx)); this.future.set(None); match res { Ok(a) => *this.accum = Some(a), Err(e) => break Err(e), } } else if this.accum.is_some() { // we're waiting on a new item from the stream let res = ready!(this.stream.as_mut().try_poll_next(cx)); let a = this.accum.take().unwrap(); match res { Some(Ok(item)) => this.future.set(Some((this.f)(a, item))), Some(Err(e)) => break Err(e), None => break Ok(a), } } else { panic!("Fold polled after completion") } }) } } futures-util-0.3.30/src/stream/try_stream/try_for_each.rs000064400000000000000000000034731046102023000216530ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::{Future, TryFuture}; use futures_core::ready; use futures_core::stream::TryStream; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the [`try_for_each`](super::TryStreamExt::try_for_each) method. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct TryForEach { #[pin] stream: St, f: F, #[pin] future: Option, } } impl fmt::Debug for TryForEach where St: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TryForEach") .field("stream", &self.stream) .field("future", &self.future) .finish() } } impl TryForEach where St: TryStream, F: FnMut(St::Ok) -> Fut, Fut: TryFuture, { pub(super) fn new(stream: St, f: F) -> Self { Self { stream, f, future: None } } } impl Future for TryForEach where St: TryStream, F: FnMut(St::Ok) -> Fut, Fut: TryFuture, { type Output = Result<(), St::Error>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.project(); loop { if let Some(fut) = this.future.as_mut().as_pin_mut() { ready!(fut.try_poll(cx))?; this.future.set(None); } else { match ready!(this.stream.as_mut().try_poll_next(cx)?) { Some(e) => this.future.set(Some((this.f)(e))), None => break, } } } Poll::Ready(Ok(())) } } futures-util-0.3.30/src/stream/try_stream/try_for_each_concurrent.rs000064400000000000000000000103541046102023000241110ustar 00000000000000use crate::stream::{FuturesUnordered, StreamExt}; use core::fmt; use core::mem; use core::num::NonZeroUsize; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::stream::TryStream; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future for the /// [`try_for_each_concurrent`](super::TryStreamExt::try_for_each_concurrent) /// method. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct TryForEachConcurrent { #[pin] stream: Option, f: F, futures: FuturesUnordered, limit: Option, } } impl fmt::Debug for TryForEachConcurrent where St: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TryForEachConcurrent") .field("stream", &self.stream) .field("futures", &self.futures) .field("limit", &self.limit) .finish() } } impl FusedFuture for TryForEachConcurrent where St: TryStream, F: FnMut(St::Ok) -> Fut, Fut: Future>, { fn is_terminated(&self) -> bool { self.stream.is_none() && self.futures.is_empty() } } impl TryForEachConcurrent where St: TryStream, F: FnMut(St::Ok) -> Fut, Fut: Future>, { pub(super) fn new(stream: St, limit: Option, f: F) -> Self { Self { stream: Some(stream), // Note: `limit` = 0 gets ignored. limit: limit.and_then(NonZeroUsize::new), f, futures: FuturesUnordered::new(), } } } impl Future for TryForEachConcurrent where St: TryStream, F: FnMut(St::Ok) -> Fut, Fut: Future>, { type Output = Result<(), St::Error>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.project(); loop { let mut made_progress_this_iter = false; // Check if we've already created a number of futures greater than `limit` if this.limit.map(|limit| limit.get() > this.futures.len()).unwrap_or(true) { let poll_res = match this.stream.as_mut().as_pin_mut() { Some(stream) => stream.try_poll_next(cx), None => Poll::Ready(None), }; let elem = match poll_res { Poll::Ready(Some(Ok(elem))) => { made_progress_this_iter = true; Some(elem) } Poll::Ready(None) => { this.stream.set(None); None } Poll::Pending => None, Poll::Ready(Some(Err(e))) => { // Empty the stream and futures so that we know // the future has completed. this.stream.set(None); drop(mem::replace(this.futures, FuturesUnordered::new())); return Poll::Ready(Err(e)); } }; if let Some(elem) = elem { this.futures.push((this.f)(elem)); } } match this.futures.poll_next_unpin(cx) { Poll::Ready(Some(Ok(()))) => made_progress_this_iter = true, Poll::Ready(None) => { if this.stream.is_none() { return Poll::Ready(Ok(())); } } Poll::Pending => {} Poll::Ready(Some(Err(e))) => { // Empty the stream and futures so that we know // the future has completed. this.stream.set(None); drop(mem::replace(this.futures, FuturesUnordered::new())); return Poll::Ready(Err(e)); } } if !made_progress_this_iter { return Poll::Pending; } } } } futures-util-0.3.30/src/stream/try_stream/try_next.rs000064400000000000000000000020301046102023000210470ustar 00000000000000use crate::stream::TryStreamExt; use core::pin::Pin; use futures_core::future::{FusedFuture, Future}; use futures_core::stream::{FusedStream, TryStream}; use futures_core::task::{Context, Poll}; /// Future for the [`try_next`](super::TryStreamExt::try_next) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct TryNext<'a, St: ?Sized> { stream: &'a mut St, } impl Unpin for TryNext<'_, St> {} impl<'a, St: ?Sized + TryStream + Unpin> TryNext<'a, St> { pub(super) fn new(stream: &'a mut St) -> Self { Self { stream } } } impl FusedFuture for TryNext<'_, St> { fn is_terminated(&self) -> bool { self.stream.is_terminated() } } impl Future for TryNext<'_, St> { type Output = Result, St::Error>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { self.stream.try_poll_next_unpin(cx)?.map(Ok) } } futures-util-0.3.30/src/stream/try_stream/try_ready_chunks.rs000064400000000000000000000100441046102023000225540ustar 00000000000000use crate::stream::{Fuse, IntoStream, StreamExt}; use alloc::vec::Vec; use core::fmt; use core::pin::Pin; use futures_core::stream::{FusedStream, Stream, TryStream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`try_ready_chunks`](super::TryStreamExt::try_ready_chunks) method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct TryReadyChunks { #[pin] stream: Fuse>, cap: usize, // https://github.com/rust-lang/futures-rs/issues/1475 } } impl TryReadyChunks { pub(super) fn new(stream: St, capacity: usize) -> Self { assert!(capacity > 0); Self { stream: IntoStream::new(stream).fuse(), cap: capacity } } delegate_access_inner!(stream, St, (. .)); } type TryReadyChunksStreamError = TryReadyChunksError<::Ok, ::Error>; impl Stream for TryReadyChunks { type Item = Result, TryReadyChunksStreamError>; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.as_mut().project(); let mut items: Vec = Vec::new(); loop { match this.stream.as_mut().poll_next(cx) { // Flush all the collected data if the underlying stream doesn't // contain more ready values Poll::Pending => { return if items.is_empty() { Poll::Pending } else { Poll::Ready(Some(Ok(items))) } } // Push the ready item into the buffer and check whether it is full. // If so, return the buffer. Poll::Ready(Some(Ok(item))) => { if items.is_empty() { items.reserve_exact(*this.cap); } items.push(item); if items.len() >= *this.cap { return Poll::Ready(Some(Ok(items))); } } // Return the already collected items and the error. Poll::Ready(Some(Err(e))) => { return Poll::Ready(Some(Err(TryReadyChunksError(items, e)))); } // Since the underlying stream ran out of values, return what we // have buffered, if we have anything. Poll::Ready(None) => { let last = if items.is_empty() { None } else { Some(Ok(items)) }; return Poll::Ready(last); } } } } fn size_hint(&self) -> (usize, Option) { let (lower, upper) = self.stream.size_hint(); let lower = lower / self.cap; (lower, upper) } } impl FusedStream for TryReadyChunks { fn is_terminated(&self) -> bool { self.stream.is_terminated() } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for TryReadyChunks where S: TryStream + Sink, { type Error = >::Error; delegate_sink!(stream, Item); } /// Error indicating, that while chunk was collected inner stream produced an error. /// /// Contains all items that were collected before an error occurred, and the stream error itself. #[derive(PartialEq, Eq)] pub struct TryReadyChunksError(pub Vec, pub E); impl fmt::Debug for TryReadyChunksError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.1.fmt(f) } } impl fmt::Display for TryReadyChunksError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.1.fmt(f) } } #[cfg(feature = "std")] impl std::error::Error for TryReadyChunksError {} futures-util-0.3.30/src/stream/try_stream/try_skip_while.rs000064400000000000000000000067341046102023000222460ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::TryFuture; use futures_core::ready; use futures_core::stream::{FusedStream, Stream, TryStream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`try_skip_while`](super::TryStreamExt::try_skip_while) /// method. #[must_use = "streams do nothing unless polled"] pub struct TrySkipWhile where St: TryStream { #[pin] stream: St, f: F, #[pin] pending_fut: Option, pending_item: Option, done_skipping: bool, } } impl fmt::Debug for TrySkipWhile where St: TryStream + fmt::Debug, St::Ok: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TrySkipWhile") .field("stream", &self.stream) .field("pending_fut", &self.pending_fut) .field("pending_item", &self.pending_item) .field("done_skipping", &self.done_skipping) .finish() } } impl TrySkipWhile where St: TryStream, F: FnMut(&St::Ok) -> Fut, Fut: TryFuture, { pub(super) fn new(stream: St, f: F) -> Self { Self { stream, f, pending_fut: None, pending_item: None, done_skipping: false } } delegate_access_inner!(stream, St, ()); } impl Stream for TrySkipWhile where St: TryStream, F: FnMut(&St::Ok) -> Fut, Fut: TryFuture, { type Item = Result; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); if *this.done_skipping { return this.stream.try_poll_next(cx); } Poll::Ready(loop { if let Some(fut) = this.pending_fut.as_mut().as_pin_mut() { let res = ready!(fut.try_poll(cx)); this.pending_fut.set(None); let skipped = res?; let item = this.pending_item.take(); if !skipped { *this.done_skipping = true; break item.map(Ok); } } else if let Some(item) = ready!(this.stream.as_mut().try_poll_next(cx)?) { this.pending_fut.set(Some((this.f)(&item))); *this.pending_item = Some(item); } else { break None; } }) } fn size_hint(&self) -> (usize, Option) { let pending_len = usize::from(self.pending_item.is_some()); let (_, upper) = self.stream.size_hint(); let upper = match upper { Some(x) => x.checked_add(pending_len), None => None, }; (0, upper) // can't know a lower bound, due to the predicate } } impl FusedStream for TrySkipWhile where St: TryStream + FusedStream, F: FnMut(&St::Ok) -> Fut, Fut: TryFuture, { fn is_terminated(&self) -> bool { self.pending_item.is_none() && self.stream.is_terminated() } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for TrySkipWhile where S: TryStream + Sink, { type Error = E; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/try_stream/try_take_while.rs000064400000000000000000000071451046102023000222210ustar 00000000000000use core::fmt; use core::pin::Pin; use futures_core::future::TryFuture; use futures_core::ready; use futures_core::stream::{FusedStream, Stream, TryStream}; use futures_core::task::{Context, Poll}; #[cfg(feature = "sink")] use futures_sink::Sink; use pin_project_lite::pin_project; pin_project! { /// Stream for the [`try_take_while`](super::TryStreamExt::try_take_while) /// method. #[must_use = "streams do nothing unless polled"] pub struct TryTakeWhile where St: TryStream, { #[pin] stream: St, f: F, #[pin] pending_fut: Option, pending_item: Option, done_taking: bool, } } impl fmt::Debug for TryTakeWhile where St: TryStream + fmt::Debug, St::Ok: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TryTakeWhile") .field("stream", &self.stream) .field("pending_fut", &self.pending_fut) .field("pending_item", &self.pending_item) .field("done_taking", &self.done_taking) .finish() } } impl TryTakeWhile where St: TryStream, F: FnMut(&St::Ok) -> Fut, Fut: TryFuture, { pub(super) fn new(stream: St, f: F) -> Self { Self { stream, f, pending_fut: None, pending_item: None, done_taking: false } } delegate_access_inner!(stream, St, ()); } impl Stream for TryTakeWhile where St: TryStream, F: FnMut(&St::Ok) -> Fut, Fut: TryFuture, { type Item = Result; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); if *this.done_taking { return Poll::Ready(None); } Poll::Ready(loop { if let Some(fut) = this.pending_fut.as_mut().as_pin_mut() { let res = ready!(fut.try_poll(cx)); this.pending_fut.set(None); let take = res?; let item = this.pending_item.take(); if take { break item.map(Ok); } else { *this.done_taking = true; break None; } } else if let Some(item) = ready!(this.stream.as_mut().try_poll_next(cx)?) { this.pending_fut.set(Some((this.f)(&item))); *this.pending_item = Some(item); } else { break None; } }) } fn size_hint(&self) -> (usize, Option) { if self.done_taking { return (0, Some(0)); } let pending_len = usize::from(self.pending_item.is_some()); let (_, upper) = self.stream.size_hint(); let upper = match upper { Some(x) => x.checked_add(pending_len), None => None, }; (0, upper) // can't know a lower bound, due to the predicate } } impl FusedStream for TryTakeWhile where St: TryStream + FusedStream, F: FnMut(&St::Ok) -> Fut, Fut: TryFuture, { fn is_terminated(&self) -> bool { self.done_taking || self.pending_item.is_none() && self.stream.is_terminated() } } // Forwarding impl of Sink from the underlying stream #[cfg(feature = "sink")] impl Sink for TryTakeWhile where S: TryStream + Sink, { type Error = E; delegate_sink!(stream, Item); } futures-util-0.3.30/src/stream/try_stream/try_unfold.rs000064400000000000000000000075171046102023000213770ustar 00000000000000use super::assert_stream; use core::fmt; use core::pin::Pin; use futures_core::future::TryFuture; use futures_core::ready; use futures_core::stream::Stream; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; /// Creates a `TryStream` from a seed and a closure returning a `TryFuture`. /// /// This function is the dual for the `TryStream::try_fold()` adapter: while /// `TryStream::try_fold()` reduces a `TryStream` to one single value, /// `try_unfold()` creates a `TryStream` from a seed value. /// /// `try_unfold()` will call the provided closure with the provided seed, then /// wait for the returned `TryFuture` to complete with `(a, b)`. It will then /// yield the value `a`, and use `b` as the next internal state. /// /// If the closure returns `None` instead of `Some(TryFuture)`, then the /// `try_unfold()` will stop producing items and return `Poll::Ready(None)` in /// future calls to `poll()`. /// /// In case of error generated by the returned `TryFuture`, the error will be /// returned by the `TryStream`. The `TryStream` will then yield /// `Poll::Ready(None)` in future calls to `poll()`. /// /// This function can typically be used when wanting to go from the "world of /// futures" to the "world of streams": the provided closure can build a /// `TryFuture` using other library functions working on futures, and /// `try_unfold()` will turn it into a `TryStream` by repeating the operation. /// /// # Example /// /// ``` /// # #[derive(Debug, PartialEq)] /// # struct SomeError; /// # futures::executor::block_on(async { /// use futures::stream::{self, TryStreamExt}; /// /// let stream = stream::try_unfold(0, |state| async move { /// if state < 0 { /// return Err(SomeError); /// } /// /// if state <= 2 { /// let next_state = state + 1; /// let yielded = state * 2; /// Ok(Some((yielded, next_state))) /// } else { /// Ok(None) /// } /// }); /// /// let result: Result, _> = stream.try_collect().await; /// assert_eq!(result, Ok(vec![0, 2, 4])); /// # }); /// ``` pub fn try_unfold(init: T, f: F) -> TryUnfold where F: FnMut(T) -> Fut, Fut: TryFuture>, { assert_stream::, _>(TryUnfold { f, state: Some(init), fut: None }) } pin_project! { /// Stream for the [`try_unfold`] function. #[must_use = "streams do nothing unless polled"] pub struct TryUnfold { f: F, state: Option, #[pin] fut: Option, } } impl fmt::Debug for TryUnfold where T: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TryUnfold").field("state", &self.state).field("fut", &self.fut).finish() } } impl Stream for TryUnfold where F: FnMut(T) -> Fut, Fut: TryFuture>, { type Item = Result; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); if let Some(state) = this.state.take() { this.fut.set(Some((this.f)(state))); } match this.fut.as_mut().as_pin_mut() { None => { // The future previously errored Poll::Ready(None) } Some(future) => { let step = ready!(future.try_poll(cx)); this.fut.set(None); match step { Ok(Some((item, next_state))) => { *this.state = Some(next_state); Poll::Ready(Some(Ok(item))) } Ok(None) => Poll::Ready(None), Err(e) => Poll::Ready(Some(Err(e))), } } } } } futures-util-0.3.30/src/stream/unfold.rs000064400000000000000000000070461046102023000163050ustar 00000000000000use super::assert_stream; use crate::unfold_state::UnfoldState; use core::fmt; use core::pin::Pin; use futures_core::future::Future; use futures_core::ready; use futures_core::stream::{FusedStream, Stream}; use futures_core::task::{Context, Poll}; use pin_project_lite::pin_project; /// Creates a `Stream` from a seed and a closure returning a `Future`. /// /// This function is the dual for the `Stream::fold()` adapter: while /// `Stream::fold()` reduces a `Stream` to one single value, `unfold()` creates a /// `Stream` from a seed value. /// /// `unfold()` will call the provided closure with the provided seed, then wait /// for the returned `Future` to complete with `(a, b)`. It will then yield the /// value `a`, and use `b` as the next internal state. /// /// If the closure returns `None` instead of `Some(Future)`, then the `unfold()` /// will stop producing items and return `Poll::Ready(None)` in future /// calls to `poll()`. /// /// This function can typically be used when wanting to go from the "world of /// futures" to the "world of streams": the provided closure can build a /// `Future` using other library functions working on futures, and `unfold()` /// will turn it into a `Stream` by repeating the operation. /// /// # Example /// /// ``` /// # futures::executor::block_on(async { /// use futures::stream::{self, StreamExt}; /// /// let stream = stream::unfold(0, |state| async move { /// if state <= 2 { /// let next_state = state + 1; /// let yielded = state * 2; /// Some((yielded, next_state)) /// } else { /// None /// } /// }); /// /// let result = stream.collect::>().await; /// assert_eq!(result, vec![0, 2, 4]); /// # }); /// ``` pub fn unfold(init: T, f: F) -> Unfold where F: FnMut(T) -> Fut, Fut: Future>, { assert_stream::(Unfold { f, state: UnfoldState::Value { value: init } }) } pin_project! { /// Stream for the [`unfold`] function. #[must_use = "streams do nothing unless polled"] pub struct Unfold { f: F, #[pin] state: UnfoldState, } } impl fmt::Debug for Unfold where T: fmt::Debug, Fut: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Unfold").field("state", &self.state).finish() } } impl FusedStream for Unfold where F: FnMut(T) -> Fut, Fut: Future>, { fn is_terminated(&self) -> bool { if let UnfoldState::Empty = self.state { true } else { false } } } impl Stream for Unfold where F: FnMut(T) -> Fut, Fut: Future>, { type Item = Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); if let Some(state) = this.state.as_mut().take_value() { this.state.set(UnfoldState::Future { future: (this.f)(state) }); } let step = match this.state.as_mut().project_future() { Some(fut) => ready!(fut.poll(cx)), None => panic!("Unfold must not be polled after it returned `Poll::Ready(None)`"), }; if let Some((item, next_state)) = step { this.state.set(UnfoldState::Value { value: next_state }); Poll::Ready(Some(item)) } else { this.state.set(UnfoldState::Empty); Poll::Ready(None) } } } futures-util-0.3.30/src/task/mod.rs000064400000000000000000000024021046102023000152330ustar 00000000000000//! Tools for working with tasks. //! //! This module contains: //! //! - [`Spawn`], a trait for spawning new tasks. //! - [`Context`], a context of an asynchronous task, //! including a handle for waking up the task. //! - [`Waker`], a handle for waking up a task. //! //! The remaining types and traits in the module are used for implementing //! executors or dealing with synchronization issues around task wakeup. #[doc(no_inline)] pub use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker}; pub use futures_task::{FutureObj, LocalFutureObj, LocalSpawn, Spawn, SpawnError, UnsafeFutureObj}; pub use futures_task::noop_waker; pub use futures_task::noop_waker_ref; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] pub use futures_task::ArcWake; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] pub use futures_task::waker; #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[cfg(feature = "alloc")] pub use futures_task::{waker_ref, WakerRef}; #[cfg_attr( target_os = "none", cfg(any(target_has_atomic = "ptr", feature = "portable-atomic")) )] pub use futures_core::task::__internal::AtomicWaker; mod spawn; pub use self::spawn::{LocalSpawnExt, SpawnExt}; futures-util-0.3.30/src/task/spawn.rs000064400000000000000000000137711046102023000156170ustar 00000000000000use futures_task::{LocalSpawn, Spawn}; #[cfg(feature = "compat")] use crate::compat::Compat; #[cfg(feature = "channel")] #[cfg(feature = "std")] use crate::future::{FutureExt, RemoteHandle}; #[cfg(feature = "alloc")] use alloc::boxed::Box; #[cfg(feature = "alloc")] use futures_core::future::Future; #[cfg(feature = "alloc")] use futures_task::{FutureObj, LocalFutureObj, SpawnError}; impl SpawnExt for Sp where Sp: Spawn {} impl LocalSpawnExt for Sp where Sp: LocalSpawn {} /// Extension trait for `Spawn`. pub trait SpawnExt: Spawn { /// Spawns a task that polls the given future with output `()` to /// completion. /// /// This method returns a [`Result`] that contains a [`SpawnError`] if /// spawning fails. /// /// You can use [`spawn_with_handle`](SpawnExt::spawn_with_handle) if /// you want to spawn a future with output other than `()` or if you want /// to be able to await its completion. /// /// Note this method will eventually be replaced with the upcoming /// `Spawn::spawn` method which will take a `dyn Future` as input. /// Technical limitations prevent `Spawn::spawn` from being implemented /// today. Feel free to use this method in the meantime. /// /// ``` /// # { /// use futures::executor::ThreadPool; /// use futures::task::SpawnExt; /// /// let executor = ThreadPool::new().unwrap(); /// /// let future = async { /* ... */ }; /// executor.spawn(future).unwrap(); /// # } /// # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 /// ``` #[cfg(feature = "alloc")] fn spawn(&self, future: Fut) -> Result<(), SpawnError> where Fut: Future + Send + 'static, { self.spawn_obj(FutureObj::new(Box::new(future))) } /// Spawns a task that polls the given future to completion and returns a /// future that resolves to the spawned future's output. /// /// This method returns a [`Result`] that contains a [`RemoteHandle`](crate::future::RemoteHandle), or, if /// spawning fails, a [`SpawnError`]. [`RemoteHandle`](crate::future::RemoteHandle) is a future that /// resolves to the output of the spawned future. /// /// ``` /// # { /// use futures::executor::{block_on, ThreadPool}; /// use futures::future; /// use futures::task::SpawnExt; /// /// let executor = ThreadPool::new().unwrap(); /// /// let future = future::ready(1); /// let join_handle_fut = executor.spawn_with_handle(future).unwrap(); /// assert_eq!(block_on(join_handle_fut), 1); /// # } /// # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 /// ``` #[cfg(feature = "channel")] #[cfg_attr(docsrs, doc(cfg(feature = "channel")))] #[cfg(feature = "std")] fn spawn_with_handle(&self, future: Fut) -> Result, SpawnError> where Fut: Future + Send + 'static, Fut::Output: Send, { let (future, handle) = future.remote_handle(); self.spawn(future)?; Ok(handle) } /// Wraps a [`Spawn`] and makes it usable as a futures 0.1 `Executor`. /// Requires the `compat` feature to enable. #[cfg(feature = "compat")] #[cfg_attr(docsrs, doc(cfg(feature = "compat")))] fn compat(self) -> Compat where Self: Sized, { Compat::new(self) } } /// Extension trait for `LocalSpawn`. pub trait LocalSpawnExt: LocalSpawn { /// Spawns a task that polls the given future with output `()` to /// completion. /// /// This method returns a [`Result`] that contains a [`SpawnError`] if /// spawning fails. /// /// You can use [`spawn_with_handle`](SpawnExt::spawn_with_handle) if /// you want to spawn a future with output other than `()` or if you want /// to be able to await its completion. /// /// Note this method will eventually be replaced with the upcoming /// `Spawn::spawn` method which will take a `dyn Future` as input. /// Technical limitations prevent `Spawn::spawn` from being implemented /// today. Feel free to use this method in the meantime. /// /// ``` /// use futures::executor::LocalPool; /// use futures::task::LocalSpawnExt; /// /// let executor = LocalPool::new(); /// let spawner = executor.spawner(); /// /// let future = async { /* ... */ }; /// spawner.spawn_local(future).unwrap(); /// ``` #[cfg(feature = "alloc")] fn spawn_local(&self, future: Fut) -> Result<(), SpawnError> where Fut: Future + 'static, { self.spawn_local_obj(LocalFutureObj::new(Box::new(future))) } /// Spawns a task that polls the given future to completion and returns a /// future that resolves to the spawned future's output. /// /// This method returns a [`Result`] that contains a [`RemoteHandle`](crate::future::RemoteHandle), or, if /// spawning fails, a [`SpawnError`]. [`RemoteHandle`](crate::future::RemoteHandle) is a future that /// resolves to the output of the spawned future. /// /// ``` /// use futures::executor::LocalPool; /// use futures::task::LocalSpawnExt; /// /// let mut executor = LocalPool::new(); /// let spawner = executor.spawner(); /// /// let future = async { 1 }; /// let join_handle_fut = spawner.spawn_local_with_handle(future).unwrap(); /// assert_eq!(executor.run_until(join_handle_fut), 1); /// ``` #[cfg(feature = "channel")] #[cfg_attr(docsrs, doc(cfg(feature = "channel")))] #[cfg(feature = "std")] fn spawn_local_with_handle( &self, future: Fut, ) -> Result, SpawnError> where Fut: Future + 'static, { let (future, handle) = future.remote_handle(); self.spawn_local(future)?; Ok(handle) } } futures-util-0.3.30/src/unfold_state.rs000064400000000000000000000017501046102023000162060ustar 00000000000000use core::pin::Pin; use pin_project_lite::pin_project; pin_project! { /// UnfoldState used for stream and sink unfolds #[project = UnfoldStateProj] #[project_replace = UnfoldStateProjReplace] #[derive(Debug)] pub(crate) enum UnfoldState { Value { value: T, }, Future { #[pin] future: R, }, Empty, } } impl UnfoldState { pub(crate) fn project_future(self: Pin<&mut Self>) -> Option> { match self.project() { UnfoldStateProj::Future { future } => Some(future), _ => None, } } pub(crate) fn take_value(self: Pin<&mut Self>) -> Option { match &*self { UnfoldState::Value { .. } => match self.project_replace(UnfoldState::Empty) { UnfoldStateProjReplace::Value { value } => Some(value), _ => unreachable!(), }, _ => None, } } }