futures-lite-1.12.0/.cargo_vcs_info.json0000644000000001120000000000000135360ustar { "git": { "sha1": "7b1f141c725738e3edadcef8a21e801bfa8b4870" } } futures-lite-1.12.0/.github/workflows/build-and-test.yaml000064400000000000000000000037240000000000000214150ustar 00000000000000name: Build and test on: push: branches: - master pull_request: jobs: build_and_test: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest] rust: [nightly, beta, stable, 1.45.2, 1.42.0] steps: - uses: actions/checkout@v2 - name: Install latest ${{ matrix.rust }} uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.rust }} profile: minimal override: true - name: Run cargo check with all features uses: actions-rs/cargo@v1 with: command: check args: --all --bins --examples --tests --all-features - name: Run cargo check with no features uses: actions-rs/cargo@v1 with: command: check args: --all --bins --examples --tests --no-default-features - name: Run cargo check with alloc feature uses: actions-rs/cargo@v1 with: command: check args: --all --bins --examples --tests --no-default-features --features alloc - name: Run cargo check (without dev-dependencies to catch missing feature flags) if: startsWith(matrix.rust, 'nightly') uses: actions-rs/cargo@v1 with: command: check args: -Z features=dev_dep - name: Run cargo test uses: actions-rs/cargo@v1 with: command: test - name: Run cargo test with no features uses: actions-rs/cargo@v1 with: command: test args: --no-default-features - name: Run cargo test with alloc feature uses: actions-rs/cargo@v1 with: command: test args: --no-default-features --features alloc - name: Install thumbv7m-none-eabi target run: rustup target add thumbv7m-none-eabi - name: Compile for thumbv7m-none-eabi target run: cargo build --no-default-features --target thumbv7m-none-eabi futures-lite-1.12.0/.github/workflows/lint.yaml000064400000000000000000000006740000000000000175500ustar 00000000000000name: Lint on: push: branches: - master pull_request: jobs: clippy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: toolchain: stable profile: minimal components: clippy - uses: actions-rs/clippy-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} args: --all-features -- -W clippy::all futures-lite-1.12.0/.github/workflows/security.yaml000064400000000000000000000004240000000000000204420ustar 00000000000000name: Security audit on: push: branches: - master pull_request: jobs: security_audit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions-rs/audit-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} futures-lite-1.12.0/.gitignore000064400000000000000000000000230000000000000142750ustar 00000000000000/target Cargo.lock futures-lite-1.12.0/CHANGELOG.md000064400000000000000000000056030000000000000141270ustar 00000000000000# Version 1.12.0 - Implement `BufRead` for `BlockOn` # Version 1.11.3 - Update `pin-project-lite`. # Version 1.11.2 - Improve docs for `ready!`. # Version 1.11.1 - Fix some typos. # Version 1.11.0 - Add the new `prelude` module. - Deprecate trait re-exports in the root module. # Version 1.10.1 - Fix compilation errors with Rust 1.42.0 and 1.45.2 # Version 1.10.0 - Add `io::split()`. # Version 1.9.0 - Add `FutureExt::poll()`. - Add `StreamExt::poll_next()`. - Add `AsyncBufReadExt::fill_buf()`. - Add `AsyncBufReadExt::consume()`. # Version 1.8.0 - Add `BoxedReader` and `BoxedWriter`. # Version 1.7.0 - Implement `AsyncRead` for `Bytes`. - Add `StreamExt::then()`. # Version 1.6.0 - Add `FutureExt::catch_unwind()`. # Version 1.5.0 - Add `stream::race()` and `StreamExt::race()`. # Version 1.4.0 - Add `alloc` Cargo feature. # Version 1.3.0 - Add `future::or()`. - Add `FutureExt::race()`. - Disable `waker-fn` dependency on `#![no_std]` targets. # Version 1.2.0 - Fix compilation errors on `#![no_std]` systems. - Add `StreamExt::try_next()`. - Add `StreamExt::partition()`. - Add `StreamExt::for_each()`. - Add `StreamExt::try_for_each()`. - Add `StreamExt::zip()`. - Add `StreamExt::unzip()`. - Add `StreamExt::nth()`. - Add `StreamExt::last()`. - Add `StreamExt::find()`. - Add `StreamExt::find_map()`. - Add `StreamExt::position()`. - Add `StreamExt::all()`. - Add `StreamExt::any()`. - Add `StreamExt::scan()`. - Add `StreamExt::flat_map()`. - Add `StreamExt::flatten()`. - Add `StreamExt::skip()`. - Add `StreamExt::skip_while()`. # Version 1.1.0 - Add `StreamExt::take()`. - Add `StreamExt::take_while()`. - Add `StreamExt::step_by()`. - Add `StreamExt::fuse()`. - Add `StreamExt::chain()`. - Add `StreamExt::cloned()`. - Add `StreamExt::copied()`. - Add `StreamExt::cycle()`. - Add `StreamExt::enumeraate()`. - Add `StreamExt::inspect()`. - Parametrize `FutureExt::boxed()` and `FutureExt::boxed_local()` over a lifetime. - Parametrize `StreamExt::boxed()` and `StreamExt::boxed_local()` over a lifetime. # Version 1.0.0 - Add `StreamExt::map()`. - Add `StreamExt::count()`. - Add `StreamExt::filter()`. - Add `StreamExt::filter_map()`. - Rename `future::join()` to `future::zip()`. - Rename `future::try_join()` to `future::try_zip()`. # Version 0.1.11 - Update `parking` to v2.0.0 # Version 0.1.10 - Add `AssertAsync`. # Version 0.1.9 - Add `FutureExt::or()`. - Put `#[must_use]` on all futures and streams. # Version 0.1.8 - Fix lints about unsafe code. # Version 0.1.7 - Add blocking APIs (`block_on()` and `BlockOn`). # Version 0.1.6 - Add `boxed()`, `boxed_local()`, `Boxed`, and `BoxedLocal`. # Version 0.1.5 - Add `fold()` and `try_fold()`. # Version 0.1.4 - Add `future::race()`. - Fix a bug in `BufReader`. # Version 0.1.3 - Add `future::join()`, `future::try_join()`, and `AsyncWriteExt::close()`. # Version 0.1.2 - Lots of new APIs. # Version 0.1.1 - Initial version futures-lite-1.12.0/Cargo.toml0000644000000030650000000000000115460ustar # 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 believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] edition = "2018" name = "futures-lite" version = "1.12.0" authors = ["Stjepan Glavina ", "Contributors to futures-rs"] description = "Futures, streams, and async I/O combinators" homepage = "https://github.com/smol-rs/futures-lite" documentation = "https://docs.rs/futures-lite" keywords = ["asynchronous", "futures", "async"] categories = ["asynchronous", "concurrency"] license = "Apache-2.0 OR MIT" repository = "https://github.com/smol-rs/futures-lite" [dependencies.fastrand] version = "1.3.4" optional = true [dependencies.futures-core] version = "0.3.5" default-features = false [dependencies.futures-io] version = "0.3.5" optional = true [dependencies.memchr] version = "2.3.3" optional = true [dependencies.parking] version = "2.0.0" optional = true [dependencies.pin-project-lite] version = "0.2.0" [dependencies.waker-fn] version = "1.0.0" optional = true [dev-dependencies.spin_on] version = "0.1.0" [features] alloc = [] default = ["std"] std = ["alloc", "fastrand", "futures-io", "parking", "memchr", "waker-fn"] futures-lite-1.12.0/Cargo.toml.orig000064400000000000000000000017530000000000000152070ustar 00000000000000[package] name = "futures-lite" version = "1.12.0" authors = [ "Stjepan Glavina ", "Contributors to futures-rs", ] edition = "2018" description = "Futures, streams, and async I/O combinators" license = "Apache-2.0 OR MIT" repository = "https://github.com/smol-rs/futures-lite" homepage = "https://github.com/smol-rs/futures-lite" documentation = "https://docs.rs/futures-lite" keywords = ["asynchronous", "futures", "async"] categories = ["asynchronous", "concurrency"] [features] default = ["std"] std = ["alloc", "fastrand", "futures-io", "parking", "memchr", "waker-fn"] alloc = [] [dependencies] fastrand = { version = "1.3.4", optional = true } futures-core = { version = "0.3.5", default-features = false } futures-io = { version = "0.3.5", optional = true } memchr = { version = "2.3.3", optional = true } parking = { version = "2.0.0", optional = true } pin-project-lite = "0.2.0" waker-fn = { version = "1.0.0", optional = true } [dev-dependencies] spin_on = "0.1.0" futures-lite-1.12.0/LICENSE-APACHE000064400000000000000000000251370000000000000142460ustar 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 [yyyy] [name of copyright owner] 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-lite-1.12.0/LICENSE-MIT000064400000000000000000000017770000000000000137620ustar 00000000000000Permission 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-lite-1.12.0/LICENSE-THIRD-PARTY000064400000000000000000000034710000000000000150710ustar 00000000000000=============================================================================== 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. =============================================================================== Copyright (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-lite-1.12.0/README.md000064400000000000000000000026550000000000000136010ustar 00000000000000# futures-lite [![Build](https://github.com/smol-rs/futures-lite/workflows/Build%20and%20test/badge.svg)]( https://github.com/smol-rs/futures-lite/actions) [![License](https://img.shields.io/badge/license-Apache--2.0_OR_MIT-blue.svg)]( https://github.com/smol-rs/futures-lite) [![Cargo](https://img.shields.io/crates/v/futures-lite.svg)]( https://crates.io/crates/futures-lite) [![Documentation](https://docs.rs/futures-lite/badge.svg)]( https://docs.rs/futures-lite) A lightweight async prelude. This crate is a subset of [futures] that compiles an order of magnitude faster, fixes minor warts in its API, fills in some obvious gaps, and removes almost all unsafe code from it. In short, this crate aims to be more enjoyable than [futures] but still fully compatible with it. [futures]: https://docs.rs/futures ## Examples ```rust use futures_lite::future; fn main() { future::block_on(async { println!("Hello world!"); }) } ``` ## License Licensed under either of * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) at your option. #### Contribution 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-lite-1.12.0/src/future.rs000064400000000000000000000501470000000000000147700ustar 00000000000000//! Combinators for the [`Future`] trait. //! //! # Examples //! //! ``` //! use futures_lite::future; //! //! # spin_on::spin_on(async { //! for step in 0..3 { //! println!("step {}", step); //! //! // Give other tasks a chance to run. //! future::yield_now().await; //! } //! # }); //! ``` #[cfg(feature = "alloc")] extern crate alloc; #[doc(no_inline)] pub use core::future::Future; use core::fmt; use core::marker::PhantomData; use core::pin::Pin; use pin_project_lite::pin_project; #[cfg(feature = "std")] use std::{ any::Any, panic::{catch_unwind, AssertUnwindSafe, UnwindSafe}, }; #[cfg(feature = "alloc")] use alloc::boxed::Box; use core::task::{Context, Poll}; /// Blocks the current thread on a future. /// /// # Examples /// /// ``` /// use futures_lite::future; /// /// let val = future::block_on(async { /// 1 + 2 /// }); /// /// assert_eq!(val, 3); /// ``` #[cfg(feature = "std")] pub fn block_on(future: impl Future) -> T { use std::cell::RefCell; use std::task::Waker; use parking::Parker; use waker_fn::waker_fn; // Pin the future on the stack. crate::pin!(future); // Creates a parker and an associated waker that unparks it. fn parker_and_waker() -> (Parker, Waker) { let parker = Parker::new(); let unparker = parker.unparker(); let waker = waker_fn(move || { unparker.unpark(); }); (parker, waker) } thread_local! { // Cached parker and waker for efficiency. static CACHE: RefCell<(Parker, Waker)> = RefCell::new(parker_and_waker()); } CACHE.with(|cache| { // Try grabbing the cached parker and waker. match cache.try_borrow_mut() { Ok(cache) => { // Use the cached parker and waker. let (parker, waker) = &*cache; let cx = &mut Context::from_waker(&waker); // Keep polling until the future is ready. loop { match future.as_mut().poll(cx) { Poll::Ready(output) => return output, Poll::Pending => parker.park(), } } } Err(_) => { // Looks like this is a recursive `block_on()` call. // Create a fresh parker and waker. let (parker, waker) = parker_and_waker(); let cx = &mut Context::from_waker(&waker); // Keep polling until the future is ready. loop { match future.as_mut().poll(cx) { Poll::Ready(output) => return output, Poll::Pending => parker.park(), } } } } }) } /// Creates a future that is always pending. /// /// # Examples /// /// ```no_run /// use futures_lite::future; /// /// # spin_on::spin_on(async { /// future::pending::<()>().await; /// unreachable!(); /// # }) /// ``` pub fn pending() -> Pending { Pending { _marker: PhantomData, } } /// Future for the [`pending()`] function. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Pending { _marker: PhantomData, } impl Unpin for Pending {} impl fmt::Debug for Pending { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Pending").finish() } } impl Future for Pending { type Output = T; fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll { Poll::Pending } } /// Polls a future just once and returns an [`Option`] with the result. /// /// # Examples /// /// ``` /// use futures_lite::future; /// /// # spin_on::spin_on(async { /// assert_eq!(future::poll_once(future::pending::<()>()).await, None); /// assert_eq!(future::poll_once(future::ready(42)).await, Some(42)); /// # }) /// ``` pub fn poll_once(f: F) -> PollOnce where F: Future, { PollOnce { f } } pin_project! { /// Future for the [`poll_once()`] function. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct PollOnce { #[pin] f: F, } } impl fmt::Debug for PollOnce { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("PollOnce").finish() } } impl Future for PollOnce where F: Future, { type Output = Option; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { match self.project().f.poll(cx) { Poll::Ready(t) => Poll::Ready(Some(t)), Poll::Pending => Poll::Ready(None), } } } /// Creates a future from a function returning [`Poll`]. /// /// # Examples /// /// ``` /// use futures_lite::future; /// use std::task::{Context, Poll}; /// /// # spin_on::spin_on(async { /// fn f(_: &mut Context<'_>) -> Poll { /// Poll::Ready(7) /// } /// /// assert_eq!(future::poll_fn(f).await, 7); /// # }) /// ``` pub fn poll_fn(f: F) -> PollFn where F: FnMut(&mut Context<'_>) -> Poll, { PollFn { f } } pin_project! { /// Future for the [`poll_fn()`] function. #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct PollFn { f: 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(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.project(); (this.f)(cx) } } /// Creates a future that resolves to the provided value. /// /// # Examples /// /// ``` /// use futures_lite::future; /// /// # spin_on::spin_on(async { /// assert_eq!(future::ready(7).await, 7); /// # }) /// ``` pub fn ready(val: T) -> Ready { Ready(Some(val)) } /// Future for the [`ready()`] function. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Ready(Option); impl Unpin for Ready {} impl Future for Ready { type Output = T; fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll { Poll::Ready(self.0.take().expect("`Ready` polled after completion")) } } /// Wakes the current task and returns [`Poll::Pending`] once. /// /// This function is useful when we want to cooperatively give time to the task scheduler. It is /// generally a good idea to yield inside loops because that way we make sure long-running tasks /// don't prevent other tasks from running. /// /// # Examples /// /// ``` /// use futures_lite::future; /// /// # spin_on::spin_on(async { /// future::yield_now().await; /// # }) /// ``` pub fn yield_now() -> YieldNow { YieldNow(false) } /// Future for the [`yield_now()`] function. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct YieldNow(bool); impl Future for YieldNow { type Output = (); fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { if !self.0 { self.0 = true; cx.waker().wake_by_ref(); Poll::Pending } else { Poll::Ready(()) } } } /// Joins two futures, waiting for both to complete. /// /// # Examples /// /// ``` /// use futures_lite::future; /// /// # spin_on::spin_on(async { /// let a = async { 1 }; /// let b = async { 2 }; /// /// assert_eq!(future::zip(a, b).await, (1, 2)); /// # }) /// ``` pub fn zip(future1: F1, future2: F2) -> Zip where F1: Future, F2: Future, { Zip { future1: future1, output1: None, future2: future2, output2: None, } } pin_project! { /// Future for the [`zip()`] function. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Zip where F1: Future, F2: Future, { #[pin] future1: F1, output1: Option, #[pin] future2: F2, output2: Option, } } impl Future for Zip where F1: Future, F2: Future, { type Output = (F1::Output, F2::Output); fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.project(); if this.output1.is_none() { if let Poll::Ready(out) = this.future1.poll(cx) { *this.output1 = Some(out); } } if this.output2.is_none() { if let Poll::Ready(out) = this.future2.poll(cx) { *this.output2 = Some(out); } } if this.output1.is_some() && this.output2.is_some() { Poll::Ready((this.output1.take().unwrap(), this.output2.take().unwrap())) } else { Poll::Pending } } } /// Joins two fallible futures, waiting for both to complete or one of them to error. /// /// # Examples /// /// ``` /// use futures_lite::future; /// /// # spin_on::spin_on(async { /// let a = async { Ok::(1) }; /// let b = async { Err::(2) }; /// /// assert_eq!(future::try_zip(a, b).await, Err(2)); /// # }) /// ``` pub fn try_zip(future1: F1, future2: F2) -> TryZip where F1: Future>, F2: Future>, { TryZip { future1: future1, output1: None, future2: future2, output2: None, } } pin_project! { /// Future for the [`try_zip()`] function. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct TryZip where F1: Future, F2: Future, { #[pin] future1: F1, output1: Option, #[pin] future2: F2, output2: Option, } } impl Future for TryZip where F1: Future>, F2: Future>, { type Output = Result<(T1, T2), E>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.project(); if this.output1.is_none() { if let Poll::Ready(out) = this.future1.poll(cx) { match out { Ok(t) => *this.output1 = Some(Ok(t)), Err(err) => return Poll::Ready(Err(err)), } } } if this.output2.is_none() { if let Poll::Ready(out) = this.future2.poll(cx) { match out { Ok(t) => *this.output2 = Some(Ok(t)), Err(err) => return Poll::Ready(Err(err)), } } } if this.output1.is_some() && this.output2.is_some() { let res1 = this.output1.take().unwrap(); let res2 = this.output2.take().unwrap(); let t1 = res1.map_err(|_| unreachable!()).unwrap(); let t2 = res2.map_err(|_| unreachable!()).unwrap(); Poll::Ready(Ok((t1, t2))) } else { Poll::Pending } } } /// Returns the result of the future that completes first, preferring `future1` if both are ready. /// /// If you need to treat the two futures fairly without a preference for either, use the [`race()`] /// function or the [`FutureExt::race()`] method. /// /// # Examples /// /// ``` /// use futures_lite::future::{self, pending, ready}; /// /// # spin_on::spin_on(async { /// assert_eq!(future::or(ready(1), pending()).await, 1); /// assert_eq!(future::or(pending(), ready(2)).await, 2); /// /// // The first future wins. /// assert_eq!(future::or(ready(1), ready(2)).await, 1); /// # }) /// ``` pub fn or(future1: F1, future2: F2) -> Or where F1: Future, F2: Future, { Or { future1, future2 } } pin_project! { /// Future for the [`or()`] function and the [`FutureExt::or()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Or { #[pin] future1: F1, #[pin] future2: F2, } } impl Future for Or where F1: Future, F2: Future, { type Output = T; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.project(); if let Poll::Ready(t) = this.future1.poll(cx) { return Poll::Ready(t); } if let Poll::Ready(t) = this.future2.poll(cx) { return Poll::Ready(t); } Poll::Pending } } /// Returns the result of the future that completes first, with no preference if both are ready. /// /// Each time [`Race`] is polled, the two inner futures are polled in random order. Therefore, no /// future takes precedence over the other if both can complete at the same time. /// /// If you have preference for one of the futures, use the [`or()`] function or the /// [`FutureExt::or()`] method. /// /// # Examples /// /// ``` /// use futures_lite::future::{self, pending, ready}; /// /// # spin_on::spin_on(async { /// assert_eq!(future::race(ready(1), pending()).await, 1); /// assert_eq!(future::race(pending(), ready(2)).await, 2); /// /// // One of the two futures is randomly chosen as the winner. /// let res = future::race(ready(1), ready(2)).await; /// # }) /// ``` #[cfg(feature = "std")] pub fn race(future1: F1, future2: F2) -> Race where F1: Future, F2: Future, { Race { future1, future2 } } #[cfg(feature = "std")] pin_project! { /// Future for the [`race()`] function and the [`FutureExt::race()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Race { #[pin] future1: F1, #[pin] future2: F2, } } #[cfg(feature = "std")] impl Future for Race where F1: Future, F2: Future, { type Output = T; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.project(); if fastrand::bool() { if let Poll::Ready(t) = this.future1.poll(cx) { return Poll::Ready(t); } if let Poll::Ready(t) = this.future2.poll(cx) { return Poll::Ready(t); } } else { if let Poll::Ready(t) = this.future2.poll(cx) { return Poll::Ready(t); } if let Poll::Ready(t) = this.future1.poll(cx) { return Poll::Ready(t); } } Poll::Pending } } #[cfg(feature = "std")] pin_project! { /// Future for the [`FutureExt::catch_unwind()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct CatchUnwind { #[pin] inner: F, } } #[cfg(feature = "std")] impl Future for CatchUnwind { type Output = Result>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.project(); catch_unwind(AssertUnwindSafe(|| this.inner.poll(cx)))?.map(Ok) } } /// Type alias for `Pin + Send + 'static>>`. /// /// # Examples /// /// ``` /// use futures_lite::future::{self, FutureExt}; /// /// // These two lines are equivalent: /// let f1: future::Boxed = async { 1 + 2 }.boxed(); /// let f2: future::Boxed = Box::pin(async { 1 + 2 }); /// ``` #[cfg(feature = "alloc")] pub type Boxed = Pin + Send + 'static>>; /// Type alias for `Pin + 'static>>`. /// /// # Examples /// /// ``` /// use futures_lite::future::{self, FutureExt}; /// /// // These two lines are equivalent: /// let f1: future::BoxedLocal = async { 1 + 2 }.boxed_local(); /// let f2: future::BoxedLocal = Box::pin(async { 1 + 2 }); /// ``` #[cfg(feature = "alloc")] pub type BoxedLocal = Pin + 'static>>; /// Extension trait for [`Future`]. pub trait FutureExt: Future { /// A convenience for calling [`Future::poll()`] on `!`[`Unpin`] types. fn poll(&mut self, cx: &mut Context<'_>) -> Poll where Self: Unpin, { Future::poll(Pin::new(self), cx) } /// Returns the result of `self` or `other` future, preferring `self` if both are ready. /// /// If you need to treat the two futures fairly without a preference for either, use the /// [`race()`] function or the [`FutureExt::race()`] method. /// /// # Examples /// /// ``` /// use futures_lite::future::{pending, ready, FutureExt}; /// /// # spin_on::spin_on(async { /// assert_eq!(ready(1).or(pending()).await, 1); /// assert_eq!(pending().or(ready(2)).await, 2); /// /// // The first future wins. /// assert_eq!(ready(1).or(ready(2)).await, 1); /// # }) /// ``` fn or(self, other: F) -> Or where Self: Sized, F: Future, { Or { future1: self, future2: other, } } /// Returns the result of `self` or `other` future, with no preference if both are ready. /// /// Each time [`Race`] is polled, the two inner futures are polled in random order. Therefore, /// no future takes precedence over the other if both can complete at the same time. /// /// If you have preference for one of the futures, use the [`or()`] function or the /// [`FutureExt::or()`] method. /// /// # Examples /// /// ``` /// use futures_lite::future::{pending, ready, FutureExt}; /// /// # spin_on::spin_on(async { /// assert_eq!(ready(1).race(pending()).await, 1); /// assert_eq!(pending().race(ready(2)).await, 2); /// /// // One of the two futures is randomly chosen as the winner. /// let res = ready(1).race(ready(2)).await; /// # }) /// ``` #[cfg(feature = "std")] fn race(self, other: F) -> Race where Self: Sized, F: Future, { Race { future1: self, future2: other, } } /// Catches panics while polling the future. /// /// # Examples /// /// ``` /// use futures_lite::future::FutureExt; /// /// # spin_on::spin_on(async { /// let fut1 = async {}.catch_unwind(); /// let fut2 = async { panic!() }.catch_unwind(); /// /// assert!(fut1.await.is_ok()); /// assert!(fut2.await.is_err()); /// # }) /// ``` #[cfg(feature = "std")] fn catch_unwind(self) -> CatchUnwind where Self: Sized + UnwindSafe, { CatchUnwind { inner: self } } /// Boxes the future and changes its type to `dyn Future + Send + 'a`. /// /// # Examples /// /// ``` /// use futures_lite::future::{self, FutureExt}; /// /// # spin_on::spin_on(async { /// let a = future::ready('a'); /// let b = future::pending(); /// /// // Futures of different types can be stored in /// // the same collection when they are boxed: /// let futures = vec![a.boxed(), b.boxed()]; /// # }) /// ``` #[cfg(feature = "alloc")] fn boxed<'a>(self) -> Pin + Send + 'a>> where Self: Sized + Send + 'a, { Box::pin(self) } /// Boxes the future and changes its type to `dyn Future + 'a`. /// /// # Examples /// /// ``` /// use futures_lite::future::{self, FutureExt}; /// /// # spin_on::spin_on(async { /// let a = future::ready('a'); /// let b = future::pending(); /// /// // Futures of different types can be stored in /// // the same collection when they are boxed: /// let futures = vec![a.boxed_local(), b.boxed_local()]; /// # }) /// ``` #[cfg(feature = "alloc")] fn boxed_local<'a>(self) -> Pin + 'a>> where Self: Sized + 'a, { Box::pin(self) } } impl FutureExt for F {} futures-lite-1.12.0/src/io.rs000064400000000000000000002411160000000000000140630ustar 00000000000000//! Tools and combinators for I/O. //! //! # Examples //! //! ``` //! use futures_lite::io::{self, AsyncReadExt}; //! //! # spin_on::spin_on(async { //! let input: &[u8] = b"hello"; //! let mut reader = io::BufReader::new(input); //! //! let mut contents = String::new(); //! reader.read_to_string(&mut contents).await?; //! # std::io::Result::Ok(()) }); //! ``` #[doc(no_inline)] pub use std::io::{Error, ErrorKind, Result, SeekFrom}; #[doc(no_inline)] pub use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite}; use std::cmp; use std::fmt; use std::future::Future; use std::io::{IoSlice, IoSliceMut}; use std::mem; use std::pin::Pin; use std::sync::{Arc, Mutex}; use std::task::{Context, Poll}; use futures_core::stream::Stream; use pin_project_lite::pin_project; use crate::future; use crate::ready; const DEFAULT_BUF_SIZE: usize = 8 * 1024; /// Copies the entire contents of a reader into a writer. /// /// This function will read data from `reader` and write it into `writer` in a streaming fashion /// until `reader` returns EOF. /// /// On success, returns the total number of bytes copied. /// /// # Examples /// /// ``` /// use futures_lite::io::{self, BufReader, BufWriter}; /// /// # spin_on::spin_on(async { /// let input: &[u8] = b"hello"; /// let reader = BufReader::new(input); /// /// let mut output = Vec::new(); /// let writer = BufWriter::new(&mut output); /// /// io::copy(reader, writer).await?; /// # std::io::Result::Ok(()) }); /// ``` pub async fn copy(reader: R, writer: W) -> Result where R: AsyncRead + Unpin, W: AsyncWrite + Unpin, { pin_project! { struct CopyFuture { #[pin] reader: R, #[pin] writer: W, amt: u64, } } impl Future for CopyFuture where R: AsyncBufRead, W: AsyncWrite + Unpin, { type Output = 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!(this.writer.as_mut().poll_flush(cx))?; return Poll::Ready(Ok(*this.amt)); } let i = ready!(this.writer.as_mut().poll_write(cx, buffer))?; if i == 0 { return Poll::Ready(Err(ErrorKind::WriteZero.into())); } *this.amt += i as u64; this.reader.as_mut().consume(i); } } } let future = CopyFuture { reader: BufReader::new(reader), writer, amt: 0, }; future.await } /// Asserts that a type implementing [`std::io`] traits can be used as an async type. /// /// The underlying I/O handle should never block nor return the [`ErrorKind::WouldBlock`] error. /// This is usually the case for in-memory buffered I/O. /// /// # Examples /// /// ``` /// use futures_lite::io::{AssertAsync, AsyncReadExt}; /// /// let reader: &[u8] = b"hello"; /// /// # spin_on::spin_on(async { /// let mut async_reader = AssertAsync::new(reader); /// let mut contents = String::new(); /// /// // This line works in async manner - note that there is await: /// async_reader.read_to_string(&mut contents).await?; /// # std::io::Result::Ok(()) }); /// ``` #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct AssertAsync(T); impl Unpin for AssertAsync {} impl AssertAsync { /// Wraps an I/O handle implementing [`std::io`] traits. /// /// # Examples /// /// ``` /// use futures_lite::io::AssertAsync; /// /// let reader: &[u8] = b"hello"; /// /// let async_reader = AssertAsync::new(reader); /// ``` pub fn new(io: T) -> Self { AssertAsync(io) } /// Gets a reference to the inner I/O handle. /// /// # Examples /// /// ``` /// use futures_lite::io::AssertAsync; /// /// let reader: &[u8] = b"hello"; /// /// let async_reader = AssertAsync::new(reader); /// let r = async_reader.get_ref(); /// ``` pub fn get_ref(&self) -> &T { &self.0 } /// Gets a mutable reference to the inner I/O handle. /// /// # Examples /// /// ``` /// use futures_lite::io::AssertAsync; /// /// let reader: &[u8] = b"hello"; /// /// let mut async_reader = AssertAsync::new(reader); /// let r = async_reader.get_mut(); /// ``` pub fn get_mut(&mut self) -> &mut T { &mut self.0 } /// Extracts the inner I/O handle. /// /// # Examples /// /// ``` /// use futures_lite::io::AssertAsync; /// /// let reader: &[u8] = b"hello"; /// /// let async_reader = AssertAsync::new(reader); /// let inner = async_reader.into_inner(); /// ``` pub fn into_inner(self) -> T { self.0 } } impl AsyncRead for AssertAsync { fn poll_read( mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &mut [u8], ) -> Poll> { loop { match self.0.read(buf) { Err(err) if err.kind() == ErrorKind::Interrupted => {} res => return Poll::Ready(res), } } } fn poll_read_vectored( mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>], ) -> Poll> { loop { match self.0.read_vectored(bufs) { Err(err) if err.kind() == ErrorKind::Interrupted => {} res => return Poll::Ready(res), } } } } impl AsyncWrite for AssertAsync { fn poll_write( mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &[u8], ) -> Poll> { loop { match self.0.write(buf) { Err(err) if err.kind() == ErrorKind::Interrupted => {} res => return Poll::Ready(res), } } } fn poll_write_vectored( mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll> { loop { match self.0.write_vectored(bufs) { Err(err) if err.kind() == ErrorKind::Interrupted => {} res => return Poll::Ready(res), } } } fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { loop { match self.0.flush() { Err(err) if err.kind() == ErrorKind::Interrupted => {} res => return Poll::Ready(res), } } } fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.poll_flush(cx) } } impl AsyncSeek for AssertAsync { fn poll_seek( mut self: Pin<&mut Self>, _: &mut Context<'_>, pos: SeekFrom, ) -> Poll> { loop { match self.0.seek(pos) { Err(err) if err.kind() == ErrorKind::Interrupted => {} res => return Poll::Ready(res), } } } } /// Blocks on all async I/O operations and implements [`std::io`] traits. /// /// Sometimes async I/O needs to be used in a blocking manner. If calling [`future::block_on()`] /// manually all the time becomes too tedious, use this type for more convenient blocking on async /// I/O operations. /// /// This type implements traits [`Read`][`std::io::Read`], [`Write`][`std::io::Write`], or /// [`Seek`][`std::io::Seek`] if the inner type implements [`AsyncRead`], [`AsyncWrite`], or /// [`AsyncSeek`], respectively. /// /// If writing data through the [`Write`][`std::io::Write`] trait, make sure to flush before /// dropping the [`BlockOn`] handle or some buffered data might get lost. /// /// # Examples /// /// ``` /// use futures_lite::io::BlockOn; /// use futures_lite::pin; /// use std::io::Read; /// /// let reader: &[u8] = b"hello"; /// pin!(reader); /// /// let mut blocking_reader = BlockOn::new(reader); /// let mut contents = String::new(); /// /// // This line blocks - note that there is no await: /// blocking_reader.read_to_string(&mut contents)?; /// # std::io::Result::Ok(()) /// ``` #[derive(Debug)] pub struct BlockOn(T); impl BlockOn { /// Wraps an async I/O handle into a blocking interface. /// /// # Examples /// /// ``` /// use futures_lite::io::BlockOn; /// use futures_lite::pin; /// /// let reader: &[u8] = b"hello"; /// pin!(reader); /// /// let blocking_reader = BlockOn::new(reader); /// ``` pub fn new(io: T) -> BlockOn { BlockOn(io) } /// Gets a reference to the async I/O handle. /// /// # Examples /// /// ``` /// use futures_lite::io::BlockOn; /// use futures_lite::pin; /// /// let reader: &[u8] = b"hello"; /// pin!(reader); /// /// let blocking_reader = BlockOn::new(reader); /// let r = blocking_reader.get_ref(); /// ``` pub fn get_ref(&self) -> &T { &self.0 } /// Gets a mutable reference to the async I/O handle. /// /// # Examples /// /// ``` /// use futures_lite::io::BlockOn; /// use futures_lite::pin; /// /// let reader: &[u8] = b"hello"; /// pin!(reader); /// /// let mut blocking_reader = BlockOn::new(reader); /// let r = blocking_reader.get_mut(); /// ``` pub fn get_mut(&mut self) -> &mut T { &mut self.0 } /// Extracts the inner async I/O handle. /// /// # Examples /// /// ``` /// use futures_lite::io::BlockOn; /// use futures_lite::pin; /// /// let reader: &[u8] = b"hello"; /// pin!(reader); /// /// let blocking_reader = BlockOn::new(reader); /// let inner = blocking_reader.into_inner(); /// ``` pub fn into_inner(self) -> T { self.0 } } impl std::io::Read for BlockOn { fn read(&mut self, buf: &mut [u8]) -> Result { future::block_on(self.0.read(buf)) } } impl std::io::BufRead for BlockOn { fn fill_buf(&mut self) -> Result<&[u8]> { future::block_on(self.0.fill_buf()) } fn consume(&mut self, amt: usize) { Pin::new(&mut self.0).consume(amt) } } impl std::io::Write for BlockOn { fn write(&mut self, buf: &[u8]) -> Result { future::block_on(self.0.write(buf)) } fn flush(&mut self) -> Result<()> { future::block_on(self.0.flush()) } } impl std::io::Seek for BlockOn { fn seek(&mut self, pos: SeekFrom) -> Result { future::block_on(self.0.seek(pos)) } } pin_project! { /// Adds buffering to a reader. /// /// It can be excessively inefficient to work directly with an [`AsyncRead`] instance. A /// [`BufReader`] performs large, infrequent reads on the underlying [`AsyncRead`] and /// maintains an in-memory buffer of the incoming byte stream. /// /// [`BufReader`] can improve the speed of programs that make *small* and *repeated* reads to /// the same file or networking socket. It does not help when reading very large amounts at /// once, or reading just once or a few times. It also provides no advantage when reading from /// a source that is already in memory, like a `Vec`. /// /// When a [`BufReader`] is dropped, the contents of its buffer are discarded. Creating /// multiple instances of [`BufReader`] on the same reader can cause data loss. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncBufReadExt, BufReader}; /// /// # spin_on::spin_on(async { /// let input: &[u8] = b"hello"; /// let mut reader = BufReader::new(input); /// /// let mut line = String::new(); /// reader.read_line(&mut line).await?; /// # std::io::Result::Ok(()) }); /// ``` pub struct BufReader { #[pin] inner: R, buf: Box<[u8]>, pos: usize, cap: usize, } } impl BufReader { /// Creates a buffered reader with the default buffer capacity. /// /// The default capacity is currently 8 KB, but that may change in the future. /// /// # Examples /// /// ``` /// use futures_lite::io::BufReader; /// /// let input: &[u8] = b"hello"; /// let reader = BufReader::new(input); /// ``` pub fn new(inner: R) -> BufReader { BufReader::with_capacity(DEFAULT_BUF_SIZE, inner) } /// Creates a buffered reader with the specified capacity. /// /// # Examples /// /// ``` /// use futures_lite::io::BufReader; /// /// let input: &[u8] = b"hello"; /// let reader = BufReader::with_capacity(1024, input); /// ``` pub fn with_capacity(capacity: usize, inner: R) -> BufReader { BufReader { inner, buf: vec![0; capacity].into_boxed_slice(), pos: 0, cap: 0, } } } impl BufReader { /// Gets a reference to the underlying reader. /// /// It is not advisable to directly read from the underlying reader. /// /// # Examples /// /// ``` /// use futures_lite::io::BufReader; /// /// let input: &[u8] = b"hello"; /// let reader = BufReader::new(input); /// /// let r = reader.get_ref(); /// ``` pub fn get_ref(&self) -> &R { &self.inner } /// Gets a mutable reference to the underlying reader. /// /// It is not advisable to directly read from the underlying reader. /// /// # Examples /// /// ``` /// use futures_lite::io::BufReader; /// /// let input: &[u8] = b"hello"; /// let mut reader = BufReader::new(input); /// /// let r = reader.get_mut(); /// ``` pub fn get_mut(&mut self) -> &mut R { &mut self.inner } /// Gets a pinned mutable reference to the underlying reader. /// /// It is not advisable to directly read from the underlying reader. fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut R> { self.project().inner } /// Returns a reference to the internal buffer. /// /// This method will not attempt to fill the buffer if it is empty. /// /// # Examples /// /// ``` /// use futures_lite::io::BufReader; /// /// let input: &[u8] = b"hello"; /// let reader = BufReader::new(input); /// /// // The internal buffer is empty until the first read request. /// assert_eq!(reader.buffer(), &[]); /// ``` pub fn buffer(&self) -> &[u8] { &self.buf[self.pos..self.cap] } /// Unwraps the buffered reader, returning the underlying reader. /// /// Note that any leftover data in the internal buffer will be lost. /// /// # Examples /// /// ``` /// use futures_lite::io::BufReader; /// /// let input: &[u8] = b"hello"; /// let reader = BufReader::new(input); /// /// assert_eq!(reader.into_inner(), input); /// ``` pub fn into_inner(self) -> R { self.inner } /// 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 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.buf.len() { let res = ready!(self.as_mut().get_pin_mut().poll_read(cx, buf)); self.discard_buffer(); return Poll::Ready(res); } let mut rem = ready!(self.as_mut().poll_fill_buf(cx))?; let nread = std::io::Read::read(&mut rem, 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.buf.len() { let res = ready!(self.as_mut().get_pin_mut().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 = std::io::Read::read_vectored(&mut rem, bufs)?; self.consume(nread); Poll::Ready(Ok(nread)) } } impl AsyncBufRead for BufReader { fn poll_fill_buf<'a>(self: Pin<&'a mut Self>, cx: &mut Context<'_>) -> Poll> { let mut 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.as_mut().poll_read(cx, this.buf))?; *this.pos = 0; } Poll::Ready(Ok(&this.buf[*this.pos..*this.cap])) } fn consume(self: Pin<&mut Self>, amt: usize) { let this = self.project(); *this.pos = cmp::min(*this.pos + amt, *this.cap); } } 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.buf.len()), ) .finish() } } impl AsyncSeek for BufReader { /// Seeks 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()`][`BufReader::into_inner()`] /// immediately after a seek yields the underlying reader at the same position. /// /// See [`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()`][`AsyncSeekExt::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() .get_pin_mut() .poll_seek(cx, SeekFrom::Current(offset)))?; } else { // seek backwards by our remainder, and then by the offset ready!(self .as_mut() .get_pin_mut() .poll_seek(cx, SeekFrom::Current(-remainder)))?; self.as_mut().discard_buffer(); result = ready!(self .as_mut() .get_pin_mut() .poll_seek(cx, SeekFrom::Current(n)))?; } } else { // Seeking with Start/End doesn't care about our buffer length. result = ready!(self.as_mut().get_pin_mut().poll_seek(cx, pos))?; } self.discard_buffer(); Poll::Ready(Ok(result)) } } impl AsyncWrite for BufReader { fn poll_write( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll> { self.as_mut().get_pin_mut().poll_write(cx, buf) } fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.as_mut().get_pin_mut().poll_flush(cx) } fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.as_mut().get_pin_mut().poll_close(cx) } } pin_project! { /// Adds buffering to a writer. /// /// It can be excessively inefficient to work directly with something that implements /// [`AsyncWrite`]. For example, every call to [`write()`][`AsyncWriteExt::write()`] on a TCP /// stream results in a system call. A [`BufWriter`] keeps an in-memory buffer of data and /// writes it to the underlying writer in large, infrequent batches. /// /// [`BufWriter`] can improve the speed of programs that make *small* and *repeated* writes to /// the same file or networking socket. It does not help when writing very large amounts at /// once, or writing just once or a few times. It also provides no advantage when writing to a /// destination that is in memory, like a `Vec`. /// /// Unlike [`std::io::BufWriter`], this type does not write out the contents of its buffer when /// it is dropped. Therefore, it is important that users explicitly flush the buffer before /// dropping the [`BufWriter`]. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncWriteExt, BufWriter}; /// /// # spin_on::spin_on(async { /// let mut output = Vec::new(); /// let mut writer = BufWriter::new(&mut output); /// /// writer.write_all(b"hello").await?; /// writer.flush().await?; /// # std::io::Result::Ok(()) }); /// ``` pub struct BufWriter { #[pin] inner: W, buf: Vec, written: usize, } } impl BufWriter { /// Creates a buffered writer with the default buffer capacity. /// /// The default capacity is currently 8 KB, but that may change in the future. /// /// # Examples /// /// ``` /// use futures_lite::io::BufWriter; /// /// let mut output = Vec::new(); /// let writer = BufWriter::new(&mut output); /// ``` pub fn new(inner: W) -> BufWriter { BufWriter::with_capacity(DEFAULT_BUF_SIZE, inner) } /// Creates a buffered writer with the specified buffer capacity. /// /// # Examples /// /// ``` /// use futures_lite::io::BufWriter; /// /// let mut output = Vec::new(); /// let writer = BufWriter::with_capacity(100, &mut output); /// ``` pub fn with_capacity(capacity: usize, inner: W) -> BufWriter { BufWriter { inner, buf: Vec::with_capacity(capacity), written: 0, } } /// Gets a reference to the underlying writer. /// /// # Examples /// /// ``` /// use futures_lite::io::BufWriter; /// /// let mut output = Vec::new(); /// let writer = BufWriter::new(&mut output); /// /// let r = writer.get_ref(); /// ``` pub fn get_ref(&self) -> &W { &self.inner } /// Gets a mutable reference to the underlying writer. /// /// It is not advisable to directly write to the underlying writer. /// /// # Examples /// /// ``` /// use futures_lite::io::BufWriter; /// /// let mut output = Vec::new(); /// let mut writer = BufWriter::new(&mut output); /// /// let r = writer.get_mut(); /// ``` pub fn get_mut(&mut self) -> &mut W { &mut self.inner } /// Gets a pinned mutable reference to the underlying writer. /// /// It is not not advisable to directly write to the underlying writer. fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut W> { self.project().inner } /// Unwraps the buffered writer, returning the underlying writer. /// /// Note that any leftover data in the internal buffer will be lost. If you don't want to lose /// that data, flush the buffered writer before unwrapping it. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncWriteExt, BufWriter}; /// /// # spin_on::spin_on(async { /// let mut output = vec![1, 2, 3]; /// let mut writer = BufWriter::new(&mut output); /// /// writer.write_all(&[4]).await?; /// writer.flush().await?; /// assert_eq!(writer.into_inner(), &[1, 2, 3, 4]); /// # std::io::Result::Ok(()) }); /// ``` pub fn into_inner(self) -> W { self.inner } /// Returns a reference to the internal buffer. /// /// # Examples /// /// ``` /// use futures_lite::io::BufWriter; /// /// let mut output = Vec::new(); /// let writer = BufWriter::new(&mut output); /// /// // The internal buffer is empty until the first write request. /// assert_eq!(writer.buffer(), &[]); /// ``` pub fn buffer(&self) -> &[u8] { &self.buf } /// Flush the buffer. fn poll_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 this .inner .as_mut() .poll_write(cx, &this.buf[*this.written..]) { Poll::Ready(Ok(0)) => { ret = Err(Error::new( ErrorKind::WriteZero, "Failed to write buffered data", )); break; } Poll::Ready(Ok(n)) => *this.written += n, Poll::Ready(Err(ref e)) if e.kind() == ErrorKind::Interrupted => {} Poll::Ready(Err(e)) => { ret = Err(e); break; } Poll::Pending => return Poll::Pending, } } if *this.written > 0 { this.buf.drain(..*this.written); } *this.written = 0; Poll::Ready(ret) } } impl fmt::Debug for BufWriter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("BufWriter") .field("writer", &self.inner) .field("buf", &self.buf) .finish() } } 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().poll_flush_buf(cx))?; } if buf.len() >= self.buf.capacity() { self.get_pin_mut().poll_write(cx, buf) } else { Pin::new(&mut *self.project().buf).poll_write(cx, buf) } } fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { ready!(self.as_mut().poll_flush_buf(cx))?; self.get_pin_mut().poll_flush(cx) } fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { ready!(self.as_mut().poll_flush_buf(cx))?; self.get_pin_mut().poll_close(cx) } } 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().poll_flush_buf(cx))?; self.get_pin_mut().poll_seek(cx, pos) } } /// Gives an in-memory buffer a cursor for reading and writing. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt, Cursor, SeekFrom}; /// /// # spin_on::spin_on(async { /// let mut bytes = b"hello".to_vec(); /// let mut cursor = Cursor::new(&mut bytes); /// /// // Overwrite 'h' with 'H'. /// cursor.write_all(b"H").await?; /// /// // Move the cursor one byte forward. /// cursor.seek(SeekFrom::Current(1)).await?; /// /// // Read a byte. /// let mut byte = [0]; /// cursor.read_exact(&mut byte).await?; /// assert_eq!(&byte, b"l"); /// /// // Check the final buffer. /// assert_eq!(bytes, b"Hello"); /// # std::io::Result::Ok(()) }); /// ``` #[derive(Clone, Debug, Default)] pub struct Cursor { inner: std::io::Cursor, } impl Cursor { /// Creates a cursor for an in-memory buffer. /// /// Cursor's initial position is 0 even if the underlying buffer is not empty. Writing using /// [`Cursor`] will overwrite the existing contents unless the cursor is moved to the end of /// the buffer using [`set_position()`][Cursor::set_position()`] or /// [`seek()`][`AsyncSeekExt::seek()`]. /// /// # Examples /// /// ``` /// use futures_lite::io::Cursor; /// /// let cursor = Cursor::new(Vec::::new()); /// ``` pub fn new(inner: T) -> Cursor { Cursor { inner: std::io::Cursor::new(inner), } } /// Gets a reference to the underlying buffer. /// /// # Examples /// /// ``` /// use futures_lite::io::Cursor; /// /// let cursor = Cursor::new(Vec::::new()); /// let r = cursor.get_ref(); /// ``` pub fn get_ref(&self) -> &T { self.inner.get_ref() } /// Gets a mutable reference to the underlying buffer. /// /// # Examples /// /// ``` /// use futures_lite::io::Cursor; /// /// let mut cursor = Cursor::new(Vec::::new()); /// let r = cursor.get_mut(); /// ``` pub fn get_mut(&mut self) -> &mut T { self.inner.get_mut() } /// Unwraps the cursor, returning the underlying buffer. /// /// # Examples /// /// ``` /// use futures_lite::io::Cursor; /// /// let cursor = Cursor::new(vec![1, 2, 3]); /// assert_eq!(cursor.into_inner(), [1, 2, 3]); /// ``` pub fn into_inner(self) -> T { self.inner.into_inner() } /// Returns the current position of this cursor. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncSeekExt, Cursor, SeekFrom}; /// /// # spin_on::spin_on(async { /// let mut cursor = Cursor::new(b"hello"); /// assert_eq!(cursor.position(), 0); /// /// cursor.seek(SeekFrom::Start(2)).await?; /// assert_eq!(cursor.position(), 2); /// # std::io::Result::Ok(()) }); /// ``` pub fn position(&self) -> u64 { self.inner.position() } /// Sets the position of this cursor. /// /// # Examples /// /// ``` /// use futures_lite::io::Cursor; /// /// let mut cursor = Cursor::new(b"hello"); /// assert_eq!(cursor.position(), 0); /// /// cursor.set_position(2); /// assert_eq!(cursor.position(), 2); /// ``` 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(std::io::Seek::seek(&mut self.inner, pos)) } } impl AsyncRead for Cursor where T: AsRef<[u8]> + Unpin, { fn poll_read( mut self: Pin<&mut Self>, _cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll> { Poll::Ready(std::io::Read::read(&mut self.inner, buf)) } fn poll_read_vectored( mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>], ) -> Poll> { Poll::Ready(std::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(std::io::BufRead::fill_buf(&mut self.get_mut().inner)) } fn consume(mut self: Pin<&mut Self>, amt: usize) { std::io::BufRead::consume(&mut self.inner, amt) } } impl AsyncWrite for Cursor<&mut [u8]> { fn poll_write( mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &[u8], ) -> Poll> { Poll::Ready(std::io::Write::write(&mut self.inner, buf)) } fn poll_write_vectored( mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll> { Poll::Ready(std::io::Write::write_vectored(&mut self.inner, bufs)) } fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { Poll::Ready(std::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 Vec> { fn poll_write( mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &[u8], ) -> Poll> { Poll::Ready(std::io::Write::write(&mut self.inner, buf)) } fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.poll_flush(cx) } fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { Poll::Ready(std::io::Write::flush(&mut self.inner)) } } impl AsyncWrite for Cursor> { fn poll_write( mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &[u8], ) -> Poll> { Poll::Ready(std::io::Write::write(&mut self.inner, buf)) } fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.poll_flush(cx) } fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { Poll::Ready(std::io::Write::flush(&mut self.inner)) } } /// Creates an empty reader. /// /// # Examples /// /// ``` /// use futures_lite::io::{self, AsyncReadExt}; /// /// # spin_on::spin_on(async { /// let mut reader = io::empty(); /// /// let mut contents = Vec::new(); /// reader.read_to_end(&mut contents).await?; /// assert!(contents.is_empty()); /// # std::io::Result::Ok(()) }); /// ``` pub fn empty() -> Empty { Empty { _private: () } } /// Reader for the [`empty()`] function. pub struct Empty { _private: (), } impl fmt::Debug for Empty { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.pad("Empty { .. }") } } 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<'a>(self: Pin<&'a mut Self>, _: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(&[])) } #[inline] fn consume(self: Pin<&mut Self>, _: usize) {} } /// Creates an infinite reader that reads the same byte repeatedly. /// /// # Examples /// /// ``` /// use futures_lite::io::{self, AsyncReadExt}; /// /// # spin_on::spin_on(async { /// let mut reader = io::repeat(b'a'); /// /// let mut contents = vec![0; 5]; /// reader.read_exact(&mut contents).await?; /// assert_eq!(contents, b"aaaaa"); /// # std::io::Result::Ok(()) }); /// ``` pub fn repeat(byte: u8) -> Repeat { Repeat { byte } } /// Reader for the [`repeat()`] function. #[derive(Debug)] pub struct Repeat { byte: u8, } impl AsyncRead for Repeat { #[inline] fn poll_read(self: Pin<&mut Self>, _: &mut Context<'_>, buf: &mut [u8]) -> Poll> { for b in &mut *buf { *b = self.byte; } Poll::Ready(Ok(buf.len())) } } /// Creates a writer that consumes and drops all data. /// /// # Examples /// /// ``` /// use futures_lite::io::{self, AsyncWriteExt}; /// /// # spin_on::spin_on(async { /// let mut writer = io::sink(); /// writer.write_all(b"hello").await?; /// # std::io::Result::Ok(()) }); /// ``` pub fn sink() -> Sink { Sink { _private: () } } /// Writer for the [`sink()`] function. #[derive(Debug)] pub struct Sink { _private: (), } 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_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(())) } } /// Extension trait for [`AsyncBufRead`]. pub trait AsyncBufReadExt: AsyncBufRead { /// Returns the contents of the internal buffer, filling it with more data if empty. /// /// If the stream has reached EOF, an empty buffer will be returned. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncBufReadExt, BufReader}; /// use std::pin::Pin; /// /// # spin_on::spin_on(async { /// let input: &[u8] = b"hello world"; /// let mut reader = BufReader::with_capacity(5, input); /// /// assert_eq!(reader.fill_buf().await?, b"hello"); /// reader.consume(2); /// assert_eq!(reader.fill_buf().await?, b"llo"); /// reader.consume(3); /// assert_eq!(reader.fill_buf().await?, b" worl"); /// # std::io::Result::Ok(()) }); /// ``` fn fill_buf(&mut self) -> FillBuf<'_, Self> where Self: Unpin, { FillBuf { reader: Some(self) } } /// Consumes `amt` buffered bytes. /// /// This method does not perform any I/O, it simply consumes some amount of bytes from the /// internal buffer. /// /// The `amt` must be <= the number of bytes in the buffer returned by /// [`fill_buf()`][`AsyncBufReadExt::fill_buf()`]. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncBufReadExt, BufReader}; /// use std::pin::Pin; /// /// # spin_on::spin_on(async { /// let input: &[u8] = b"hello"; /// let mut reader = BufReader::with_capacity(4, input); /// /// assert_eq!(reader.fill_buf().await?, b"hell"); /// reader.consume(2); /// assert_eq!(reader.fill_buf().await?, b"ll"); /// # std::io::Result::Ok(()) }); /// ``` fn consume(&mut self, amt: usize) where Self: Unpin, { AsyncBufRead::consume(Pin::new(self), amt); } /// Reads all bytes and appends them into `buf` until the delimiter `byte` or EOF is found. /// /// This method will read bytes from the underlying stream until the delimiter or EOF is /// found. All bytes up to and including the delimiter (if found) will be appended to `buf`. /// /// If successful, returns the total number of bytes read. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncBufReadExt, BufReader}; /// /// # spin_on::spin_on(async { /// let input: &[u8] = b"hello"; /// let mut reader = BufReader::new(input); /// /// let mut buf = Vec::new(); /// let n = reader.read_until(b'\n', &mut buf).await?; /// # std::io::Result::Ok(()) }); /// ``` fn read_until<'a>(&'a mut self, byte: u8, buf: &'a mut Vec) -> ReadUntilFuture<'_, Self> where Self: Unpin, { ReadUntilFuture { reader: self, byte, buf, read: 0, } } /// Reads all bytes and appends them into `buf` until a newline (the 0xA byte) or EOF is found. /// /// This method will read bytes from the underlying stream until the newline delimiter (the /// 0xA byte) or EOF is found. All bytes up to, and including, the newline delimiter (if found) /// will be appended to `buf`. /// /// If successful, returns the total number of bytes read. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncBufReadExt, BufReader}; /// /// # spin_on::spin_on(async { /// let input: &[u8] = b"hello"; /// let mut reader = BufReader::new(input); /// /// let mut line = String::new(); /// let n = reader.read_line(&mut line).await?; /// # std::io::Result::Ok(()) }); /// ``` fn read_line<'a>(&'a mut self, buf: &'a mut String) -> ReadLineFuture<'_, Self> where Self: Unpin, { ReadLineFuture { reader: self, buf, bytes: Vec::new(), read: 0, } } /// Returns a stream over the lines of this byte stream. /// /// The stream returned from this method yields items of type /// [`io::Result`][`super::io::Result`]`<`[`String`]`>`. /// Each string returned will *not* have a newline byte (the 0xA byte) or CRLF (0xD, 0xA bytes) /// at the end. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncBufReadExt, BufReader}; /// use futures_lite::stream::StreamExt; /// /// # spin_on::spin_on(async { /// let input: &[u8] = b"hello\nworld\n"; /// let mut reader = BufReader::new(input); /// let mut lines = reader.lines(); /// /// while let Some(line) = lines.next().await { /// println!("{}", line?); /// } /// # std::io::Result::Ok(()) }); /// ``` fn lines(self) -> Lines where Self: Unpin + Sized, { Lines { reader: self, buf: String::new(), bytes: Vec::new(), read: 0, } } /// Returns a stream over the contents of this reader split on the specified `byte`. /// /// The stream returned from this method yields items of type /// [`io::Result`][`super::io::Result`]`<`[`Vec`][`Vec`]`>`. /// Each vector returned will *not* have the delimiter byte at the end. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncBufReadExt, Cursor}; /// use futures_lite::stream::StreamExt; /// /// # spin_on::spin_on(async { /// let cursor = Cursor::new(b"lorem-ipsum-dolor"); /// let items: Vec> = cursor.split(b'-').try_collect().await?; /// /// assert_eq!(items[0], b"lorem"); /// assert_eq!(items[1], b"ipsum"); /// assert_eq!(items[2], b"dolor"); /// # std::io::Result::Ok(()) }); /// ``` fn split(self, byte: u8) -> Split where Self: Sized, { Split { reader: self, buf: Vec::new(), delim: byte, read: 0, } } } impl AsyncBufReadExt for R {} /// Future for the [`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> Future for FillBuf<'a, R> where R: AsyncBufRead + Unpin + ?Sized, { type Output = 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(_)) => match Pin::new(reader).poll_fill_buf(cx) { Poll::Ready(Ok(slice)) => Poll::Ready(Ok(slice)), poll => panic!("`poll_fill_buf()` was ready but now it isn't: {:?}", poll), }, Poll::Ready(Err(err)) => Poll::Ready(Err(err)), Poll::Pending => { this.reader = Some(reader); Poll::Pending } } } } /// Future for the [`AsyncBufReadExt::read_until()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct ReadUntilFuture<'a, R: Unpin + ?Sized> { reader: &'a mut R, byte: u8, buf: &'a mut Vec, read: usize, } impl Unpin for ReadUntilFuture<'_, R> {} impl Future for ReadUntilFuture<'_, R> { type Output = 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) } } 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))); } } } /// Future for the [`AsyncBufReadExt::read_line()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct ReadLineFuture<'a, R: Unpin + ?Sized> { reader: &'a mut R, buf: &'a mut String, bytes: Vec, read: usize, } impl Unpin for ReadLineFuture<'_, R> {} impl Future for ReadLineFuture<'_, R> { type Output = 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) } } pin_project! { /// Stream for the [`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 Stream for Lines { type Item = 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::replace(this.buf, String::new())))) } } 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)); match String::from_utf8(mem::replace(bytes, Vec::new())) { Ok(s) => { debug_assert!(buf.is_empty()); debug_assert_eq!(*read, 0); *buf = s; Poll::Ready(ret) } Err(_) => Poll::Ready(ret.and_then(|_| { Err(Error::new( ErrorKind::InvalidData, "stream did not contain valid UTF-8", )) })), } } pin_project! { /// Stream for the [`AsyncBufReadExt::split()`] method. #[derive(Debug)] #[must_use = "streams do nothing unless polled"] pub struct Split { #[pin] reader: R, buf: Vec, read: usize, delim: u8, } } impl Stream for Split { type Item = Result>; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); let n = ready!(read_until_internal( this.reader, cx, *this.delim, this.buf, this.read ))?; if n == 0 && this.buf.is_empty() { return Poll::Ready(None); } if this.buf[this.buf.len() - 1] == *this.delim { this.buf.pop(); } Poll::Ready(Some(Ok(mem::replace(this.buf, vec![])))) } } /// Extension trait for [`AsyncRead`]. pub trait AsyncReadExt: AsyncRead { /// Reads some bytes from the byte stream. /// /// On success, returns the total number of bytes read. /// /// If the return value is `Ok(n)`, then it must be guaranteed that /// `0 <= n <= buf.len()`. A nonzero `n` value indicates that the buffer has been /// filled with `n` bytes of data. If `n` is `0`, then it can indicate one of two /// scenarios: /// /// 1. This reader has reached its "end of file" and will likely no longer be able to /// produce bytes. Note that this does not mean that the reader will always no /// longer be able to produce bytes. /// 2. The buffer specified was 0 bytes in length. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncReadExt, BufReader}; /// /// # spin_on::spin_on(async { /// let input: &[u8] = b"hello"; /// let mut reader = BufReader::new(input); /// /// let mut buf = vec![0; 1024]; /// let n = reader.read(&mut buf).await?; /// # std::io::Result::Ok(()) }); /// ``` fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadFuture<'a, Self> where Self: Unpin, { ReadFuture { reader: self, buf } } /// Like [`read()`][`AsyncReadExt::read()`], except it reads into a slice of buffers. /// /// Data is copied to fill each buffer in order, with the final buffer possibly being /// only partially filled. This method must behave same as a single call to /// [`read()`][`AsyncReadExt::read()`] with the buffers concatenated would. fn read_vectored<'a>( &'a mut self, bufs: &'a mut [IoSliceMut<'a>], ) -> ReadVectoredFuture<'a, Self> where Self: Unpin, { ReadVectoredFuture { reader: self, bufs } } /// Reads the entire contents and appends them to a [`Vec`]. /// /// On success, returns the total number of bytes read. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncReadExt, Cursor}; /// /// # spin_on::spin_on(async { /// let mut reader = Cursor::new(vec![1, 2, 3]); /// let mut contents = Vec::new(); /// /// let n = reader.read_to_end(&mut contents).await?; /// assert_eq!(n, 3); /// assert_eq!(contents, [1, 2, 3]); /// # std::io::Result::Ok(()) }); /// ``` fn read_to_end<'a>(&'a mut self, buf: &'a mut Vec) -> ReadToEndFuture<'a, Self> where Self: Unpin, { let start_len = buf.len(); ReadToEndFuture { reader: self, buf, start_len, } } /// Reads the entire contents and appends them to a [`String`]. /// /// On success, returns the total number of bytes read. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncReadExt, Cursor}; /// /// # spin_on::spin_on(async { /// let mut reader = Cursor::new(&b"hello"); /// let mut contents = String::new(); /// /// let n = reader.read_to_string(&mut contents).await?; /// assert_eq!(n, 5); /// assert_eq!(contents, "hello"); /// # std::io::Result::Ok(()) }); /// ``` fn read_to_string<'a>(&'a mut self, buf: &'a mut String) -> ReadToStringFuture<'a, Self> where Self: Unpin, { ReadToStringFuture { reader: self, buf, bytes: Vec::new(), start_len: 0, } } /// Reads the exact number of bytes required to fill `buf`. /// /// On success, returns the total number of bytes read. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncReadExt, Cursor}; /// /// # spin_on::spin_on(async { /// let mut reader = Cursor::new(&b"hello"); /// let mut contents = vec![0; 3]; /// /// reader.read_exact(&mut contents).await?; /// assert_eq!(contents, b"hel"); /// # std::io::Result::Ok(()) }); /// ``` fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExactFuture<'a, Self> where Self: Unpin, { ReadExactFuture { reader: self, buf } } /// Creates an adapter which will read at most `limit` bytes from it. /// /// This method returns a new instance of [`AsyncRead`] which will read at most /// `limit` bytes, after which it will always return `Ok(0)` indicating EOF. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncReadExt, Cursor}; /// /// # spin_on::spin_on(async { /// let mut reader = Cursor::new(&b"hello"); /// let mut contents = String::new(); /// /// let n = reader.take(3).read_to_string(&mut contents).await?; /// assert_eq!(n, 3); /// assert_eq!(contents, "hel"); /// # std::io::Result::Ok(()) }); /// ``` fn take(self, limit: u64) -> Take where Self: Sized, { Take { inner: self, limit } } /// Converts this [`AsyncRead`] into a [`Stream`] of bytes. /// /// The returned type implements [`Stream`] where `Item` is `io::Result`. /// /// ``` /// use futures_lite::io::{AsyncReadExt, Cursor}; /// use futures_lite::stream::StreamExt; /// /// # spin_on::spin_on(async { /// let reader = Cursor::new(&b"hello"); /// let mut bytes = reader.bytes(); /// /// while let Some(byte) = bytes.next().await { /// println!("byte: {}", byte?); /// } /// # std::io::Result::Ok(()) }); /// ``` fn bytes(self) -> Bytes where Self: Sized, { Bytes { inner: self } } /// Creates an adapter which will chain this stream with another. /// /// The returned [`AsyncRead`] instance will first read all bytes from this reader /// until EOF is found, and then continue with `next`. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncReadExt, Cursor}; /// /// # spin_on::spin_on(async { /// let r1 = Cursor::new(&b"hello"); /// let r2 = Cursor::new(&b"world"); /// let mut reader = r1.chain(r2); /// /// let mut contents = String::new(); /// reader.read_to_string(&mut contents).await?; /// assert_eq!(contents, "helloworld"); /// # std::io::Result::Ok(()) }); /// ``` fn chain(self, next: R) -> Chain where Self: Sized, { Chain { first: self, second: next, done_first: false, } } /// Boxes the reader and changes its type to `dyn AsyncRead + Send + 'a`. /// /// # Examples /// /// ``` /// use futures_lite::io::AsyncReadExt; /// /// let reader = [1, 2, 3].boxed_reader(); /// ``` #[cfg(feature = "alloc")] fn boxed_reader<'a>(self) -> Pin> where Self: Sized + Send + 'a, { Box::pin(self) } } impl AsyncReadExt for R {} /// Future for the [`AsyncReadExt::read()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct ReadFuture<'a, R: Unpin + ?Sized> { reader: &'a mut R, buf: &'a mut [u8], } impl Unpin for ReadFuture<'_, R> {} impl Future for ReadFuture<'_, R> { type Output = Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let Self { reader, buf } = &mut *self; Pin::new(reader).poll_read(cx, buf) } } /// Future for the [`AsyncReadExt::read_vectored()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct ReadVectoredFuture<'a, R: Unpin + ?Sized> { reader: &'a mut R, bufs: &'a mut [IoSliceMut<'a>], } impl Unpin for ReadVectoredFuture<'_, R> {} impl Future for ReadVectoredFuture<'_, R> { type Output = Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let Self { reader, bufs } = &mut *self; Pin::new(reader).poll_read_vectored(cx, bufs) } } /// Future for the [`AsyncReadExt::read_to_end()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct ReadToEndFuture<'a, R: Unpin + ?Sized> { reader: &'a mut R, buf: &'a mut Vec, start_len: usize, } impl Unpin for ReadToEndFuture<'_, R> {} impl Future for ReadToEndFuture<'_, R> { type Output = Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let Self { reader, buf, start_len, } = &mut *self; read_to_end_internal(Pin::new(reader), cx, buf, *start_len) } } /// Future for the [`AsyncReadExt::read_to_string()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct ReadToStringFuture<'a, R: Unpin + ?Sized> { reader: &'a mut R, buf: &'a mut String, bytes: Vec, start_len: usize, } impl Unpin for ReadToStringFuture<'_, R> {} impl Future for ReadToStringFuture<'_, R> { type Output = Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let Self { reader, buf, bytes, start_len, } = &mut *self; let reader = Pin::new(reader); let ret = ready!(read_to_end_internal(reader, cx, bytes, *start_len)); match String::from_utf8(mem::replace(bytes, Vec::new())) { Ok(s) => { debug_assert!(buf.is_empty()); **buf = s; Poll::Ready(ret) } Err(_) => Poll::Ready(ret.and_then(|_| { Err(Error::new( ErrorKind::InvalidData, "stream did not contain valid UTF-8", )) })), } } } // 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. fn read_to_end_internal( mut rd: Pin<&mut R>, cx: &mut Context<'_>, buf: &mut Vec, start_len: usize, ) -> Poll> { struct Guard<'a> { buf: &'a mut Vec, len: usize, } impl Drop for Guard<'_> { fn drop(&mut self) { self.buf.resize(self.len, 0); } } let mut g = Guard { len: buf.len(), buf, }; let ret; loop { if g.len == g.buf.len() { g.buf.reserve(32); let capacity = g.buf.capacity(); g.buf.resize(capacity, 0); } match ready!(rd.as_mut().poll_read(cx, &mut g.buf[g.len..])) { Ok(0) => { ret = Poll::Ready(Ok(g.len - start_len)); break; } Ok(n) => g.len += n, Err(e) => { ret = Poll::Ready(Err(e)); break; } } } ret } /// Future for the [`AsyncReadExt::read_exact()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct ReadExactFuture<'a, R: Unpin + ?Sized> { reader: &'a mut R, buf: &'a mut [u8], } impl Unpin for ReadExactFuture<'_, R> {} impl Future for ReadExactFuture<'_, R> { type Output = Result<()>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let Self { reader, buf } = &mut *self; while !buf.is_empty() { let n = ready!(Pin::new(&mut *reader).poll_read(cx, buf))?; let (_, rest) = mem::replace(buf, &mut []).split_at_mut(n); *buf = rest; if n == 0 { return Poll::Ready(Err(ErrorKind::UnexpectedEof.into())); } } Poll::Ready(Ok(())) } } pin_project! { /// Reader for the [`AsyncReadExt::take()`] method. #[derive(Debug)] pub struct Take { #[pin] inner: R, limit: u64, } } impl Take { /// Returns the number of bytes before this adapter will return EOF. /// /// Note that EOF may be reached sooner if the underlying reader is shorter than the limit. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncReadExt, Cursor}; /// /// let reader = Cursor::new("hello"); /// /// let reader = reader.take(3); /// assert_eq!(reader.limit(), 3); /// ``` pub fn limit(&self) -> u64 { self.limit } /// Puts a limit on the number of bytes. /// /// Changing the limit is equivalent to creating a new adapter with [`AsyncReadExt::take()`]. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncReadExt, Cursor}; /// /// let reader = Cursor::new("hello"); /// /// let mut reader = reader.take(10); /// assert_eq!(reader.limit(), 10); /// /// reader.set_limit(3); /// assert_eq!(reader.limit(), 3); /// ``` pub fn set_limit(&mut self, limit: u64) { self.limit = limit; } /// Gets a reference to the underlying reader. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncReadExt, Cursor}; /// /// let reader = Cursor::new("hello"); /// /// let reader = reader.take(3); /// let r = reader.get_ref(); /// ``` pub fn get_ref(&self) -> &R { &self.inner } /// Gets a mutable reference to the underlying reader. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncReadExt, Cursor}; /// /// let reader = Cursor::new("hello"); /// /// let mut reader = reader.take(3); /// let r = reader.get_mut(); /// ``` pub fn get_mut(&mut self) -> &mut R { &mut self.inner } /// Unwraps the adapter, returning the underlying reader. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncReadExt, Cursor}; /// /// let reader = Cursor::new("hello"); /// /// let reader = reader.take(3); /// let reader = reader.into_inner(); /// ``` pub fn into_inner(self) -> R { self.inner } } impl AsyncRead for Take { fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll> { let this = self.project(); take_read_internal(this.inner, cx, buf, this.limit) } } fn take_read_internal( mut rd: Pin<&mut R>, cx: &mut Context<'_>, buf: &mut [u8], limit: &mut u64, ) -> Poll> { // Don't call into inner reader at all at EOF because it may still block if *limit == 0 { return Poll::Ready(Ok(0)); } let max = cmp::min(buf.len() as u64, *limit) as usize; match ready!(rd.as_mut().poll_read(cx, &mut buf[..max])) { Ok(n) => { *limit -= n as u64; Poll::Ready(Ok(n)) } Err(e) => Poll::Ready(Err(e)), } } impl AsyncBufRead for Take { fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); if *this.limit == 0 { return Poll::Ready(Ok(&[])); } match ready!(this.inner.poll_fill_buf(cx)) { Ok(buf) => { let cap = cmp::min(buf.len() as u64, *this.limit) as usize; Poll::Ready(Ok(&buf[..cap])) } Err(e) => Poll::Ready(Err(e)), } } 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); } } pin_project! { /// Reader for the [`AsyncReadExt::bytes()`] method. #[derive(Debug)] pub struct Bytes { #[pin] inner: R, } } impl Stream for Bytes { type Item = Result; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut byte = 0; let rd = Pin::new(&mut self.inner); match ready!(rd.poll_read(cx, std::slice::from_mut(&mut byte))) { Ok(0) => Poll::Ready(None), Ok(..) => Poll::Ready(Some(Ok(byte))), Err(ref e) if e.kind() == ErrorKind::Interrupted => Poll::Pending, Err(e) => Poll::Ready(Some(Err(e))), } } } impl AsyncRead for Bytes { fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll> { self.project().inner.poll_read(cx, buf) } fn poll_read_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>], ) -> Poll> { self.project().inner.poll_read_vectored(cx, bufs) } } pin_project! { /// Reader for the [`AsyncReadExt::chain()`] method. pub struct Chain { #[pin] first: R1, #[pin] second: R2, done_first: bool, } } impl Chain { /// Gets references to the underlying readers. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncReadExt, Cursor}; /// /// let r1 = Cursor::new(b"hello"); /// let r2 = Cursor::new(b"world"); /// /// let reader = r1.chain(r2); /// let (r1, r2) = reader.get_ref(); /// ``` pub fn get_ref(&self) -> (&R1, &R2) { (&self.first, &self.second) } /// Gets mutable references to the underlying readers. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncReadExt, Cursor}; /// /// let r1 = Cursor::new(b"hello"); /// let r2 = Cursor::new(b"world"); /// /// let mut reader = r1.chain(r2); /// let (r1, r2) = reader.get_mut(); /// ``` pub fn get_mut(&mut self) -> (&mut R1, &mut R2) { (&mut self.first, &mut self.second) } /// Unwraps the adapter, returning the underlying readers. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncReadExt, Cursor}; /// /// let r1 = Cursor::new(b"hello"); /// let r2 = Cursor::new(b"world"); /// /// let reader = r1.chain(r2); /// let (r1, r2) = reader.into_inner(); /// ``` pub fn into_inner(self) -> (R1, R2) { (self.first, self.second) } } impl fmt::Debug for Chain { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Chain") .field("r1", &self.first) .field("r2", &self.second) .finish() } } impl AsyncRead for Chain { 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)) { Ok(0) if !buf.is_empty() => *this.done_first = true, Ok(n) => return Poll::Ready(Ok(n)), Err(err) => return Poll::Ready(Err(err)), } } 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 { match ready!(this.first.poll_read_vectored(cx, bufs)) { Ok(0) if !bufs.is_empty() => *this.done_first = true, Ok(n) => return Poll::Ready(Ok(n)), Err(err) => return Poll::Ready(Err(err)), } } this.second.poll_read_vectored(cx, bufs) } } impl AsyncBufRead for Chain { 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)) { Ok(buf) if buf.is_empty() => { *this.done_first = true; } Ok(buf) => return Poll::Ready(Ok(buf)), Err(err) => return Poll::Ready(Err(err)), } } 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) } } } /// Extension trait for [`AsyncSeek`]. pub trait AsyncSeekExt: AsyncSeek { /// Seeks to a new position in a byte stream. /// /// Returns the new position in the byte stream. /// /// A seek beyond the end of stream is allowed, but behavior is defined by the implementation. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncSeekExt, Cursor, SeekFrom}; /// /// # spin_on::spin_on(async { /// let mut cursor = Cursor::new("hello"); /// /// // Move the cursor to the end. /// cursor.seek(SeekFrom::End(0)).await?; /// /// // Check the current position. /// assert_eq!(cursor.seek(SeekFrom::Current(0)).await?, 5); /// # std::io::Result::Ok(()) }); /// ``` fn seek(&mut self, pos: SeekFrom) -> SeekFuture<'_, Self> where Self: Unpin, { SeekFuture { seeker: self, pos } } } impl AsyncSeekExt for S {} /// Future for the [`AsyncSeekExt::seek()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct SeekFuture<'a, S: Unpin + ?Sized> { seeker: &'a mut S, pos: SeekFrom, } impl Unpin for SeekFuture<'_, S> {} impl Future for SeekFuture<'_, S> { type Output = Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let pos = self.pos; Pin::new(&mut *self.seeker).poll_seek(cx, pos) } } /// Extension trait for [`AsyncWrite`]. pub trait AsyncWriteExt: AsyncWrite { /// Writes some bytes into the byte stream. /// /// Returns the number of bytes written from the start of the buffer. /// /// If the return value is `Ok(n)` then it must be guaranteed that /// `0 <= n <= buf.len()`. A return value of `0` typically means that the underlying /// object is no longer able to accept bytes and will likely not be able to in the /// future as well, or that the provided buffer is empty. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncWriteExt, BufWriter}; /// /// # spin_on::spin_on(async { /// let mut output = Vec::new(); /// let mut writer = BufWriter::new(&mut output); /// /// let n = writer.write(b"hello").await?; /// # std::io::Result::Ok(()) }); /// ``` fn write<'a>(&'a mut self, buf: &'a [u8]) -> WriteFuture<'a, Self> where Self: Unpin, { WriteFuture { writer: self, buf } } /// Like [`write()`][`AsyncWriteExt::write()`], except that it writes a slice of buffers. /// /// Data is copied from each buffer in order, with the final buffer possibly being only /// partially consumed. This method must behave same as a call to /// [`write()`][`AsyncWriteExt::write()`] with the buffers concatenated would. fn write_vectored<'a>(&'a mut self, bufs: &'a [IoSlice<'a>]) -> WriteVectoredFuture<'a, Self> where Self: Unpin, { WriteVectoredFuture { writer: self, bufs } } /// Writes an entire buffer into the byte stream. /// /// This method will keep calling [`write()`][`AsyncWriteExt::write()`] until there is no more /// data to be written or an error occurs. It will not return before the entire buffer is /// successfully written or an error occurs. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncWriteExt, BufWriter}; /// /// # spin_on::spin_on(async { /// let mut output = Vec::new(); /// let mut writer = BufWriter::new(&mut output); /// /// let n = writer.write_all(b"hello").await?; /// # std::io::Result::Ok(()) }); /// ``` fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> WriteAllFuture<'a, Self> where Self: Unpin, { WriteAllFuture { writer: self, buf } } /// Flushes the stream to ensure that all buffered contents reach their destination. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncWriteExt, BufWriter}; /// /// # spin_on::spin_on(async { /// let mut output = Vec::new(); /// let mut writer = BufWriter::new(&mut output); /// /// writer.write_all(b"hello").await?; /// writer.flush().await?; /// # std::io::Result::Ok(()) }); /// ``` fn flush(&mut self) -> FlushFuture<'_, Self> where Self: Unpin, { FlushFuture { writer: self } } /// Closes the writer. /// /// # Examples /// /// ``` /// use futures_lite::io::{AsyncWriteExt, BufWriter}; /// /// # spin_on::spin_on(async { /// let mut output = Vec::new(); /// let mut writer = BufWriter::new(&mut output); /// /// writer.close().await?; /// # std::io::Result::Ok(()) }); /// ``` fn close(&mut self) -> CloseFuture<'_, Self> where Self: Unpin, { CloseFuture { writer: self } } /// Boxes the writer and changes its type to `dyn AsyncWrite + Send + 'a`. /// /// # Examples /// /// ``` /// use futures_lite::io::AsyncWriteExt; /// /// let writer = Vec::::new().boxed_writer(); /// ``` #[cfg(feature = "alloc")] fn boxed_writer<'a>(self) -> Pin> where Self: Sized + Send + 'a, { Box::pin(self) } } impl AsyncWriteExt for W {} /// Future for the [`AsyncWriteExt::write()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct WriteFuture<'a, W: Unpin + ?Sized> { writer: &'a mut W, buf: &'a [u8], } impl Unpin for WriteFuture<'_, W> {} impl Future for WriteFuture<'_, W> { type Output = Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let buf = self.buf; Pin::new(&mut *self.writer).poll_write(cx, buf) } } /// Future for the [`AsyncWriteExt::write_vectored()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct WriteVectoredFuture<'a, W: Unpin + ?Sized> { writer: &'a mut W, bufs: &'a [IoSlice<'a>], } impl Unpin for WriteVectoredFuture<'_, W> {} impl Future for WriteVectoredFuture<'_, W> { type Output = Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let bufs = self.bufs; Pin::new(&mut *self.writer).poll_write_vectored(cx, bufs) } } /// Future for the [`AsyncWriteExt::write_all()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct WriteAllFuture<'a, W: Unpin + ?Sized> { writer: &'a mut W, buf: &'a [u8], } impl Unpin for WriteAllFuture<'_, W> {} impl Future for WriteAllFuture<'_, W> { type Output = Result<()>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let Self { writer, buf } = &mut *self; while !buf.is_empty() { let n = ready!(Pin::new(&mut **writer).poll_write(cx, buf))?; let (_, rest) = mem::replace(buf, &[]).split_at(n); *buf = rest; if n == 0 { return Poll::Ready(Err(ErrorKind::WriteZero.into())); } } Poll::Ready(Ok(())) } } /// Future for the [`AsyncWriteExt::flush()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct FlushFuture<'a, W: Unpin + ?Sized> { writer: &'a mut W, } impl Unpin for FlushFuture<'_, W> {} impl Future for FlushFuture<'_, W> { type Output = Result<()>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Pin::new(&mut *self.writer).poll_flush(cx) } } /// Future for the [`AsyncWriteExt::close()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct CloseFuture<'a, W: Unpin + ?Sized> { writer: &'a mut W, } impl Unpin for CloseFuture<'_, W> {} impl Future for CloseFuture<'_, W> { type Output = Result<()>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Pin::new(&mut *self.writer).poll_close(cx) } } /// Type alias for `Pin>`. /// /// # Examples /// /// ``` /// use futures_lite::io::AsyncReadExt; /// /// let reader = [1, 2, 3].boxed_reader(); /// ``` #[cfg(feature = "alloc")] pub type BoxedReader = Pin>; /// Type alias for `Pin>`. /// /// # Examples /// /// ``` /// use futures_lite::io::AsyncWriteExt; /// /// let writer = Vec::::new().boxed_writer(); /// ``` #[cfg(feature = "alloc")] pub type BoxedWriter = Pin>; /// Splits a stream into [`AsyncRead`] and [`AsyncWrite`] halves. /// /// # Examples /// /// ``` /// use futures_lite::io::{self, Cursor}; /// /// # spin_on::spin_on(async { /// let stream = Cursor::new(vec![]); /// let (mut reader, mut writer) = io::split(stream); /// # std::io::Result::Ok(()) }); /// ``` pub fn split(stream: T) -> (ReadHalf, WriteHalf) where T: AsyncRead + AsyncWrite + Unpin, { let inner = Arc::new(Mutex::new(stream)); (ReadHalf(inner.clone()), WriteHalf(inner)) } /// The read half returned by [`split()`]. #[derive(Debug)] pub struct ReadHalf(Arc>); /// The write half returned by [`split()`]. #[derive(Debug)] pub struct WriteHalf(Arc>); impl AsyncRead for ReadHalf { fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll> { let mut inner = self.0.lock().unwrap(); Pin::new(&mut *inner).poll_read(cx, buf) } fn poll_read_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>], ) -> Poll> { let mut inner = self.0.lock().unwrap(); Pin::new(&mut *inner).poll_read_vectored(cx, bufs) } } impl AsyncWrite for WriteHalf { fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll> { let mut inner = self.0.lock().unwrap(); Pin::new(&mut *inner).poll_write(cx, buf) } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut inner = self.0.lock().unwrap(); Pin::new(&mut *inner).poll_flush(cx) } fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut inner = self.0.lock().unwrap(); Pin::new(&mut *inner).poll_close(cx) } } futures-lite-1.12.0/src/lib.rs000064400000000000000000000063130000000000000142200ustar 00000000000000//! Futures, streams, and async I/O combinators. //! //! This crate is a subset of [futures] that compiles an order of magnitude faster, fixes minor //! warts in its API, fills in some obvious gaps, and removes almost all unsafe code from it. //! //! In short, this crate aims to be more enjoyable than [futures] but still fully compatible with //! it. //! //! [futures]: https://docs.rs/futures //! //! # Examples //! #![cfg_attr(feature = "std", doc = "```no_run")] #![cfg_attr(not(feature = "std"), doc = "```ignore")] //! use futures_lite::future; //! //! fn main() { //! future::block_on(async { //! println!("Hello world!"); //! }) //! } //! ``` #![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)] #![cfg_attr(not(feature = "std"), no_std)] // TODO: These hidden re-exports are deprecated and should eventually be removed. #[cfg(feature = "std")] #[doc(hidden)] pub use crate::io::{ AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, AsyncWrite, AsyncWriteExt, }; #[doc(hidden)] pub use crate::{ future::{Future, FutureExt}, stream::{Stream, StreamExt}, }; pub mod future; pub mod prelude; pub mod stream; #[cfg(feature = "std")] pub mod io; /// Unwraps `Poll` or returns [`Pending`][`core::task::Poll::Pending`]. /// /// # Examples /// /// ``` /// use futures_lite::{future, prelude::*, ready}; /// use std::pin::Pin; /// use std::task::{Context, Poll}; /// /// fn do_poll(cx: &mut Context<'_>) -> Poll<()> { /// let mut fut = future::ready(42); /// let fut = Pin::new(&mut fut); /// /// let num = ready!(fut.poll(cx)); /// # drop(num); /// // ... use num /// /// Poll::Ready(()) /// } /// ``` /// /// The `ready!` call expands to: /// /// ``` /// # use futures_lite::{future, prelude::*, ready}; /// # use std::pin::Pin; /// # use std::task::{Context, Poll}; /// # /// # fn do_poll(cx: &mut Context<'_>) -> Poll<()> { /// # let mut fut = future::ready(42); /// # let fut = Pin::new(&mut fut); /// # /// let num = match fut.poll(cx) { /// Poll::Ready(t) => t, /// Poll::Pending => return Poll::Pending, /// }; /// # drop(num); /// # // ... use num /// # /// # Poll::Ready(()) /// # } /// ``` #[macro_export] macro_rules! ready { ($e:expr $(,)?) => { match $e { core::task::Poll::Ready(t) => t, core::task::Poll::Pending => return core::task::Poll::Pending, } }; } /// Pins a variable of type `T` on the stack and rebinds it as `Pin<&mut T>`. /// /// ``` /// use futures_lite::{future, pin}; /// use std::fmt::Debug; /// use std::future::Future; /// use std::pin::Pin; /// use std::time::Instant; /// /// // Inspects each invocation of `Future::poll()`. /// async fn inspect(f: impl Future) -> T { /// pin!(f); /// future::poll_fn(|cx| dbg!(f.as_mut().poll(cx))).await /// } /// /// # spin_on::spin_on(async { /// let f = async { 1 + 2 }; /// inspect(f).await; /// # }) /// ``` #[macro_export] macro_rules! pin { ($($x:ident),* $(,)?) => { $( let mut $x = $x; #[allow(unused_mut)] let mut $x = unsafe { core::pin::Pin::new_unchecked(&mut $x) }; )* } } futures-lite-1.12.0/src/prelude.rs000064400000000000000000000010400000000000000151020ustar 00000000000000//! Traits [`Future`], [`Stream`], [`AsyncRead`], [`AsyncWrite`], [`AsyncBufRead`], //! [`AsyncSeek`], and their extensions. //! //! # Examples //! //! ``` //! use futures_lite::prelude::*; //! ``` #[doc(no_inline)] pub use crate::{ future::{Future, FutureExt as _}, stream::{Stream, StreamExt as _}, }; #[cfg(feature = "std")] #[doc(no_inline)] pub use crate::{ io::{AsyncBufRead, AsyncBufReadExt as _}, io::{AsyncRead, AsyncReadExt as _}, io::{AsyncSeek, AsyncSeekExt as _}, io::{AsyncWrite, AsyncWriteExt as _}, }; futures-lite-1.12.0/src/stream.rs000064400000000000000000002303000000000000000147400ustar 00000000000000//! Combinators for the [`Stream`] trait. //! //! # Examples //! //! ``` //! use futures_lite::stream::{self, StreamExt}; //! //! # spin_on::spin_on(async { //! let mut s = stream::iter(vec![1, 2, 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, None); //! # }); //! ``` #[cfg(feature = "alloc")] extern crate alloc; #[doc(no_inline)] pub use futures_core::stream::Stream; #[cfg(feature = "alloc")] use alloc::boxed::Box; use core::fmt; use core::future::Future; use core::marker::PhantomData; use core::mem; use core::pin::Pin; use core::task::{Context, Poll}; use pin_project_lite::pin_project; use crate::ready; /// Converts a stream into a blocking iterator. /// /// # Examples /// /// ``` /// use futures_lite::{pin, stream}; /// /// let stream = stream::once(7); /// pin!(stream); /// /// let mut iter = stream::block_on(stream); /// assert_eq!(iter.next(), Some(7)); /// assert_eq!(iter.next(), None); /// ``` #[cfg(feature = "std")] pub fn block_on(stream: S) -> BlockOn { BlockOn(stream) } /// Iterator for the [`block_on()`] function. #[derive(Debug)] pub struct BlockOn(S); #[cfg(feature = "std")] impl Iterator for BlockOn { type Item = S::Item; fn next(&mut self) -> Option { crate::future::block_on(self.0.next()) } } /// Creates an empty stream. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::empty::(); /// assert_eq!(s.next().await, None); /// # }) /// ``` pub fn empty() -> Empty { Empty { _marker: PhantomData, } } /// Stream for the [`empty()`] function. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Empty { _marker: PhantomData, } impl Unpin for Empty {} 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)) } } /// Creates a stream from an iterator. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::iter(vec![1, 2]); /// /// assert_eq!(s.next().await, Some(1)); /// assert_eq!(s.next().await, Some(2)); /// assert_eq!(s.next().await, None); /// # }) /// ``` pub fn iter(iter: I) -> Iter { Iter { iter: iter.into_iter(), } } /// Stream for the [`iter()`] function. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Iter { iter: I, } impl Unpin for Iter {} impl Stream for Iter { type Item = I::Item; fn poll_next(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { Poll::Ready(self.iter.next()) } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } /// Creates a stream that yields a single item. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::once(7); /// /// assert_eq!(s.next().await, Some(7)); /// assert_eq!(s.next().await, None); /// # }) /// ``` pub fn once(t: T) -> Once { Once { value: Some(t) } } pin_project! { /// Stream for the [`once()`] function. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Once { value: Option, } } impl Stream for Once { type Item = T; fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { Poll::Ready(self.project().value.take()) } fn size_hint(&self) -> (usize, Option) { if self.value.is_some() { (1, Some(1)) } else { (0, Some(0)) } } } /// Creates a stream that is always pending. /// /// # Examples /// /// ```no_run /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::pending::(); /// s.next().await; /// unreachable!(); /// # }) /// ``` pub fn pending() -> Pending { Pending { _marker: PhantomData, } } /// Stream for the [`pending()`] function. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Pending { _marker: PhantomData, } impl Unpin for Pending {} 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)) } } /// Creates a stream from a function returning [`Poll`]. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// use std::task::{Context, Poll}; /// /// # spin_on::spin_on(async { /// fn f(_: &mut Context<'_>) -> Poll> { /// Poll::Ready(Some(7)) /// } /// /// assert_eq!(stream::poll_fn(f).next().await, Some(7)); /// # }) /// ``` pub fn poll_fn(f: F) -> PollFn where F: FnMut(&mut Context<'_>) -> Poll>, { PollFn { f } } /// Stream for the [`poll_fn()`] function. #[derive(Clone)] #[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() } } 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) } } /// Creates an infinite stream that yields the same item repeatedly. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::repeat(7); /// /// assert_eq!(s.next().await, Some(7)); /// assert_eq!(s.next().await, Some(7)); /// # }) /// ``` pub fn repeat(item: T) -> Repeat { Repeat { item } } /// Stream for the [`repeat()`] function. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Repeat { item: T, } impl Unpin for Repeat {} impl Stream for Repeat { 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) } } /// Creates an infinite stream from a closure that generates items. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::repeat_with(|| 7); /// /// assert_eq!(s.next().await, Some(7)); /// assert_eq!(s.next().await, Some(7)); /// # }) /// ``` pub fn repeat_with(repeater: F) -> RepeatWith where F: FnMut() -> T, { RepeatWith { f: repeater } } /// Stream for the [`repeat_with()`] function. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct RepeatWith { f: F, } impl Unpin for RepeatWith {} impl Stream for RepeatWith where F: FnMut() -> T, { type Item = T; fn poll_next(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { let item = (&mut self.f)(); Poll::Ready(Some(item)) } fn size_hint(&self) -> (usize, Option) { (usize::max_value(), None) } } /// Creates a stream from a seed value and an async closure operating on it. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::unfold(0, |mut n| async move { /// if n < 2 { /// let m = n + 1; /// Some((n, m)) /// } else { /// None /// } /// }); /// /// let v: Vec = s.collect().await; /// assert_eq!(v, [0, 1]); /// # }) /// ``` pub fn unfold(seed: T, f: F) -> Unfold where F: FnMut(T) -> Fut, Fut: Future>, { Unfold { f, state: Some(seed), fut: None, } } pin_project! { /// Stream for the [`unfold()`] function. #[derive(Clone)] #[must_use = "streams do nothing unless polled"] pub struct Unfold { f: F, state: Option, #[pin] fut: Option, } } 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) .field("fut", &self.fut) .finish() } } 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.take() { this.fut.set(Some((this.f)(state))); } let step = ready!(this .fut .as_mut() .as_pin_mut() .expect("`Unfold` must not be polled after it returned `Poll::Ready(None)`") .poll(cx)); this.fut.set(None); if let Some((item, next_state)) = step { *this.state = Some(next_state); Poll::Ready(Some(item)) } else { Poll::Ready(None) } } } /// Creates a stream from a seed value and a fallible async closure operating on it. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::try_unfold(0, |mut n| async move { /// if n < 2 { /// let m = n + 1; /// Ok(Some((n, m))) /// } else { /// std::io::Result::Ok(None) /// } /// }); /// /// let v: Vec = s.try_collect().await?; /// assert_eq!(v, [0, 1]); /// # std::io::Result::Ok(()) }); /// ``` pub fn try_unfold(init: T, f: F) -> TryUnfold where F: FnMut(T) -> Fut, Fut: Future, E>>, { TryUnfold { f, state: Some(init), fut: None, } } pin_project! { /// Stream for the [`try_unfold()`] function. #[derive(Clone)] #[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: Future, E>>, { 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.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))), } } } } } /// Extension trait for [`Stream`]. pub trait StreamExt: Stream { /// A convenience for calling [`Stream::poll_next()`] on `!`[`Unpin`] types. fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll> where Self: Unpin, { Stream::poll_next(Pin::new(self), cx) } /// Retrieves the next item in the stream. /// /// Returns [`None`] when iteration is finished. Stream implementations may choose to or not to /// resume iteration after that. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::iter(1..=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, None); /// # }); /// ``` fn next(&mut self) -> NextFuture<'_, Self> where Self: Unpin, { NextFuture { stream: self } } /// Retrieves the next item in the stream. /// /// This is similar to the [`next()`][`StreamExt::next()`] method, but returns /// `Result, E>` rather than `Option>`. /// /// Note that `s.try_next().await` is equivalent to `s.next().await.transpose()`. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::iter(vec![Ok(1), Ok(2), Err("error")]); /// /// assert_eq!(s.try_next().await, Ok(Some(1))); /// assert_eq!(s.try_next().await, Ok(Some(2))); /// assert_eq!(s.try_next().await, Err("error")); /// assert_eq!(s.try_next().await, Ok(None)); /// # }); /// ``` fn try_next(&mut self) -> TryNextFuture<'_, Self> where Self: Stream> + Unpin, { TryNextFuture { stream: self } } /// Counts the number of items in the stream. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s1 = stream::iter(vec![0]); /// let s2 = stream::iter(vec![1, 2, 3]); /// /// assert_eq!(s1.count().await, 1); /// assert_eq!(s2.count().await, 3); /// # }); /// ``` fn count(self) -> CountFuture where Self: Sized, { CountFuture { stream: self, count: 0, } } /// Maps items of the stream to new values using a closure. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::iter(vec![1, 2, 3]); /// let mut s = s.map(|x| 2 * x); /// /// assert_eq!(s.next().await, Some(2)); /// assert_eq!(s.next().await, Some(4)); /// assert_eq!(s.next().await, Some(6)); /// assert_eq!(s.next().await, None); /// # }); /// ``` fn map(self, f: F) -> Map where Self: Sized, F: FnMut(Self::Item) -> T, { Map { stream: self, f } } /// Maps items to streams and then concatenates them. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let words = stream::iter(vec!["one", "two"]); /// /// let s: String = words /// .flat_map(|s| stream::iter(s.chars())) /// .collect() /// .await; /// /// assert_eq!(s, "onetwo"); /// # }); /// ``` fn flat_map(self, f: F) -> FlatMap where Self: Sized, U: Stream, F: FnMut(Self::Item) -> U, { FlatMap { stream: self.map(f), inner_stream: None, } } /// Concatenates inner streams. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s1 = stream::iter(vec![1, 2, 3]); /// let s2 = stream::iter(vec![4, 5]); /// /// let s = stream::iter(vec![s1, s2]); /// let v: Vec<_> = s.flatten().collect().await; /// assert_eq!(v, [1, 2, 3, 4, 5]); /// # }); /// ``` fn flatten(self) -> Flatten where Self: Sized, Self::Item: Stream, { Flatten { stream: self, inner_stream: None, } } /// Maps items of the stream to new values using an async closure. /// /// # Examples /// /// ``` /// use futures_lite::pin; /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::iter(vec![1, 2, 3]); /// let mut s = s.then(|x| async move { 2 * x }); /// /// pin!(s); /// assert_eq!(s.next().await, Some(2)); /// assert_eq!(s.next().await, Some(4)); /// assert_eq!(s.next().await, Some(6)); /// assert_eq!(s.next().await, None); /// # }); /// ``` fn then(self, f: F) -> Then where Self: Sized, F: FnMut(Self::Item) -> Fut, Fut: Future, { Then { stream: self, future: None, f, } } /// Keeps items of the stream for which `predicate` returns `true`. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::iter(vec![1, 2, 3, 4]); /// let mut s = s.filter(|i| i % 2 == 0); /// /// assert_eq!(s.next().await, Some(2)); /// assert_eq!(s.next().await, Some(4)); /// assert_eq!(s.next().await, None); /// # }); /// ``` fn filter

(self, predicate: P) -> Filter where Self: Sized, P: FnMut(&Self::Item) -> bool, { Filter { stream: self, predicate, } } /// Filters and maps items of the stream using a closure. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::iter(vec!["1", "lol", "3", "NaN", "5"]); /// let mut s = s.filter_map(|a| a.parse::().ok()); /// /// assert_eq!(s.next().await, Some(1)); /// assert_eq!(s.next().await, Some(3)); /// assert_eq!(s.next().await, Some(5)); /// assert_eq!(s.next().await, None); /// # }); /// ``` fn filter_map(self, f: F) -> FilterMap where Self: Sized, F: FnMut(Self::Item) -> Option, { FilterMap { stream: self, f } } /// Takes only the first `n` items of the stream. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::repeat(7).take(2); /// /// assert_eq!(s.next().await, Some(7)); /// assert_eq!(s.next().await, Some(7)); /// assert_eq!(s.next().await, None); /// # }); /// ``` fn take(self, n: usize) -> Take where Self: Sized, { Take { stream: self, n } } /// Takes items while `predicate` returns `true`. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::iter(vec![1, 2, 3, 4]); /// let mut s = s.take_while(|x| *x < 3); /// /// assert_eq!(s.next().await, Some(1)); /// assert_eq!(s.next().await, Some(2)); /// assert_eq!(s.next().await, None); /// # }); /// ``` fn take_while

(self, predicate: P) -> TakeWhile where Self: Sized, P: FnMut(&Self::Item) -> bool, { TakeWhile { stream: self, predicate, } } /// Skips the first `n` items of the stream. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::iter(vec![1, 2, 3]); /// let mut s = s.skip(2); /// /// assert_eq!(s.next().await, Some(3)); /// assert_eq!(s.next().await, None); /// # }); /// ``` fn skip(self, n: usize) -> Skip where Self: Sized, { Skip { stream: self, n } } /// Skips items while `predicate` returns `true`. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::iter(vec![-1i32, 0, 1]); /// let mut s = s.skip_while(|x| x.is_negative()); /// /// assert_eq!(s.next().await, Some(0)); /// assert_eq!(s.next().await, Some(1)); /// assert_eq!(s.next().await, None); /// # }); /// ``` fn skip_while

(self, predicate: P) -> SkipWhile where Self: Sized, P: FnMut(&Self::Item) -> bool, { SkipWhile { stream: self, predicate: Some(predicate), } } /// Yields every `step`th item. /// /// # Panics /// /// This method will panic if the `step` is 0. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::iter(vec![0, 1, 2, 3, 4]); /// let mut s = s.step_by(2); /// /// assert_eq!(s.next().await, Some(0)); /// assert_eq!(s.next().await, Some(2)); /// assert_eq!(s.next().await, Some(4)); /// assert_eq!(s.next().await, None); /// # }); /// ``` fn step_by(self, step: usize) -> StepBy where Self: Sized, { assert!(step > 0, "`step` must be greater than zero"); StepBy { stream: self, step, i: 0, } } /// Appends another stream to the end of this one. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s1 = stream::iter(vec![1, 2]); /// let s2 = stream::iter(vec![7, 8]); /// let mut s = s1.chain(s2); /// /// assert_eq!(s.next().await, Some(1)); /// assert_eq!(s.next().await, Some(2)); /// assert_eq!(s.next().await, Some(7)); /// assert_eq!(s.next().await, Some(8)); /// assert_eq!(s.next().await, None); /// # }); /// ``` fn chain(self, other: U) -> Chain where Self: Sized, U: Stream + Sized, { Chain { first: self.fuse(), second: other.fuse(), } } /// Clones all items. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::iter(vec![&1, &2]); /// let mut s = s.cloned(); /// /// assert_eq!(s.next().await, Some(1)); /// assert_eq!(s.next().await, Some(2)); /// assert_eq!(s.next().await, None); /// # }); /// ``` fn cloned<'a, T>(self) -> Cloned where Self: Stream + Sized, T: Clone + 'a, { Cloned { stream: self } } /// Copies all items. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::iter(vec![&1, &2]); /// let mut s = s.copied(); /// /// assert_eq!(s.next().await, Some(1)); /// assert_eq!(s.next().await, Some(2)); /// assert_eq!(s.next().await, None); /// # }); /// ``` fn copied<'a, T>(self) -> Copied where Self: Stream + Sized, T: Copy + 'a, { Copied { stream: self } } /// Collects all items in the stream into a collection. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::iter(1..=3); /// /// let items: Vec<_> = s.collect().await; /// assert_eq!(items, [1, 2, 3]); /// # }); /// ``` fn collect(self) -> CollectFuture where Self: Sized, C: Default + Extend, { CollectFuture { stream: self, collection: Default::default(), } } /// Collects all items in the fallible stream into a collection. /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::iter(vec![Ok(1), Err(2), Ok(3)]); /// let res: Result, i32> = s.try_collect().await; /// assert_eq!(res, Err(2)); /// /// let s = stream::iter(vec![Ok(1), Ok(2), Ok(3)]); /// let res: Result, i32> = s.try_collect().await; /// assert_eq!(res, Ok(vec![1, 2, 3])); /// # }) /// ``` fn try_collect(self) -> TryCollectFuture where Self: Stream> + Sized, C: Default + Extend, { TryCollectFuture { stream: self, items: Default::default(), } } /// Partitions items into those for which `predicate` is `true` and those for which it is /// `false`, and then collects them into two collections. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::iter(vec![1, 2, 3]); /// let (even, odd): (Vec<_>, Vec<_>) = s.partition(|&n| n % 2 == 0).await; /// /// assert_eq!(even, &[2]); /// assert_eq!(odd, &[1, 3]); /// # }) /// ``` fn partition(self, predicate: P) -> PartitionFuture where Self: Sized, B: Default + Extend, P: FnMut(&Self::Item) -> bool, { PartitionFuture { stream: self, predicate, res: Some(Default::default()), } } /// Accumulates a computation over the stream. /// /// The computation begins with the accumulator value set to `init`, and then applies `f` to /// the accumulator and each item in the stream. The final accumulator value is returned. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::iter(vec![1, 2, 3]); /// let sum = s.fold(0, |acc, x| acc + x).await; /// /// assert_eq!(sum, 6); /// # }) /// ``` fn fold(self, init: T, f: F) -> FoldFuture where Self: Sized, F: FnMut(T, Self::Item) -> T, { FoldFuture { stream: self, f, acc: Some(init), } } /// Accumulates a fallible computation over the stream. /// /// The computation begins with the accumulator value set to `init`, and then applies `f` to /// the accumulator and each item in the stream. The final accumulator value is returned, or an /// error if `f` failed the computation. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::iter(vec![Ok(1), Ok(2), Ok(3)]); /// /// let sum = s.try_fold(0, |acc, v| { /// if (acc + v) % 2 == 1 { /// Ok(acc + v) /// } else { /// Err("fail") /// } /// }) /// .await; /// /// assert_eq!(sum, Err("fail")); /// # }) /// ``` fn try_fold(&mut self, init: B, f: F) -> TryFoldFuture<'_, Self, F, B> where Self: Stream> + Unpin + Sized, F: FnMut(B, T) -> Result, { TryFoldFuture { stream: self, f, acc: Some(init), } } /// Maps items of the stream to new values using a state value and a closure. /// /// Scanning begins with the inital state set to `initial_state`, and then applies `f` to the /// state and each item in the stream. The stream stops when `f` returns `None`. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::iter(vec![1, 2, 3]); /// let mut s = s.scan(1, |state, x| { /// *state = *state * x; /// Some(-*state) /// }); /// /// assert_eq!(s.next().await, Some(-1)); /// assert_eq!(s.next().await, Some(-2)); /// assert_eq!(s.next().await, Some(-6)); /// assert_eq!(s.next().await, None); /// # }) /// ``` fn scan(self, initial_state: St, f: F) -> Scan where Self: Sized, F: FnMut(&mut St, Self::Item) -> Option, { Scan { stream: self, state_f: (initial_state, f), } } /// Fuses the stream so that it stops yielding items after the first [`None`]. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::once(1).fuse(); /// /// assert_eq!(s.next().await, Some(1)); /// assert_eq!(s.next().await, None); /// assert_eq!(s.next().await, None); /// # }) /// ``` fn fuse(self) -> Fuse where Self: Sized, { Fuse { stream: self, done: false, } } /// Repeats the stream from beginning to end, forever. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::iter(vec![1, 2]).cycle(); /// /// assert_eq!(s.next().await, Some(1)); /// assert_eq!(s.next().await, Some(2)); /// assert_eq!(s.next().await, Some(1)); /// assert_eq!(s.next().await, Some(2)); /// # }); /// ``` fn cycle(self) -> Cycle where Self: Clone + Sized, { Cycle { orig: self.clone(), stream: self, } } /// Enumerates items, mapping them to `(index, item)`. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::iter(vec!['a', 'b', 'c']); /// let mut s = s.enumerate(); /// /// assert_eq!(s.next().await, Some((0, 'a'))); /// assert_eq!(s.next().await, Some((1, 'b'))); /// assert_eq!(s.next().await, Some((2, 'c'))); /// assert_eq!(s.next().await, None); /// # }); /// ``` fn enumerate(self) -> Enumerate where Self: Sized, { Enumerate { stream: self, i: 0 } } /// Calls a closure on each item and passes it on. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::iter(vec![1, 2, 3, 4, 5]); /// /// let sum = s /// .inspect(|x| println!("about to filter {}", x)) /// .filter(|x| x % 2 == 0) /// .inspect(|x| println!("made it through filter: {}", x)) /// .fold(0, |sum, i| sum + i) /// .await; /// # }); /// ``` fn inspect(self, f: F) -> Inspect where Self: Sized, F: FnMut(&Self::Item), { Inspect { stream: self, f } } /// Gets the `n`th item of the stream. /// /// In the end, `n+1` items of the stream will be consumed. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::iter(vec![0, 1, 2, 3, 4, 5, 6, 7]); /// /// assert_eq!(s.nth(2).await, Some(2)); /// assert_eq!(s.nth(2).await, Some(5)); /// assert_eq!(s.nth(2).await, None); /// # }); /// ``` fn nth(&mut self, n: usize) -> NthFuture<'_, Self> where Self: Unpin, { NthFuture { stream: self, n } } /// Returns the last item in the stream. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::iter(vec![1, 2, 3, 4]); /// assert_eq!(s.last().await, Some(4)); /// /// let s = stream::empty::(); /// assert_eq!(s.last().await, None); /// # }); /// ``` fn last(self) -> LastFuture where Self: Sized, { LastFuture { stream: self, last: None, } } /// Finds the first item of the stream for which `predicate` returns `true`. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::iter(vec![11, 12, 13, 14]); /// /// assert_eq!(s.find(|x| *x % 2 == 0).await, Some(12)); /// assert_eq!(s.next().await, Some(13)); /// # }); /// ``` fn find

(&mut self, predicate: P) -> FindFuture<'_, Self, P> where Self: Unpin, P: FnMut(&Self::Item) -> bool, { FindFuture { stream: self, predicate, } } /// Applies a closure to items in the stream and returns the first [`Some`] result. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::iter(vec!["lol", "NaN", "2", "5"]); /// let number = s.find_map(|s| s.parse().ok()).await; /// /// assert_eq!(number, Some(2)); /// # }); /// ``` fn find_map(&mut self, f: F) -> FindMapFuture<'_, Self, F> where Self: Unpin, F: FnMut(Self::Item) -> Option, { FindMapFuture { stream: self, f } } /// Finds the index of the first item of the stream for which `predicate` returns `true`. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::iter(vec![0, 1, 2, 3, 4, 5]); /// /// assert_eq!(s.position(|x| x == 2).await, Some(2)); /// assert_eq!(s.position(|x| x == 3).await, Some(0)); /// assert_eq!(s.position(|x| x == 9).await, None); /// # }); /// ``` fn position

(&mut self, predicate: P) -> PositionFuture<'_, Self, P> where Self: Unpin, P: FnMut(Self::Item) -> bool, { PositionFuture { stream: self, predicate, index: 0, } } /// Tests if `predicate` returns `true` for all items in the stream. /// /// The result is `true` for an empty stream. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::iter(vec![1, 2, 3]); /// assert!(!s.all(|x| x % 2 == 0).await); /// /// let mut s = stream::iter(vec![2, 4, 6, 8]); /// assert!(s.all(|x| x % 2 == 0).await); /// /// let mut s = stream::empty::(); /// assert!(s.all(|x| x % 2 == 0).await); /// # }); /// ``` fn all

(&mut self, predicate: P) -> AllFuture<'_, Self, P> where Self: Unpin, P: FnMut(Self::Item) -> bool, { AllFuture { stream: self, predicate, } } /// Tests if `predicate` returns `true` for any item in the stream. /// /// The result is `false` for an empty stream. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::iter(vec![1, 3, 5, 7]); /// assert!(!s.any(|x| x % 2 == 0).await); /// /// let mut s = stream::iter(vec![1, 2, 3]); /// assert!(s.any(|x| x % 2 == 0).await); /// /// let mut s = stream::empty::(); /// assert!(!s.any(|x| x % 2 == 0).await); /// # }); /// ``` fn any

(&mut self, predicate: P) -> AnyFuture<'_, Self, P> where Self: Unpin, P: FnMut(Self::Item) -> bool, { AnyFuture { stream: self, predicate, } } /// Calls a closure on each item of the stream. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::iter(vec![1, 2, 3]); /// s.for_each(|s| println!("{}", s)).await; /// # }); /// ``` fn for_each(self, f: F) -> ForEachFuture where Self: Sized, F: FnMut(Self::Item), { ForEachFuture { stream: self, f } } /// Calls a fallible closure on each item of the stream, stopping on first error. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let mut s = stream::iter(vec![0, 1, 2, 3]); /// /// let mut v = vec![]; /// let res = s /// .try_for_each(|n| { /// if n < 2 { /// v.push(n); /// Ok(()) /// } else { /// Err("too big") /// } /// }) /// .await; /// /// assert_eq!(v, &[0, 1]); /// assert_eq!(res, Err("too big")); /// # }); /// ``` fn try_for_each(&mut self, f: F) -> TryForEachFuture<'_, Self, F> where Self: Unpin, F: FnMut(Self::Item) -> Result<(), E>, { TryForEachFuture { stream: self, f } } /// Zips up two streams into a single stream of pairs. /// /// The stream of pairs stops when either of the original two streams is exhausted. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let l = stream::iter(vec![1, 2, 3]); /// let r = stream::iter(vec![4, 5, 6, 7]); /// let mut s = l.zip(r); /// /// assert_eq!(s.next().await, Some((1, 4))); /// assert_eq!(s.next().await, Some((2, 5))); /// assert_eq!(s.next().await, Some((3, 6))); /// assert_eq!(s.next().await, None); /// # }); /// ``` fn zip(self, other: U) -> Zip where Self: Sized, U: Stream, { Zip { item_slot: None, first: self, second: other, } } /// Collects a stream of pairs into a pair of collections. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let s = stream::iter(vec![(1, 2), (3, 4)]); /// let (left, right): (Vec<_>, Vec<_>) = s.unzip().await; /// /// assert_eq!(left, [1, 3]); /// assert_eq!(right, [2, 4]); /// # }); /// ``` fn unzip(self) -> UnzipFuture where FromA: Default + Extend, FromB: Default + Extend, Self: Stream + Sized, { UnzipFuture { stream: self, res: Some(Default::default()), } } /// Merges with `other` stream, preferring items from `self` whenever both streams are ready. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// use futures_lite::stream::{once, pending}; /// /// # spin_on::spin_on(async { /// assert_eq!(once(1).or(pending()).next().await, Some(1)); /// assert_eq!(pending().or(once(2)).next().await, Some(2)); /// /// // The first future wins. /// assert_eq!(once(1).or(once(2)).next().await, Some(1)); /// # }) /// ``` fn or(self, other: S) -> Or where Self: Sized, S: Stream, { Or { stream1: self, stream2: other, } } /// Merges with `other` stream, with no preference for either stream when both are ready. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// use futures_lite::stream::{once, pending}; /// /// # spin_on::spin_on(async { /// assert_eq!(once(1).race(pending()).next().await, Some(1)); /// assert_eq!(pending().race(once(2)).next().await, Some(2)); /// /// // One of the two stream is randomly chosen as the winner. /// let res = once(1).race(once(2)).next().await; /// # }) /// ``` #[cfg(feature = "std")] fn race(self, other: S) -> Race where Self: Sized, S: Stream, { Race { stream1: self, stream2: other, } } /// Boxes the stream and changes its type to `dyn Stream + Send + 'a`. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let a = stream::once(1); /// let b = stream::empty(); /// /// // Streams of different types can be stored in /// // the same collection when they are boxed: /// let streams = vec![a.boxed(), b.boxed()]; /// # }) /// ``` #[cfg(feature = "alloc")] fn boxed<'a>(self) -> Pin + Send + 'a>> where Self: Send + Sized + 'a, { Box::pin(self) } /// Boxes the stream and changes its type to `dyn Stream + 'a`. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// # spin_on::spin_on(async { /// let a = stream::once(1); /// let b = stream::empty(); /// /// // Streams of different types can be stored in /// // the same collection when they are boxed: /// let streams = vec![a.boxed_local(), b.boxed_local()]; /// # }) /// ``` #[cfg(feature = "alloc")] fn boxed_local<'a>(self) -> Pin + 'a>> where Self: Sized + 'a, { Box::pin(self) } } impl StreamExt for S {} /// Type alias for `Pin + Send + 'static>>`. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// // These two lines are equivalent: /// let s1: stream::Boxed = stream::once(7).boxed(); /// let s2: stream::Boxed = Box::pin(stream::once(7)); /// ``` #[cfg(feature = "alloc")] pub type Boxed = Pin + Send + 'static>>; /// Type alias for `Pin + 'static>>`. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, StreamExt}; /// /// // These two lines are equivalent: /// let s1: stream::BoxedLocal = stream::once(7).boxed_local(); /// let s2: stream::BoxedLocal = Box::pin(stream::once(7)); /// ``` #[cfg(feature = "alloc")] pub type BoxedLocal = Pin + 'static>>; /// Future for the [`StreamExt::next()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct NextFuture<'a, S: ?Sized> { stream: &'a mut S, } impl Unpin for NextFuture<'_, S> {} impl Future for NextFuture<'_, S> { type Output = Option; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { self.stream.poll_next(cx) } } /// Future for the [`StreamExt::try_next()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct TryNextFuture<'a, S: ?Sized> { stream: &'a mut S, } impl Unpin for TryNextFuture<'_, S> {} impl Future for TryNextFuture<'_, S> where S: Stream> + Unpin + ?Sized, { type Output = Result, E>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let res = ready!(self.stream.poll_next(cx)); Poll::Ready(res.transpose()) } } pin_project! { /// Future for the [`StreamExt::count()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct CountFuture { count: usize, #[pin] stream: S, } } impl Future for CountFuture { type Output = usize; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { loop { match ready!(self.as_mut().project().stream.poll_next(cx)) { None => return Poll::Ready(self.count), Some(_) => *self.as_mut().project().count += 1, } } } } pin_project! { /// Future for the [`StreamExt::collect()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct CollectFuture { #[pin] stream: S, collection: C, } } impl Future for CollectFuture where S: 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(mem::replace(self.project().collection, Default::default())) } } } } } pin_project! { /// Future for the [`StreamExt::try_collect()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct TryCollectFuture { #[pin] stream: S, items: C, } } impl Future for TryCollectFuture where S: Stream>, 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().poll_next(cx)?) { Some(x) => this.items.extend(Some(x)), None => break mem::replace(this.items, Default::default()), } })) } } pin_project! { /// Future for the [`StreamExt::partition()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct PartitionFuture { #[pin] stream: S, predicate: P, res: Option<(B, B)>, } } impl Future for PartitionFuture where S: Stream + Sized, P: FnMut(&S::Item) -> bool, B: Default + Extend, { type Output = (B, B); 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)) { Some(v) => { let res = this.res.as_mut().unwrap(); if (this.predicate)(&v) { res.0.extend(Some(v)) } else { res.1.extend(Some(v)) } } None => return Poll::Ready(this.res.take().unwrap()), } } } } pin_project! { /// Future for the [`StreamExt::fold()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct FoldFuture { #[pin] stream: S, f: F, acc: Option, } } impl Future for FoldFuture where S: Stream, F: FnMut(T, S::Item) -> T, { type Output = T; 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)) { Some(v) => { let old = this.acc.take().unwrap(); let new = (this.f)(old, v); *this.acc = Some(new); } None => return Poll::Ready(this.acc.take().unwrap()), } } } } /// Future for the [`StreamExt::try_fold()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct TryFoldFuture<'a, S, F, B> { stream: &'a mut S, f: F, acc: Option, } impl<'a, S, F, B> Unpin for TryFoldFuture<'a, S, F, B> {} impl<'a, T, E, S, F, B> Future for TryFoldFuture<'a, S, F, B> where S: Stream> + Unpin, F: FnMut(B, T) -> Result, { type Output = Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { loop { match ready!(self.stream.poll_next(cx)) { Some(Err(e)) => return Poll::Ready(Err(e)), Some(Ok(t)) => { let old = self.acc.take().unwrap(); let new = (&mut self.f)(old, t); match new { Ok(t) => self.acc = Some(t), Err(e) => return Poll::Ready(Err(e)), } } None => return Poll::Ready(Ok(self.acc.take().unwrap())), } } } } pin_project! { /// Stream for the [`StreamExt::scan()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Scan { #[pin] stream: S, state_f: (St, F), } } impl Stream for Scan where S: Stream, F: FnMut(&mut St, S::Item) -> Option, { type Item = B; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); this.stream.as_mut().poll_next(cx).map(|item| { item.and_then(|item| { let (state, f) = this.state_f; f(state, item) }) }) } } pin_project! { /// Stream for the [`StreamExt::fuse()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Fuse { #[pin] stream: S, done: bool, } } 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 { Poll::Ready(None) } else { let next = ready!(this.stream.poll_next(cx)); if next.is_none() { *this.done = true; } Poll::Ready(next) } } } pin_project! { /// Stream for the [`StreamExt::map()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Map { #[pin] stream: S, f: F, } } impl Stream for Map where S: Stream, F: FnMut(S::Item) -> T, { type Item = T; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); let next = ready!(this.stream.poll_next(cx)); Poll::Ready(next.map(this.f)) } fn size_hint(&self) -> (usize, Option) { self.stream.size_hint() } } pin_project! { /// Stream for the [`StreamExt::flat_map()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct FlatMap { #[pin] stream: Map, #[pin] inner_stream: Option, } } impl Stream for FlatMap where S: Stream, U: Stream, F: FnMut(S::Item) -> U, { type Item = U::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); loop { if let Some(inner) = this.inner_stream.as_mut().as_pin_mut() { match ready!(inner.poll_next(cx)) { Some(item) => return Poll::Ready(Some(item)), None => this.inner_stream.set(None), } } match ready!(this.stream.as_mut().poll_next(cx)) { Some(stream) => this.inner_stream.set(Some(stream)), None => return Poll::Ready(None), } } } } pin_project! { /// Stream for the [`StreamExt::flat_map()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Flatten { #[pin] stream: S, #[pin] inner_stream: Option, } } impl Stream for Flatten where S: Stream, U: Stream, { type Item = U::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); loop { if let Some(inner) = this.inner_stream.as_mut().as_pin_mut() { match ready!(inner.poll_next(cx)) { Some(item) => return Poll::Ready(Some(item)), None => this.inner_stream.set(None), } } match ready!(this.stream.as_mut().poll_next(cx)) { Some(inner) => this.inner_stream.set(Some(inner)), None => return Poll::Ready(None), } } } } pin_project! { /// Stream for the [`StreamExt::then()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Then { #[pin] stream: S, #[pin] future: Option, f: F, } } impl Stream for Then where S: Stream, F: FnMut(S::Item) -> Fut, Fut: Future, { type Item = Fut::Output; fn poll_next(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() { let item = ready!(fut.poll(cx)); this.future.set(None); return Poll::Ready(Some(item)); } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) { this.future.set(Some((this.f)(item))); } else { return Poll::Ready(None); } } } fn size_hint(&self) -> (usize, Option) { let future_len = if self.future.is_some() { 1 } else { 0 }; let (lower, upper) = self.stream.size_hint(); let lower = lower.saturating_add(future_len); let upper = upper.and_then(|u| u.checked_add(future_len)); (lower, upper) } } pin_project! { /// Stream for the [`StreamExt::filter()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Filter { #[pin] stream: S, predicate: P, } } impl Stream for Filter where S: Stream, P: FnMut(&S::Item) -> bool, { type Item = S::Item; fn poll_next(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(None), Some(v) if (this.predicate)(&v) => return Poll::Ready(Some(v)), Some(_) => {} } } } } /// Merges two streams, preferring items from `stream1` whenever both streams are ready. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, once, pending, StreamExt}; /// /// # spin_on::spin_on(async { /// assert_eq!(stream::or(once(1), pending()).next().await, Some(1)); /// assert_eq!(stream::or(pending(), once(2)).next().await, Some(2)); /// /// // The first stream wins. /// assert_eq!(stream::or(once(1), once(2)).next().await, Some(1)); /// # }) /// ``` pub fn or(stream1: S1, stream2: S2) -> Or where S1: Stream, S2: Stream, { Or { stream1, stream2 } } pin_project! { /// Stream for the [`or()`] function and the [`StreamExt::or()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Or { #[pin] stream1: S1, #[pin] stream2: S2, } } impl Stream for Or where S1: Stream, S2: Stream, { type Item = T; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); if let Poll::Ready(Some(t)) = this.stream1.as_mut().poll_next(cx) { return Poll::Ready(Some(t)); } this.stream2.as_mut().poll_next(cx) } } /// Merges two streams, with no preference for either stream when both are ready. /// /// # Examples /// /// ``` /// use futures_lite::stream::{self, once, pending, StreamExt}; /// /// # spin_on::spin_on(async { /// assert_eq!(stream::race(once(1), pending()).next().await, Some(1)); /// assert_eq!(stream::race(pending(), once(2)).next().await, Some(2)); /// /// // One of the two stream is randomly chosen as the winner. /// let res = stream::race(once(1), once(2)).next().await; /// # }) #[cfg(feature = "std")] pub fn race(stream1: S1, stream2: S2) -> Race where S1: Stream, S2: Stream, { Race { stream1, stream2 } } #[cfg(feature = "std")] pin_project! { /// Stream for the [`race()`] function and the [`StreamExt::race()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Race { #[pin] stream1: S1, #[pin] stream2: S2, } } #[cfg(feature = "std")] impl Stream for Race where S1: Stream, S2: Stream, { type Item = T; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); if fastrand::bool() { if let Poll::Ready(Some(t)) = this.stream1.as_mut().poll_next(cx) { return Poll::Ready(Some(t)); } if let Poll::Ready(Some(t)) = this.stream2.as_mut().poll_next(cx) { return Poll::Ready(Some(t)); } } else { if let Poll::Ready(Some(t)) = this.stream2.as_mut().poll_next(cx) { return Poll::Ready(Some(t)); } if let Poll::Ready(Some(t)) = this.stream1.as_mut().poll_next(cx) { return Poll::Ready(Some(t)); } } Poll::Pending } } pin_project! { /// Stream for the [`StreamExt::filter_map()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct FilterMap { #[pin] stream: S, f: F, } } impl Stream for FilterMap where S: Stream, F: FnMut(S::Item) -> Option, { type Item = T; fn poll_next(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(None), Some(v) => { if let Some(t) = (this.f)(v) { return Poll::Ready(Some(t)); } } } } } } pin_project! { /// Stream for the [`StreamExt::take()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Take { #[pin] stream: S, n: usize, } } impl Stream for Take { type Item = S::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); if *this.n == 0 { Poll::Ready(None) } else { let next = ready!(this.stream.poll_next(cx)); match next { Some(_) => *this.n -= 1, None => *this.n = 0, } Poll::Ready(next) } } } pin_project! { /// Stream for the [`StreamExt::take_while()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct TakeWhile { #[pin] stream: S, predicate: P, } } impl Stream for TakeWhile where S: Stream, P: FnMut(&S::Item) -> bool, { type Item = S::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); match ready!(this.stream.poll_next(cx)) { Some(v) => { if (this.predicate)(&v) { Poll::Ready(Some(v)) } else { Poll::Ready(None) } } None => Poll::Ready(None), } } } pin_project! { /// Stream for the [`StreamExt::skip()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Skip { #[pin] stream: S, n: usize, } } impl Stream for Skip { type Item = S::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); loop { match ready!(this.stream.as_mut().poll_next(cx)) { Some(v) => match *this.n { 0 => return Poll::Ready(Some(v)), _ => *this.n -= 1, }, None => return Poll::Ready(None), } } } } pin_project! { /// Stream for the [`StreamExt::skip_while()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct SkipWhile { #[pin] stream: S, predicate: Option

, } } impl Stream for SkipWhile where S: Stream, P: FnMut(&S::Item) -> bool, { type Item = S::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); loop { match ready!(this.stream.as_mut().poll_next(cx)) { Some(v) => match this.predicate { Some(p) => { if !p(&v) { *this.predicate = None; return Poll::Ready(Some(v)); } } None => return Poll::Ready(Some(v)), }, None => return Poll::Ready(None), } } } } pin_project! { /// Stream for the [`StreamExt::step_by()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct StepBy { #[pin] stream: S, step: usize, i: usize, } } impl Stream for StepBy { type Item = S::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); loop { match ready!(this.stream.as_mut().poll_next(cx)) { Some(v) => { if *this.i == 0 { *this.i = *this.step - 1; return Poll::Ready(Some(v)); } else { *this.i -= 1; } } None => return Poll::Ready(None), } } } } pin_project! { /// Stream for the [`StreamExt::chain()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Chain { #[pin] first: Fuse, #[pin] second: Fuse, } } impl> Stream for Chain { type Item = S::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); if !this.first.done { let next = ready!(this.first.as_mut().poll_next(cx)); if let Some(next) = next { return Poll::Ready(Some(next)); } } if !this.second.done { let next = ready!(this.second.as_mut().poll_next(cx)); if let Some(next) = next { return Poll::Ready(Some(next)); } } if this.first.done && this.second.done { Poll::Ready(None) } else { Poll::Pending } } } pin_project! { /// Stream for the [`StreamExt::cloned()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Cloned { #[pin] stream: S, } } impl<'a, S, T: 'a> Stream for Cloned where S: Stream, T: Clone, { type Item = T; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); let next = ready!(this.stream.poll_next(cx)); Poll::Ready(next.cloned()) } } pin_project! { /// Stream for the [`StreamExt::copied()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Copied { #[pin] stream: S, } } impl<'a, S, T: 'a> Stream for Copied where S: Stream, T: Copy, { type Item = T; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); let next = ready!(this.stream.poll_next(cx)); Poll::Ready(next.copied()) } } pin_project! { /// Stream for the [`StreamExt::cycle()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Cycle { orig: S, #[pin] stream: S, } } impl Stream for Cycle where S: Stream + Clone, { type Item = S::Item; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match ready!(self.as_mut().project().stream.as_mut().poll_next(cx)) { Some(item) => Poll::Ready(Some(item)), None => { let new = self.as_mut().orig.clone(); self.as_mut().project().stream.set(new); self.project().stream.poll_next(cx) } } } } pin_project! { /// Stream for the [`StreamExt::cycle()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Enumerate { #[pin] stream: S, i: usize, } } impl Stream for Enumerate where S: Stream, { type Item = (usize, S::Item); fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); match ready!(this.stream.poll_next(cx)) { Some(v) => { let ret = (*this.i, v); *this.i += 1; Poll::Ready(Some(ret)) } None => Poll::Ready(None), } } } pin_project! { /// Stream for the [`StreamExt::inspect()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Inspect { #[pin] stream: S, f: F, } } impl Stream for Inspect where S: Stream, F: FnMut(&S::Item), { type Item = S::Item; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let mut this = self.project(); let next = ready!(this.stream.as_mut().poll_next(cx)); if let Some(x) = &next { (this.f)(x); } Poll::Ready(next) } } /// Future for the [`StreamExt::nth()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct NthFuture<'a, S: ?Sized> { stream: &'a mut S, n: usize, } impl Unpin for NthFuture<'_, S> {} impl<'a, S> Future for NthFuture<'a, S> where S: Stream + Unpin + ?Sized, { type Output = Option; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { loop { match ready!(self.stream.poll_next(cx)) { Some(v) => match self.n { 0 => return Poll::Ready(Some(v)), _ => self.n -= 1, }, None => return Poll::Ready(None), } } } } pin_project! { /// Future for the [`StreamExt::last()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct LastFuture { #[pin] stream: S, last: Option, } } impl Future for LastFuture { type Output = Option; 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)) { Some(new) => *this.last = Some(new), None => return Poll::Ready(this.last.take()), } } } } /// Future for the [`StreamExt::find()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct FindFuture<'a, S: ?Sized, P> { stream: &'a mut S, predicate: P, } impl Unpin for FindFuture<'_, S, P> {} impl<'a, S, P> Future for FindFuture<'a, S, P> where S: Stream + Unpin + ?Sized, P: FnMut(&S::Item) -> bool, { type Output = Option; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { loop { match ready!(self.stream.poll_next(cx)) { Some(v) if (&mut self.predicate)(&v) => return Poll::Ready(Some(v)), Some(_) => {} None => return Poll::Ready(None), } } } } /// Future for the [`StreamExt::find_map()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct FindMapFuture<'a, S: ?Sized, F> { stream: &'a mut S, f: F, } impl Unpin for FindMapFuture<'_, S, F> {} impl<'a, S, B, F> Future for FindMapFuture<'a, S, F> where S: Stream + Unpin + ?Sized, F: FnMut(S::Item) -> Option, { type Output = Option; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { loop { match ready!(self.stream.poll_next(cx)) { Some(v) => { if let Some(v) = (&mut self.f)(v) { return Poll::Ready(Some(v)); } } None => return Poll::Ready(None), } } } } /// Future for the [`StreamExt::position()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct PositionFuture<'a, S: ?Sized, P> { stream: &'a mut S, predicate: P, index: usize, } impl<'a, S: Unpin + ?Sized, P> Unpin for PositionFuture<'a, S, P> {} impl<'a, S, P> Future for PositionFuture<'a, S, P> where S: Stream + Unpin + ?Sized, P: FnMut(S::Item) -> bool, { type Output = Option; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { loop { match ready!(self.stream.poll_next(cx)) { Some(v) => { if (&mut self.predicate)(v) { return Poll::Ready(Some(self.index)); } else { self.index += 1; } } None => return Poll::Ready(None), } } } } /// Future for the [`StreamExt::all()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct AllFuture<'a, S: ?Sized, P> { stream: &'a mut S, predicate: P, } impl Unpin for AllFuture<'_, S, P> {} impl Future for AllFuture<'_, S, P> where S: Stream + Unpin + ?Sized, P: FnMut(S::Item) -> bool, { type Output = bool; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { loop { match ready!(self.stream.poll_next(cx)) { Some(v) => { if !(&mut self.predicate)(v) { return Poll::Ready(false); } } None => return Poll::Ready(true), } } } } /// Future for the [`StreamExt::any()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct AnyFuture<'a, S: ?Sized, P> { stream: &'a mut S, predicate: P, } impl Unpin for AnyFuture<'_, S, P> {} impl Future for AnyFuture<'_, S, P> where S: Stream + Unpin + ?Sized, P: FnMut(S::Item) -> bool, { type Output = bool; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { loop { match ready!(self.stream.poll_next(cx)) { Some(v) => { if (&mut self.predicate)(v) { return Poll::Ready(true); } } None => return Poll::Ready(false), } } } } pin_project! { /// Future for the [`StreamExt::for_each()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct ForEachFuture { #[pin] stream: S, f: F, } } impl Future for ForEachFuture where S: Stream, F: FnMut(S::Item), { type Output = (); 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)) { Some(v) => (this.f)(v), None => return Poll::Ready(()), } } } } /// Future for the [`StreamExt::try_for_each()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct TryForEachFuture<'a, S: ?Sized, F> { stream: &'a mut S, f: F, } impl<'a, S: Unpin + ?Sized, F> Unpin for TryForEachFuture<'a, S, F> {} impl<'a, S, F, E> Future for TryForEachFuture<'a, S, F> where S: Stream + Unpin + ?Sized, F: FnMut(S::Item) -> Result<(), E>, { type Output = Result<(), E>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { loop { match ready!(self.stream.poll_next(cx)) { None => return Poll::Ready(Ok(())), Some(v) => (&mut self.f)(v)?, } } } } pin_project! { /// Stream for the [`StreamExt::zip()`] method. #[derive(Clone, Debug)] #[must_use = "streams do nothing unless polled"] pub struct Zip { item_slot: Option, #[pin] first: A, #[pin] second: B, } } impl Stream for Zip { type Item = (A::Item, B::Item); fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); if this.item_slot.is_none() { match this.first.poll_next(cx) { Poll::Pending => return Poll::Pending, Poll::Ready(None) => return Poll::Ready(None), Poll::Ready(Some(item)) => *this.item_slot = Some(item), } } let second_item = ready!(this.second.poll_next(cx)); let first_item = this.item_slot.take().unwrap(); Poll::Ready(second_item.map(|second_item| (first_item, second_item))) } } pin_project! { /// Future for the [`StreamExt::unzip()`] method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct UnzipFuture { #[pin] stream: S, res: Option<(FromA, FromB)>, } } impl Future for UnzipFuture where S: Stream, FromA: Default + Extend, FromB: Default + Extend, { type Output = (FromA, FromB); 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)) { Some((a, b)) => { let res = this.res.as_mut().unwrap(); res.0.extend(Some(a)); res.1.extend(Some(b)); } None => return Poll::Ready(this.res.take().unwrap()), } } } }