aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-15 21:44:05 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-15 21:44:05 +0000
commit9853b768e3e30475e787d7cc6a9aded8155e185c (patch)
tree40ff38ba7efefc72f4eb5f49327b0a83727f254f
parente910e64e08d57dfe1b1f7941e1324f4a7977d28f (diff)
parent5a2ead4f79e3b4c604edd450714bd1d925de1d4e (diff)
downloadfutures-util-9853b768e3e30475e787d7cc6a9aded8155e185c.tar.gz
Change-Id: Ie332a12e79d6861a2d37b552d05d8b4d81bafb7b
-rw-r--r--.cargo_vcs_info.json7
-rw-r--r--Android.bp102
-rw-r--r--Cargo.toml99
-rw-r--r--Cargo.toml.orig27
-rw-r--r--METADATA8
-rw-r--r--README.md23
-rw-r--r--TEST_MAPPING48
-rw-r--r--benches/flatten_unordered.rs66
-rw-r--r--benches/futures_unordered.rs4
-rw-r--r--benches_disabled/bilock.rs208
-rw-r--r--build.rs41
-rw-r--r--cargo2android.json5
-rw-r--r--no_atomic_cas.rs13
-rw-r--r--src/abortable.rs185
-rw-r--r--src/async_await/join_mod.rs6
-rw-r--r--src/async_await/mod.rs11
-rw-r--r--src/async_await/pending.rs2
-rw-r--r--src/async_await/poll.rs2
-rw-r--r--src/async_await/select_mod.rs9
-rw-r--r--src/async_await/stream_select_mod.rs40
-rw-r--r--src/compat/compat01as03.rs92
-rw-r--r--src/compat/compat03as01.rs68
-rw-r--r--src/compat/executor.rs5
-rw-r--r--src/compat/mod.rs8
-rw-r--r--src/fns.rs61
-rw-r--r--src/future/abortable.rs170
-rw-r--r--src/future/either.rs31
-rw-r--r--src/future/future/catch_unwind.rs10
-rw-r--r--src/future/future/flatten.rs47
-rw-r--r--src/future/future/fuse.rs4
-rw-r--r--src/future/future/remote_handle.rs14
-rw-r--r--src/future/future/shared.rs35
-rw-r--r--src/future/join.rs11
-rw-r--r--src/future/join_all.rs109
-rw-r--r--src/future/lazy.rs15
-rw-r--r--src/future/mod.rs24
-rw-r--r--src/future/option.rs13
-rw-r--r--src/future/pending.rs7
-rw-r--r--src/future/poll_fn.rs5
-rw-r--r--src/future/poll_immediate.rs126
-rw-r--r--src/future/select.rs18
-rw-r--r--src/future/select_all.rs26
-rw-r--r--src/future/select_ok.rs29
-rw-r--r--src/future/try_future/into_future.rs9
-rw-r--r--src/future/try_future/try_flatten.rs77
-rw-r--r--src/future/try_future/try_flatten_err.rs24
-rw-r--r--src/future/try_join_all.rs31
-rw-r--r--src/future/try_maybe_done.rs18
-rw-r--r--src/future/try_select.rs25
-rw-r--r--src/io/allow_std.rs101
-rw-r--r--src/io/buf_reader.rs94
-rw-r--r--src/io/buf_writer.rs73
-rw-r--r--src/io/chain.rs18
-rw-r--r--src/io/copy.rs8
-rw-r--r--src/io/copy_buf.rs15
-rw-r--r--src/io/cursor.rs22
-rw-r--r--src/io/empty.rs8
-rw-r--r--src/io/fill_buf.rs5
-rw-r--r--src/io/flush.rs3
-rw-r--r--src/io/into_sink.rs31
-rw-r--r--src/io/line_writer.rs155
-rw-r--r--src/io/lines.rs13
-rw-r--r--src/io/mod.rs118
-rw-r--r--src/io/read_exact.rs4
-rw-r--r--src/io/read_line.rs11
-rw-r--r--src/io/read_to_end.rs11
-rw-r--r--src/io/read_to_string.rs14
-rw-r--r--src/io/repeat.rs8
-rw-r--r--src/io/split.rs53
-rw-r--r--src/io/take.rs34
-rw-r--r--src/io/window.rs5
-rw-r--r--src/io/write_all_vectored.rs29
-rw-r--r--src/lib.rs57
-rw-r--r--src/lock/bilock.rs29
-rw-r--r--src/lock/mod.rs35
-rw-r--r--src/lock/mutex.rs32
-rw-r--r--src/sink/buffer.rs49
-rw-r--r--src/sink/close.rs10
-rw-r--r--src/sink/drain.rs20
-rw-r--r--src/sink/err_into.rs28
-rw-r--r--src/sink/fanout.rs50
-rw-r--r--src/sink/feed.rs10
-rw-r--r--src/sink/flush.rs10
-rw-r--r--src/sink/map_err.rs29
-rw-r--r--src/sink/mod.rs3
-rw-r--r--src/sink/send.rs9
-rw-r--r--src/sink/send_all.rs35
-rw-r--r--src/sink/unfold.rs5
-rw-r--r--src/sink/with.rs75
-rw-r--r--src/sink/with_flat_map.rs35
-rw-r--r--src/stream/abortable.rs19
-rw-r--r--src/stream/empty.rs6
-rw-r--r--src/stream/futures_ordered.rs10
-rw-r--r--src/stream/futures_unordered/iter.rs85
-rw-r--r--src/stream/futures_unordered/mod.rs192
-rw-r--r--src/stream/futures_unordered/ready_to_run_queue.rs43
-rw-r--r--src/stream/futures_unordered/task.rs19
-rw-r--r--src/stream/iter.rs10
-rw-r--r--src/stream/mod.rs68
-rw-r--r--src/stream/once.rs2
-rw-r--r--src/stream/poll_immediate.rs80
-rw-r--r--src/stream/repeat.rs11
-rw-r--r--src/stream/repeat_with.rs5
-rw-r--r--src/stream/select.rs99
-rw-r--r--src/stream/select_all.rs159
-rw-r--r--src/stream/select_with_strategy.rs229
-rw-r--r--src/stream/stream/all.rs92
-rw-r--r--src/stream/stream/any.rs92
-rw-r--r--src/stream/stream/buffer_unordered.rs11
-rw-r--r--src/stream/stream/buffered.rs17
-rw-r--r--src/stream/stream/catch_unwind.rs15
-rw-r--r--src/stream/stream/chain.rs29
-rw-r--r--src/stream/stream/chunks.rs20
-rw-r--r--src/stream/stream/collect.rs15
-rw-r--r--src/stream/stream/concat.rs35
-rw-r--r--src/stream/stream/count.rs53
-rw-r--r--src/stream/stream/cycle.rs5
-rw-r--r--src/stream/stream/enumerate.rs10
-rw-r--r--src/stream/stream/filter.rs42
-rw-r--r--src/stream/stream/filter_map.rs35
-rw-r--r--src/stream/stream/flatten_unordered.rs509
-rw-r--r--src/stream/stream/fold.rs28
-rw-r--r--src/stream/stream/for_each.rs27
-rw-r--r--src/stream/stream/for_each_concurrent.rs29
-rw-r--r--src/stream/stream/forward.rs15
-rw-r--r--src/stream/stream/fuse.rs5
-rw-r--r--src/stream/stream/into_future.rs5
-rw-r--r--src/stream/stream/map.rs24
-rw-r--r--src/stream/stream/mod.rs285
-rw-r--r--src/stream/stream/next.rs5
-rw-r--r--src/stream/stream/peek.rs311
-rw-r--r--src/stream/stream/ready_chunks.rs23
-rw-r--r--src/stream/stream/scan.rs15
-rw-r--r--src/stream/stream/select_next_some.rs4
-rw-r--r--src/stream/stream/skip.rs17
-rw-r--r--src/stream/stream/skip_while.rs41
-rw-r--r--src/stream/stream/split.rs31
-rw-r--r--src/stream/stream/take.rs23
-rw-r--r--src/stream/stream/take_until.rs12
-rw-r--r--src/stream/stream/take_while.rs39
-rw-r--r--src/stream/stream/then.rs38
-rw-r--r--src/stream/stream/unzip.rs27
-rw-r--r--src/stream/stream/zip.rs24
-rw-r--r--src/stream/try_stream/and_then.rs31
-rw-r--r--src/stream/try_stream/into_async_read.rs81
-rw-r--r--src/stream/try_stream/into_stream.rs5
-rw-r--r--src/stream/try_stream/mod.rs123
-rw-r--r--src/stream/try_stream/or_else.rs33
-rw-r--r--src/stream/try_stream/try_buffer_unordered.rs24
-rw-r--r--src/stream/try_stream/try_buffered.rs9
-rw-r--r--src/stream/try_stream/try_chunks.rs131
-rw-r--r--src/stream/try_stream/try_collect.rs10
-rw-r--r--src/stream/try_stream/try_concat.rs5
-rw-r--r--src/stream/try_stream/try_filter.rs34
-rw-r--r--src/stream/try_stream/try_filter_map.rs26
-rw-r--r--src/stream/try_stream/try_fold.rs28
-rw-r--r--src/stream/try_stream/try_for_each.rs20
-rw-r--r--src/stream/try_stream/try_for_each_concurrent.rs29
-rw-r--r--src/stream/try_stream/try_next.rs5
-rw-r--r--src/stream/try_stream/try_skip_while.rs39
-rw-r--r--src/stream/try_stream/try_take_while.rs8
-rw-r--r--src/stream/try_stream/try_unfold.rs16
-rw-r--r--src/stream/unfold.rs13
-rw-r--r--src/task/mod.rs30
-rw-r--r--src/task/spawn.rs3
165 files changed, 2488 insertions, 4632 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index b52386f..f3ad3ab 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,5 @@
{
"git": {
- "sha1": "fc1e3250219170e31cddb8857a276cba7dd08d44"
- },
- "path_in_vcs": "futures-util"
-} \ No newline at end of file
+ "sha1": "c91f8691672c7401b1923ab00bf138975c99391a"
+ }
+}
diff --git a/Android.bp b/Android.bp
index 9d3dea9..5f4d572 100644
--- a/Android.bp
+++ b/Android.bp
@@ -37,18 +37,12 @@ license {
],
}
-rust_test {
- name: "futures-util_test_src_lib",
- host_supported: true,
+rust_defaults {
+ name: "futures-util_defaults",
crate_name: "futures_util",
- cargo_env_compat: true,
- cargo_pkg_version: "0.3.21",
srcs: ["src/lib.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
- test_options: {
- unit_test: true,
- },
edition: "2018",
features: [
"alloc",
@@ -62,6 +56,8 @@ rust_test {
"futures-sink",
"io",
"memchr",
+ "proc-macro-hack",
+ "proc-macro-nested",
"sink",
"slab",
"std",
@@ -75,18 +71,33 @@ rust_test {
"libmemchr",
"libpin_project_lite",
"libpin_utils",
+ "libproc_macro_nested",
"libslab",
"libtokio",
],
- proc_macros: ["libfutures_macro"],
+ proc_macros: [
+ "libfutures_macro",
+ "libproc_macro_hack",
+ ],
+}
+
+rust_test_host {
+ name: "futures-util_host_test_src_lib",
+ defaults: ["futures-util_defaults"],
+ test_options: {
+ unit_test: true,
+ },
+}
+
+rust_test {
+ name: "futures-util_device_test_src_lib",
+ defaults: ["futures-util_defaults"],
}
rust_library {
name: "libfutures_util",
host_supported: true,
crate_name: "futures_util",
- cargo_env_compat: true,
- cargo_pkg_version: "0.3.21",
srcs: ["src/lib.rs"],
edition: "2018",
features: [
@@ -101,6 +112,8 @@ rust_library {
"futures-sink",
"io",
"memchr",
+ "proc-macro-hack",
+ "proc-macro-nested",
"sink",
"slab",
"std",
@@ -114,14 +127,77 @@ rust_library {
"libmemchr",
"libpin_project_lite",
"libpin_utils",
+ "libproc_macro_nested",
"libslab",
],
- proc_macros: ["libfutures_macro"],
+ proc_macros: [
+ "libfutures_macro",
+ "libproc_macro_hack",
+ ],
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth",
"com.android.resolv",
"com.android.virt",
],
min_sdk_version: "29",
}
+
+// dependent_library ["feature_list"]
+// autocfg-1.0.1
+// byteorder-1.4.3 "default,std"
+// bytes-0.4.12
+// cfg-if-0.1.10
+// cfg-if-1.0.0
+// crossbeam-deque-0.7.3
+// crossbeam-epoch-0.8.2 "default,lazy_static,std"
+// crossbeam-queue-0.2.3 "default,std"
+// crossbeam-utils-0.7.2 "default,lazy_static,std"
+// fnv-1.0.7 "default,std"
+// futures-0.1.31 "default,use_std,with-deprecated"
+// futures-channel-0.3.14 "alloc,std"
+// futures-core-0.3.14 "alloc,std"
+// futures-io-0.3.14 "std"
+// futures-macro-0.3.13
+// futures-sink-0.3.14
+// futures-task-0.3.14 "alloc,std"
+// iovec-0.1.4
+// lazy_static-1.4.0
+// libc-0.2.94 "default,std"
+// lock_api-0.3.4
+// log-0.4.14
+// maybe-uninit-2.0.0
+// memchr-2.3.4 "default,std"
+// memoffset-0.5.6 "default"
+// mio-0.6.23 "default,with-deprecated"
+// mio-uds-0.6.8
+// net2-0.2.37 "default,duration"
+// num_cpus-1.13.0
+// parking_lot-0.9.0 "default"
+// parking_lot_core-0.6.2
+// pin-project-lite-0.2.6
+// pin-utils-0.1.0
+// proc-macro-hack-0.5.19
+// proc-macro-nested-0.1.7
+// proc-macro2-1.0.26 "default,proc-macro"
+// quote-1.0.9 "default,proc-macro"
+// rustc_version-0.2.3
+// scopeguard-1.1.0
+// semver-0.9.0 "default"
+// semver-parser-0.7.0
+// slab-0.4.3 "default,std"
+// smallvec-0.6.14 "default,std"
+// syn-1.0.70 "clone-impls,default,derive,full,parsing,printing,proc-macro,quote"
+// tokio-0.1.22 "bytes,codec,default,fs,io,mio,num_cpus,reactor,rt-full,sync,tcp,timer,tokio-codec,tokio-current-thread,tokio-executor,tokio-fs,tokio-io,tokio-reactor,tokio-sync,tokio-tcp,tokio-threadpool,tokio-timer,tokio-udp,tokio-uds,udp,uds"
+// tokio-codec-0.1.2
+// tokio-current-thread-0.1.7
+// tokio-executor-0.1.10
+// tokio-fs-0.1.7
+// tokio-io-0.1.13
+// tokio-reactor-0.1.12
+// tokio-sync-0.1.8
+// tokio-tcp-0.1.4
+// tokio-threadpool-0.1.18
+// tokio-timer-0.2.13
+// tokio-udp-0.1.6
+// tokio-uds-0.2.7
+// unicode-xid-0.2.1 "default"
diff --git a/Cargo.toml b/Cargo.toml
index a148319..9b87df6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,59 +3,54 @@
# 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.
+# to registry (e.g., crates.io) dependencies
#
-# If you are reading this file be aware that the original Cargo.toml
-# will likely look very different (and much more reasonable).
-# See Cargo.toml.orig for the original contents.
+# 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"
-rust-version = "1.45"
name = "futures-util"
-version = "0.3.21"
-description = """
-Common utilities and extension traits for the futures-rs library.
-"""
+version = "0.3.13"
+authors = ["Alex Crichton <alex@alexcrichton.com>"]
+description = "Common utilities and extension traits for the futures-rs library.\n"
homepage = "https://rust-lang.github.io/futures-rs"
+documentation = "https://docs.rs/futures-util/0.3"
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-lang/futures-rs"
-
[package.metadata.docs.rs]
all-features = true
-rustdoc-args = [
- "--cfg",
- "docsrs",
-]
-
+rustdoc-args = ["--cfg", "docsrs"]
[dependencies.futures-channel]
-version = "0.3.21"
+version = "0.3.13"
features = ["std"]
optional = true
default-features = false
[dependencies.futures-core]
-version = "0.3.21"
+version = "0.3.13"
default-features = false
[dependencies.futures-io]
-version = "0.3.21"
+version = "0.3.13"
features = ["std"]
optional = true
default-features = false
[dependencies.futures-macro]
-version = "=0.3.21"
+version = "=0.3.13"
optional = true
default-features = false
[dependencies.futures-sink]
-version = "0.3.21"
+version = "0.3.13"
optional = true
default-features = false
[dependencies.futures-task]
-version = "0.3.21"
+version = "0.3.13"
default-features = false
[dependencies.futures_01]
@@ -73,6 +68,14 @@ version = "0.2.4"
[dependencies.pin-utils]
version = "0.1.0"
+[dependencies.proc-macro-hack]
+version = "0.5.19"
+optional = true
+
+[dependencies.proc-macro-nested]
+version = "0.1.2"
+optional = true
+
[dependencies.slab]
version = "0.4.2"
optional = true
@@ -80,54 +83,22 @@ optional = true
[dependencies.tokio-io]
version = "0.1.9"
optional = true
-
[dev-dependencies.tokio]
version = "0.1.11"
[features]
-alloc = [
- "futures-core/alloc",
- "futures-task/alloc",
-]
+alloc = ["futures-core/alloc", "futures-task/alloc"]
async-await = []
-async-await-macro = [
- "async-await",
- "futures-macro",
-]
+async-await-macro = ["async-await", "futures-macro", "proc-macro-hack", "proc-macro-nested"]
bilock = []
-cfg-target-has-atomic = []
-channel = [
- "std",
- "futures-channel",
-]
-compat = [
- "std",
- "futures_01",
-]
-default = [
- "std",
- "async-await",
- "async-await-macro",
-]
-io = [
- "std",
- "futures-io",
- "memchr",
-]
-io-compat = [
- "io",
- "compat",
- "tokio-io",
-]
+cfg-target-has-atomic = ["futures-core/cfg-target-has-atomic", "futures-task/cfg-target-has-atomic"]
+channel = ["std", "futures-channel"]
+compat = ["std", "futures_01"]
+default = ["std", "async-await", "async-await-macro"]
+io = ["std", "futures-io", "memchr"]
+io-compat = ["io", "compat", "tokio-io"]
+read-initializer = ["io", "futures-io/read-initializer", "futures-io/unstable"]
sink = ["futures-sink"]
-std = [
- "alloc",
- "futures-core/std",
- "futures-task/std",
- "slab",
-]
-unstable = [
- "futures-core/unstable",
- "futures-task/unstable",
-]
+std = ["alloc", "futures-core/std", "futures-task/std", "slab"]
+unstable = ["futures-core/unstable", "futures-task/unstable"]
write-all-vectored = ["io"]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 46ec854..b7cc193 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,11 +1,12 @@
[package]
name = "futures-util"
-version = "0.3.21"
edition = "2018"
-rust-version = "1.45"
+version = "0.3.13"
+authors = ["Alex Crichton <alex@alexcrichton.com>"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-lang/futures-rs"
homepage = "https://rust-lang.github.io/futures-rs"
+documentation = "https://docs.rs/futures-util/0.3"
description = """
Common utilities and extension traits for the futures-rs library.
"""
@@ -15,7 +16,7 @@ default = ["std", "async-await", "async-await-macro"]
std = ["alloc", "futures-core/std", "futures-task/std", "slab"]
alloc = ["futures-core/alloc", "futures-task/alloc"]
async-await = []
-async-await-macro = ["async-await", "futures-macro"]
+async-await-macro = ["async-await", "futures-macro", "proc-macro-hack", "proc-macro-nested"]
compat = ["std", "futures_01"]
io-compat = ["io", "compat", "tokio-io"]
sink = ["futures-sink"]
@@ -26,20 +27,20 @@ channel = ["std", "futures-channel"]
# These features are outside of the normal semver guarantees and require the
# `unstable` feature as an explicit opt-in to unstable API.
unstable = ["futures-core/unstable", "futures-task/unstable"]
+cfg-target-has-atomic = ["futures-core/cfg-target-has-atomic", "futures-task/cfg-target-has-atomic"]
bilock = []
+read-initializer = ["io", "futures-io/read-initializer", "futures-io/unstable"]
write-all-vectored = ["io"]
-# These features are no longer used.
-# TODO: remove in the next major version.
-cfg-target-has-atomic = []
-
[dependencies]
-futures-core = { path = "../futures-core", version = "0.3.21", default-features = false }
-futures-task = { path = "../futures-task", version = "0.3.21", default-features = false }
-futures-channel = { path = "../futures-channel", version = "0.3.21", default-features = false, features = ["std"], optional = true }
-futures-io = { path = "../futures-io", version = "0.3.21", default-features = false, features = ["std"], optional = true }
-futures-sink = { path = "../futures-sink", version = "0.3.21", default-features = false, optional = true }
-futures-macro = { path = "../futures-macro", version = "=0.3.21", default-features = false, optional = true }
+futures-core = { path = "../futures-core", version = "0.3.13", default-features = false }
+futures-task = { path = "../futures-task", version = "0.3.13", default-features = false }
+futures-channel = { path = "../futures-channel", version = "0.3.13", default-features = false, features = ["std"], optional = true }
+futures-io = { path = "../futures-io", version = "0.3.13", default-features = false, features = ["std"], optional = true }
+futures-sink = { path = "../futures-sink", version = "0.3.13", default-features = false, optional = true }
+futures-macro = { path = "../futures-macro", version = "=0.3.13", default-features = false, optional = true }
+proc-macro-hack = { version = "0.5.19", optional = true }
+proc-macro-nested = { version = "0.1.2", optional = true }
slab = { version = "0.4.2", optional = true }
memchr = { version = "2.2", optional = true }
futures_01 = { version = "0.1.25", optional = true, package = "futures" }
diff --git a/METADATA b/METADATA
index ed41eb9..36be8c4 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/futures-util/futures-util-0.3.21.crate"
+ value: "https://static.crates.io/crates/futures-util/futures-util-0.3.13.crate"
}
- version: "0.3.21"
+ version: "0.3.13"
license_type: NOTICE
last_upgrade_date {
- year: 2022
- month: 3
+ year: 2021
+ month: 4
day: 1
}
}
diff --git a/README.md b/README.md
deleted file mode 100644
index 6e0aaed..0000000
--- a/README.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# futures-util
-
-Common utilities and extension traits for the futures-rs library.
-
-## Usage
-
-Add this to your `Cargo.toml`:
-
-```toml
-[dependencies]
-futures-util = "0.3"
-```
-
-The current `futures-util` requires Rust 1.45 or later.
-
-## License
-
-Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or
-[MIT license](LICENSE-MIT) at your option.
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in the work by you, as defined in the Apache-2.0 license, shall
-be dual licensed as above, without any additional terms or conditions.
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 1c27227..203632d 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,48 +1,56 @@
// Generated by update_crate_tests.py for tests that depend on this crate.
{
- "imports": [
+ "presubmit": [
{
- "path": "external/rust/crates/anyhow"
+ "name": "anyhow_device_test_tests_test_boxed"
},
{
- "path": "external/rust/crates/tokio"
+ "name": "anyhow_device_test_tests_test_ffi"
},
{
- "path": "external/rust/crates/tokio-test"
- }
- ],
- "presubmit": [
+ "name": "futures-util_device_test_src_lib"
+ },
{
- "name": "ZipFuseTest"
+ "name": "anyhow_device_test_tests_test_chain"
},
{
- "name": "authfs_device_test_src_lib"
+ "name": "anyhow_device_test_tests_test_convert"
},
{
- "name": "doh_unit_test"
+ "name": "anyhow_device_test_tests_test_source"
},
{
- "name": "futures-util_test_src_lib"
+ "name": "tokio-test_device_test_tests_io"
},
{
- "name": "virtualizationservice_device_test"
- }
- ],
- "presubmit-rust": [
+ "name": "tokio-test_device_test_tests_macros"
+ },
+ {
+ "name": "anyhow_device_test_tests_test_context"
+ },
+ {
+ "name": "anyhow_device_test_tests_test_autotrait"
+ },
+ {
+ "name": "tokio-test_device_test_src_lib"
+ },
+ {
+ "name": "anyhow_device_test_tests_test_macros"
+ },
{
- "name": "ZipFuseTest"
+ "name": "anyhow_device_test_src_lib"
},
{
- "name": "authfs_device_test_src_lib"
+ "name": "tokio-test_device_test_tests_block_on"
},
{
- "name": "doh_unit_test"
+ "name": "anyhow_device_test_tests_test_fmt"
},
{
- "name": "futures-util_test_src_lib"
+ "name": "anyhow_device_test_tests_test_downcast"
},
{
- "name": "virtualizationservice_device_test"
+ "name": "anyhow_device_test_tests_test_repr"
}
]
}
diff --git a/benches/flatten_unordered.rs b/benches/flatten_unordered.rs
deleted file mode 100644
index 64d5f9a..0000000
--- a/benches/flatten_unordered.rs
+++ /dev/null
@@ -1,66 +0,0 @@
-#![feature(test)]
-
-extern crate test;
-use crate::test::Bencher;
-
-use futures::channel::oneshot;
-use futures::executor::block_on;
-use futures::future::{self, FutureExt};
-use futures::stream::{self, StreamExt};
-use futures::task::Poll;
-use std::collections::VecDeque;
-use std::thread;
-
-#[bench]
-fn oneshot_streams(b: &mut Bencher) {
- const STREAM_COUNT: usize = 10_000;
- const STREAM_ITEM_COUNT: usize = 1;
-
- b.iter(|| {
- let mut txs = VecDeque::with_capacity(STREAM_COUNT);
- let mut rxs = Vec::new();
-
- for _ in 0..STREAM_COUNT {
- let (tx, rx) = oneshot::channel();
- txs.push_back(tx);
- rxs.push(rx);
- }
-
- thread::spawn(move || {
- let mut last = 1;
- while let Some(tx) = txs.pop_front() {
- let _ = tx.send(stream::iter(last..last + STREAM_ITEM_COUNT));
- last += STREAM_ITEM_COUNT;
- }
- });
-
- let mut flatten = stream::unfold(rxs.into_iter(), |mut vals| {
- async {
- if let Some(next) = vals.next() {
- let val = next.await.unwrap();
- Some((val, vals))
- } else {
- None
- }
- }
- .boxed()
- })
- .flatten_unordered(None);
-
- block_on(future::poll_fn(move |cx| {
- let mut count = 0;
- loop {
- match flatten.poll_next_unpin(cx) {
- Poll::Ready(None) => break,
- Poll::Ready(Some(_)) => {
- count += 1;
- }
- _ => {}
- }
- }
- assert_eq!(count, STREAM_COUNT * STREAM_ITEM_COUNT);
-
- Poll::Ready(())
- }))
- });
-}
diff --git a/benches/futures_unordered.rs b/benches/futures_unordered.rs
index d5fe7a5..05e9ead 100644
--- a/benches/futures_unordered.rs
+++ b/benches/futures_unordered.rs
@@ -6,7 +6,7 @@ use crate::test::Bencher;
use futures::channel::oneshot;
use futures::executor::block_on;
use futures::future;
-use futures::stream::{FuturesUnordered, StreamExt};
+use futures::stream::{StreamExt, FuturesUnordered};
use futures::task::Poll;
use std::collections::VecDeque;
use std::thread;
@@ -34,7 +34,7 @@ fn oneshots(b: &mut Bencher) {
block_on(future::poll_fn(move |cx| {
loop {
if let Poll::Ready(None) = rxs.poll_next_unpin(cx) {
- break;
+ break
}
}
Poll::Ready(())
diff --git a/benches_disabled/bilock.rs b/benches_disabled/bilock.rs
index 417f75d..48afe3c 100644
--- a/benches_disabled/bilock.rs
+++ b/benches_disabled/bilock.rs
@@ -2,121 +2,125 @@
#[cfg(feature = "bilock")]
mod bench {
- use futures::executor::LocalPool;
- use futures::task::{Context, Waker};
- use futures_util::lock::BiLock;
- use futures_util::lock::BiLockAcquire;
- use futures_util::lock::BiLockAcquired;
- use futures_util::task::ArcWake;
+use futures::task::{Context, Waker};
+use futures::executor::LocalPool;
+use futures_util::lock::BiLock;
+use futures_util::lock::BiLockAcquire;
+use futures_util::lock::BiLockAcquired;
+use futures_util::task::ArcWake;
- use std::sync::Arc;
- use test::Bencher;
+use std::sync::Arc;
+use test::Bencher;
- fn notify_noop() -> Waker {
- struct Noop;
+fn notify_noop() -> Waker {
+ struct Noop;
- impl ArcWake for Noop {
- fn wake(_: &Arc<Self>) {}
- }
+ impl ArcWake for Noop {
+ fn wake(_: &Arc<Self>) {}
+ }
+
+ ArcWake::into_waker(Arc::new(Noop))
+}
- ArcWake::into_waker(Arc::new(Noop))
+
+/// Pseudo-stream which simply calls `lock.poll()` on `poll`
+struct LockStream {
+ lock: BiLockAcquire<u32>,
+}
+
+impl LockStream {
+ fn new(lock: BiLock<u32>) -> Self {
+ Self {
+ lock: lock.lock()
+ }
}
- /// Pseudo-stream which simply calls `lock.poll()` on `poll`
- struct LockStream {
- lock: BiLockAcquire<u32>,
+ /// Release a lock after it was acquired in `poll`,
+ /// so `poll` could be called again.
+ fn release_lock(&mut self, guard: BiLockAcquired<u32>) {
+ self.lock = guard.unlock().lock()
}
+}
- impl LockStream {
- fn new(lock: BiLock<u32>) -> Self {
- Self { lock: lock.lock() }
- }
+impl Stream for LockStream {
+ type Item = BiLockAcquired<u32>;
+ type Error = ();
- /// Release a lock after it was acquired in `poll`,
- /// so `poll` could be called again.
- fn release_lock(&mut self, guard: BiLockAcquired<u32>) {
- self.lock = guard.unlock().lock()
- }
+ fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>, Self::Error> {
+ self.lock.poll(cx).map(|a| a.map(Some))
}
+}
+
+
+#[bench]
+fn contended(b: &mut Bencher) {
+ let pool = LocalPool::new();
+ let mut exec = pool.executor();
+ let waker = notify_noop();
+ let mut map = task::LocalMap::new();
+ let mut waker = task::Context::new(&mut map, &waker, &mut exec);
+
+ b.iter(|| {
+ let (x, y) = BiLock::new(1);
- impl Stream for LockStream {
- type Item = BiLockAcquired<u32>;
- type Error = ();
+ let mut x = LockStream::new(x);
+ let mut y = LockStream::new(y);
- fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>, Self::Error> {
- self.lock.poll(cx).map(|a| a.map(Some))
+ for _ in 0..1000 {
+ let x_guard = match x.poll_next(&mut waker) {
+ Ok(Poll::Ready(Some(guard))) => guard,
+ _ => panic!(),
+ };
+
+ // Try poll second lock while first lock still holds the lock
+ match y.poll_next(&mut waker) {
+ Ok(Poll::Pending) => (),
+ _ => panic!(),
+ };
+
+ x.release_lock(x_guard);
+
+ let y_guard = match y.poll_next(&mut waker) {
+ Ok(Poll::Ready(Some(guard))) => guard,
+ _ => panic!(),
+ };
+
+ y.release_lock(y_guard);
}
- }
+ (x, y)
+ });
+}
- #[bench]
- fn contended(b: &mut Bencher) {
- let pool = LocalPool::new();
- let mut exec = pool.executor();
- let waker = notify_noop();
- let mut map = task::LocalMap::new();
- let mut waker = task::Context::new(&mut map, &waker, &mut exec);
-
- b.iter(|| {
- let (x, y) = BiLock::new(1);
-
- let mut x = LockStream::new(x);
- let mut y = LockStream::new(y);
-
- for _ in 0..1000 {
- let x_guard = match x.poll_next(&mut waker) {
- Ok(Poll::Ready(Some(guard))) => guard,
- _ => panic!(),
- };
-
- // Try poll second lock while first lock still holds the lock
- match y.poll_next(&mut waker) {
- Ok(Poll::Pending) => (),
- _ => panic!(),
- };
-
- x.release_lock(x_guard);
-
- let y_guard = match y.poll_next(&mut waker) {
- Ok(Poll::Ready(Some(guard))) => guard,
- _ => panic!(),
- };
-
- y.release_lock(y_guard);
- }
- (x, y)
- });
- }
+#[bench]
+fn lock_unlock(b: &mut Bencher) {
+ let pool = LocalPool::new();
+ let mut exec = pool.executor();
+ let waker = notify_noop();
+ let mut map = task::LocalMap::new();
+ let mut waker = task::Context::new(&mut map, &waker, &mut exec);
- #[bench]
- fn lock_unlock(b: &mut Bencher) {
- let pool = LocalPool::new();
- let mut exec = pool.executor();
- let waker = notify_noop();
- let mut map = task::LocalMap::new();
- let mut waker = task::Context::new(&mut map, &waker, &mut exec);
-
- b.iter(|| {
- let (x, y) = BiLock::new(1);
-
- let mut x = LockStream::new(x);
- let mut y = LockStream::new(y);
-
- for _ in 0..1000 {
- let x_guard = match x.poll_next(&mut waker) {
- Ok(Poll::Ready(Some(guard))) => guard,
- _ => panic!(),
- };
-
- x.release_lock(x_guard);
-
- let y_guard = match y.poll_next(&mut waker) {
- Ok(Poll::Ready(Some(guard))) => guard,
- _ => panic!(),
- };
-
- y.release_lock(y_guard);
- }
- (x, y)
- })
- }
+ b.iter(|| {
+ let (x, y) = BiLock::new(1);
+
+ let mut x = LockStream::new(x);
+ let mut y = LockStream::new(y);
+
+ for _ in 0..1000 {
+ let x_guard = match x.poll_next(&mut waker) {
+ Ok(Poll::Ready(Some(guard))) => guard,
+ _ => panic!(),
+ };
+
+ x.release_lock(x_guard);
+
+ let y_guard = match y.poll_next(&mut waker) {
+ Ok(Poll::Ready(Some(guard))) => guard,
+ _ => panic!(),
+ };
+
+ y.release_lock(y_guard);
+ }
+ (x, y)
+ })
+}
}
diff --git a/build.rs b/build.rs
deleted file mode 100644
index 05e0496..0000000
--- a/build.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-// The rustc-cfg listed below are considered public API, but it is *unstable*
-// and outside of the normal semver guarantees:
-//
-// - `futures_no_atomic_cas`
-// Assume the target does *not* support atomic CAS operations.
-// This is usually detected automatically by the build script, but you may
-// need to enable it manually when building for custom targets or using
-// non-cargo build systems that don't run the build script.
-//
-// With the exceptions mentioned above, the rustc-cfg emitted by the build
-// script are *not* public API.
-
-#![warn(rust_2018_idioms, single_use_lifetimes)]
-
-use std::env;
-
-include!("no_atomic_cas.rs");
-
-fn main() {
- let target = match env::var("TARGET") {
- Ok(target) => target,
- Err(e) => {
- println!(
- "cargo:warning={}: unable to get TARGET environment variable: {}",
- env!("CARGO_PKG_NAME"),
- e
- );
- return;
- }
- };
-
- // Note that this is `no_*`, not `has_*`. This allows treating
- // `cfg(target_has_atomic = "ptr")` as true when the build script doesn't
- // run. This is needed for compatibility with non-cargo build systems that
- // don't run the build script.
- if NO_ATOMIC_CAS.contains(&&*target) {
- println!("cargo:rustc-cfg=futures_no_atomic_cas");
- }
-
- println!("cargo:rerun-if-changed=no_atomic_cas.rs");
-}
diff --git a/cargo2android.json b/cargo2android.json
index 4e11868..8bef0a5 100644
--- a/cargo2android.json
+++ b/cargo2android.json
@@ -1,14 +1,13 @@
{
"apex-available": [
"//apex_available:platform",
- "com.android.bluetooth",
"com.android.resolv",
"com.android.virt"
],
+ "min_sdk_version": "29",
"dependencies": true,
"device": true,
"features": "channel,default,io,memchr,sink",
- "min-sdk-version": "29",
"run": true,
"tests": true
-}
+} \ No newline at end of file
diff --git a/no_atomic_cas.rs b/no_atomic_cas.rs
deleted file mode 100644
index 9b05d4b..0000000
--- a/no_atomic_cas.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-// This file is @generated by no_atomic_cas.sh.
-// It is not intended for manual editing.
-
-const NO_ATOMIC_CAS: &[&str] = &[
- "avr-unknown-gnu-atmega328",
- "bpfeb-unknown-none",
- "bpfel-unknown-none",
- "msp430-none-elf",
- "riscv32i-unknown-none-elf",
- "riscv32imc-unknown-none-elf",
- "thumbv4t-none-eabi",
- "thumbv6m-none-eabi",
-];
diff --git a/src/abortable.rs b/src/abortable.rs
deleted file mode 100644
index bb82dd0..0000000
--- a/src/abortable.rs
+++ /dev/null
@@ -1,185 +0,0 @@
-use crate::task::AtomicWaker;
-use alloc::sync::Arc;
-use core::fmt;
-use core::pin::Pin;
-use core::sync::atomic::{AtomicBool, Ordering};
-use futures_core::future::Future;
-use futures_core::task::{Context, Poll};
-use futures_core::Stream;
-use pin_project_lite::pin_project;
-
-pin_project! {
- /// A future/stream which can be remotely short-circuited using an `AbortHandle`.
- #[derive(Debug, Clone)]
- #[must_use = "futures/streams do nothing unless you poll them"]
- pub struct Abortable<T> {
- #[pin]
- task: T,
- inner: Arc<AbortInner>,
- }
-}
-
-impl<T> Abortable<T> {
- /// Creates a new `Abortable` future/stream using an existing `AbortRegistration`.
- /// `AbortRegistration`s can be acquired through `AbortHandle::new`.
- ///
- /// When `abort` is called on the handle tied to `reg` or if `abort` has
- /// already been called, the future/stream will complete immediately without making
- /// any further progress.
- ///
- /// # Examples:
- ///
- /// Usage with futures:
- ///
- /// ```
- /// # futures::executor::block_on(async {
- /// use futures::future::{Abortable, AbortHandle, Aborted};
- ///
- /// let (abort_handle, abort_registration) = AbortHandle::new_pair();
- /// let future = Abortable::new(async { 2 }, abort_registration);
- /// abort_handle.abort();
- /// assert_eq!(future.await, Err(Aborted));
- /// # });
- /// ```
- ///
- /// Usage with streams:
- ///
- /// ```
- /// # futures::executor::block_on(async {
- /// # use futures::future::{Abortable, AbortHandle};
- /// # use futures::stream::{self, StreamExt};
- ///
- /// let (abort_handle, abort_registration) = AbortHandle::new_pair();
- /// let mut stream = Abortable::new(stream::iter(vec![1, 2, 3]), abort_registration);
- /// abort_handle.abort();
- /// assert_eq!(stream.next().await, None);
- /// # });
- /// ```
- pub fn new(task: T, reg: AbortRegistration) -> Self {
- Self { task, inner: reg.inner }
- }
-
- /// Checks whether the task has been aborted. Note that all this
- /// method indicates is whether [`AbortHandle::abort`] was *called*.
- /// This means that it will return `true` even if:
- /// * `abort` was called after the task had completed.
- /// * `abort` was called while the task was being polled - the task may still be running and
- /// will not be stopped until `poll` returns.
- pub fn is_aborted(&self) -> bool {
- self.inner.aborted.load(Ordering::Relaxed)
- }
-}
-
-/// A registration handle for an `Abortable` task.
-/// Values of this type can be acquired from `AbortHandle::new` and are used
-/// in calls to `Abortable::new`.
-#[derive(Debug)]
-pub struct AbortRegistration {
- inner: Arc<AbortInner>,
-}
-
-/// A handle to an `Abortable` task.
-#[derive(Debug, Clone)]
-pub struct AbortHandle {
- inner: Arc<AbortInner>,
-}
-
-impl AbortHandle {
- /// Creates an (`AbortHandle`, `AbortRegistration`) pair which can be used
- /// to abort a running future or stream.
- ///
- /// This function is usually paired with a call to [`Abortable::new`].
- pub fn new_pair() -> (Self, AbortRegistration) {
- let inner =
- Arc::new(AbortInner { waker: AtomicWaker::new(), aborted: AtomicBool::new(false) });
-
- (Self { inner: inner.clone() }, AbortRegistration { inner })
- }
-}
-
-// Inner type storing the waker to awaken and a bool indicating that it
-// should be aborted.
-#[derive(Debug)]
-struct AbortInner {
- waker: AtomicWaker,
- aborted: AtomicBool,
-}
-
-/// Indicator that the `Abortable` task was aborted.
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub struct Aborted;
-
-impl fmt::Display for Aborted {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "`Abortable` future has been aborted")
- }
-}
-
-#[cfg(feature = "std")]
-impl std::error::Error for Aborted {}
-
-impl<T> Abortable<T> {
- fn try_poll<I>(
- mut self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- poll: impl Fn(Pin<&mut T>, &mut Context<'_>) -> Poll<I>,
- ) -> Poll<Result<I, Aborted>> {
- // Check if the task has been aborted
- if self.is_aborted() {
- return Poll::Ready(Err(Aborted));
- }
-
- // attempt to complete the task
- if let Poll::Ready(x) = poll(self.as_mut().project().task, cx) {
- return Poll::Ready(Ok(x));
- }
-
- // Register to receive a wakeup if the task is aborted in the future
- self.inner.waker.register(cx.waker());
-
- // Check to see if the task was aborted between the first check and
- // registration.
- // Checking with `is_aborted` which uses `Relaxed` is sufficient because
- // `register` introduces an `AcqRel` barrier.
- if self.is_aborted() {
- return Poll::Ready(Err(Aborted));
- }
-
- Poll::Pending
- }
-}
-
-impl<Fut> Future for Abortable<Fut>
-where
- Fut: Future,
-{
- type Output = Result<Fut::Output, Aborted>;
-
- fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- self.try_poll(cx, |fut, cx| fut.poll(cx))
- }
-}
-
-impl<St> Stream for Abortable<St>
-where
- St: Stream,
-{
- type Item = St::Item;
-
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
- self.try_poll(cx, |stream, cx| stream.poll_next(cx)).map(Result::ok).map(Option::flatten)
- }
-}
-
-impl AbortHandle {
- /// Abort the `Abortable` stream/future associated with this handle.
- ///
- /// Notifies the Abortable task associated with this handle that it
- /// should abort. Note that if the task is currently being polled on
- /// another thread, it will not immediately stop running. Instead, it will
- /// continue to run until its poll method returns.
- pub fn abort(&self) {
- self.inner.aborted.store(true, Ordering::Relaxed);
- self.inner.waker.wake();
- }
-}
diff --git a/src/async_await/join_mod.rs b/src/async_await/join_mod.rs
index 28f3b23..965d9fb 100644
--- a/src/async_await/join_mod.rs
+++ b/src/async_await/join_mod.rs
@@ -1,5 +1,7 @@
//! The `join` macro.
+use proc_macro_hack::proc_macro_hack;
+
macro_rules! document_join_macro {
($join:item $try_join:item) => {
/// Polls multiple futures simultaneously, returning a tuple
@@ -79,12 +81,12 @@ macro_rules! document_join_macro {
}
}
-#[allow(unreachable_pub)]
#[doc(hidden)]
+#[proc_macro_hack(support_nested, only_hack_old_rustc)]
pub use futures_macro::join_internal;
-#[allow(unreachable_pub)]
#[doc(hidden)]
+#[proc_macro_hack(support_nested, only_hack_old_rustc)]
pub use futures_macro::try_join_internal;
document_join_macro! {
diff --git a/src/async_await/mod.rs b/src/async_await/mod.rs
index 7276da2..bdaed95 100644
--- a/src/async_await/mod.rs
+++ b/src/async_await/mod.rs
@@ -3,8 +3,8 @@
//! This module contains a number of functions and combinators for working
//! with `async`/`await` code.
-use futures_core::future::{FusedFuture, Future};
-use futures_core::stream::{FusedStream, Stream};
+use futures_core::future::{Future, FusedFuture};
+use futures_core::stream::{Stream, FusedStream};
#[macro_use]
mod poll;
@@ -30,13 +30,6 @@ mod select_mod;
#[cfg(feature = "async-await-macro")]
pub use self::select_mod::*;
-// Primary export is a macro
-#[cfg(feature = "async-await-macro")]
-mod stream_select_mod;
-#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762
-#[cfg(feature = "async-await-macro")]
-pub use self::stream_select_mod::*;
-
#[cfg(feature = "std")]
#[cfg(feature = "async-await-macro")]
mod random;
diff --git a/src/async_await/pending.rs b/src/async_await/pending.rs
index 5d7a431..e0cf341 100644
--- a/src/async_await/pending.rs
+++ b/src/async_await/pending.rs
@@ -16,7 +16,7 @@ use futures_core::task::{Context, Poll};
macro_rules! pending {
() => {
$crate::__private::async_await::pending_once().await
- };
+ }
}
#[doc(hidden)]
diff --git a/src/async_await/poll.rs b/src/async_await/poll.rs
index b62f45a..b5782df 100644
--- a/src/async_await/poll.rs
+++ b/src/async_await/poll.rs
@@ -17,7 +17,7 @@ use futures_core::task::{Context, Poll};
macro_rules! poll {
($x:expr $(,)?) => {
$crate::__private::async_await::poll($x).await
- };
+ }
}
#[doc(hidden)]
diff --git a/src/async_await/select_mod.rs b/src/async_await/select_mod.rs
index 1d13067..59bca08 100644
--- a/src/async_await/select_mod.rs
+++ b/src/async_await/select_mod.rs
@@ -1,5 +1,7 @@
//! The `select` macro.
+use proc_macro_hack::proc_macro_hack;
+
macro_rules! document_select_macro {
// This branch is required for `futures 0.3.1`, from before select_biased was introduced
($select:item) => {
@@ -29,6 +31,9 @@ macro_rules! document_select_macro {
/// It is also gated behind the `async-await` feature of this library, which is
/// activated by default.
///
+ /// Note that `select!` relies on `proc-macro-hack`, and may require to set the
+ /// compiler's recursion limit very high, e.g. `#![recursion_limit="1024"]`.
+ ///
/// # Examples
///
/// ```
@@ -304,12 +309,12 @@ macro_rules! document_select_macro {
}
#[cfg(feature = "std")]
-#[allow(unreachable_pub)]
#[doc(hidden)]
+#[proc_macro_hack(support_nested, only_hack_old_rustc)]
pub use futures_macro::select_internal;
-#[allow(unreachable_pub)]
#[doc(hidden)]
+#[proc_macro_hack(support_nested, only_hack_old_rustc)]
pub use futures_macro::select_biased_internal;
document_select_macro! {
diff --git a/src/async_await/stream_select_mod.rs b/src/async_await/stream_select_mod.rs
deleted file mode 100644
index 1c8002f..0000000
--- a/src/async_await/stream_select_mod.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-//! The `stream_select` macro.
-
-#[cfg(feature = "std")]
-#[allow(unreachable_pub)]
-#[doc(hidden)]
-pub use futures_macro::stream_select_internal;
-
-/// Combines several streams, all producing the same `Item` type, into one stream.
-/// This is similar to `select_all` but does not require the streams to all be the same type.
-/// It also keeps the streams inline, and does not require `Box<dyn Stream>`s to be allocated.
-/// Streams passed to this macro must be `Unpin`.
-///
-/// If multiple streams are ready, one will be pseudo randomly selected at runtime.
-///
-/// # Examples
-///
-/// ```
-/// # futures::executor::block_on(async {
-/// use futures::{stream, StreamExt, stream_select};
-/// let endless_ints = |i| stream::iter(vec![i].into_iter().cycle()).fuse();
-///
-/// let mut endless_numbers = stream_select!(endless_ints(1i32), endless_ints(2), endless_ints(3));
-/// match endless_numbers.next().await {
-/// Some(1) => println!("Got a 1"),
-/// Some(2) => println!("Got a 2"),
-/// Some(3) => println!("Got a 3"),
-/// _ => unreachable!(),
-/// }
-/// # });
-/// ```
-#[cfg(feature = "std")]
-#[macro_export]
-macro_rules! stream_select {
- ($($tokens:tt)*) => {{
- use $crate::__private as __futures_crate;
- $crate::stream_select_internal! {
- $( $tokens )*
- }
- }}
-}
diff --git a/src/compat/compat01as03.rs b/src/compat/compat01as03.rs
index 36de1da..bc3aee3 100644
--- a/src/compat/compat01as03.rs
+++ b/src/compat/compat01as03.rs
@@ -1,15 +1,18 @@
use futures_01::executor::{
- spawn as spawn01, Notify as Notify01, NotifyHandle as NotifyHandle01, Spawn as Spawn01,
- UnsafeNotify as UnsafeNotify01,
+ spawn as spawn01, Notify as Notify01, NotifyHandle as NotifyHandle01,
+ Spawn as Spawn01, UnsafeNotify as UnsafeNotify01,
+};
+use futures_01::{
+ Async as Async01, Future as Future01,
+ Stream as Stream01,
};
-use futures_01::{Async as Async01, Future as Future01, Stream as Stream01};
#[cfg(feature = "sink")]
use futures_01::{AsyncSink as AsyncSink01, Sink as Sink01};
-use futures_core::{future::Future as Future03, stream::Stream as Stream03, task as task03};
-#[cfg(feature = "sink")]
-use futures_sink::Sink as Sink03;
+use futures_core::{task as task03, future::Future as Future03, stream::Stream as Stream03};
use std::pin::Pin;
use std::task::Context;
+#[cfg(feature = "sink")]
+use futures_sink::Sink as Sink03;
#[cfg(feature = "io-compat")]
#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
@@ -30,7 +33,9 @@ impl<T> Compat01As03<T> {
/// Wraps a futures 0.1 Future, Stream, AsyncRead, or AsyncWrite
/// object in a futures 0.3-compatible wrapper.
pub fn new(object: T) -> Self {
- Self { inner: spawn01(object) }
+ Self {
+ inner: spawn01(object),
+ }
}
fn in_notify<R>(&mut self, cx: &mut Context<'_>, f: impl FnOnce(&mut T) -> R) -> R {
@@ -64,7 +69,6 @@ pub trait Future01CompatExt: Future01 {
/// [`Future<Output = Result<T, E>>`](futures_core::future::Future).
///
/// ```
- /// # if cfg!(miri) { return; } // https://github.com/rust-lang/futures-rs/issues/2514
/// # futures::executor::block_on(async {
/// # // TODO: These should be all using `futures::compat`, but that runs up against Cargo
/// # // feature issues
@@ -91,7 +95,6 @@ pub trait Stream01CompatExt: Stream01 {
/// [`Stream<Item = Result<T, E>>`](futures_core::stream::Stream).
///
/// ```
- /// # if cfg!(miri) { return; } // https://github.com/rust-lang/futures-rs/issues/2514
/// # futures::executor::block_on(async {
/// use futures::stream::StreamExt;
/// use futures_util::compat::Stream01CompatExt;
@@ -121,7 +124,6 @@ pub trait Sink01CompatExt: Sink01 {
/// [`Sink<T, Error = E>`](futures_sink::Sink).
///
/// ```
- /// # if cfg!(miri) { return; } // https://github.com/rust-lang/futures-rs/issues/2514
/// # futures::executor::block_on(async {
/// use futures::{sink::SinkExt, stream::StreamExt};
/// use futures_util::compat::{Stream01CompatExt, Sink01CompatExt};
@@ -155,7 +157,10 @@ fn poll_01_to_03<T, E>(x: Result<Async01<T>, E>) -> task03::Poll<Result<T, E>> {
impl<Fut: Future01> Future03 for Compat01As03<Fut> {
type Output = Result<Fut::Item, Fut::Error>;
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> task03::Poll<Self::Output> {
+ fn poll(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> task03::Poll<Self::Output> {
poll_01_to_03(self.in_notify(cx, Future01::poll))
}
}
@@ -193,10 +198,18 @@ impl<S, SinkItem> Unpin for Compat01As03Sink<S, SinkItem> {}
impl<S, SinkItem> Compat01As03Sink<S, SinkItem> {
/// Wraps a futures 0.1 Sink object in a futures 0.3-compatible wrapper.
pub fn new(inner: S) -> Self {
- Self { inner: spawn01(inner), buffer: None, close_started: false }
+ Self {
+ inner: spawn01(inner),
+ buffer: None,
+ close_started: false
+ }
}
- fn in_notify<R>(&mut self, cx: &mut Context<'_>, f: impl FnOnce(&mut S) -> R) -> R {
+ fn in_notify<R>(
+ &mut self,
+ cx: &mut Context<'_>,
+ f: impl FnOnce(&mut S) -> R,
+ ) -> R {
let notify = &WakerToHandle(cx.waker());
self.inner.poll_fn_notify(notify, 0, f)
}
@@ -243,7 +256,10 @@ where
{
type Error = S::SinkError;
- fn start_send(mut self: Pin<&mut Self>, item: SinkItem) -> Result<(), Self::Error> {
+ fn start_send(
+ mut self: Pin<&mut Self>,
+ item: SinkItem,
+ ) -> Result<(), Self::Error> {
debug_assert!(self.buffer.is_none());
self.buffer = Some(item);
Ok(())
@@ -273,7 +289,9 @@ where
match self.in_notify(cx, |f| match item {
Some(i) => match f.start_send(i)? {
AsyncSink01::Ready => f.poll_complete().map(|i| (i, None)),
- AsyncSink01::NotReady(t) => Ok((Async01::NotReady, Some(t))),
+ AsyncSink01::NotReady(t) => {
+ Ok((Async01::NotReady, Some(t)))
+ }
},
None => f.poll_complete().map(|i| (i, None)),
})? {
@@ -354,6 +372,8 @@ unsafe impl UnsafeNotify01 for NotifyWaker {
#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
mod io {
use super::*;
+ #[cfg(feature = "read-initializer")]
+ use futures_io::Initializer;
use futures_io::{AsyncRead as AsyncRead03, AsyncWrite as AsyncWrite03};
use std::io::Error;
use tokio_io::{AsyncRead as AsyncRead01, AsyncWrite as AsyncWrite01};
@@ -365,7 +385,6 @@ mod io {
/// [`AsyncRead`](futures_io::AsyncRead).
///
/// ```
- /// # if cfg!(miri) { return; } // https://github.com/rust-lang/futures-rs/issues/2514
/// # futures::executor::block_on(async {
/// use futures::io::AsyncReadExt;
/// use futures_util::compat::AsyncRead01CompatExt;
@@ -395,7 +414,6 @@ mod io {
/// [`AsyncWrite`](futures_io::AsyncWrite).
///
/// ```
- /// # if cfg!(miri) { return; } // https://github.com/rust-lang/futures-rs/issues/2514
/// # futures::executor::block_on(async {
/// use futures::io::AsyncWriteExt;
/// use futures_util::compat::AsyncWrite01CompatExt;
@@ -419,35 +437,39 @@ mod io {
impl<W: AsyncWrite01> AsyncWrite01CompatExt for W {}
impl<R: AsyncRead01> AsyncRead03 for Compat01As03<R> {
- fn poll_read(
- mut self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- buf: &mut [u8],
- ) -> task03::Poll<Result<usize, Error>> {
+ #[cfg(feature = "read-initializer")]
+ unsafe fn initializer(&self) -> Initializer {
+ // check if `prepare_uninitialized_buffer` needs zeroing
+ if self.inner.get_ref().prepare_uninitialized_buffer(&mut [1]) {
+ Initializer::zeroing()
+ } else {
+ Initializer::nop()
+ }
+ }
+
+ fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8])
+ -> task03::Poll<Result<usize, Error>>
+ {
poll_01_to_03(self.in_notify(cx, |x| x.poll_read(buf)))
}
}
impl<W: AsyncWrite01> AsyncWrite03 for Compat01As03<W> {
- fn poll_write(
- mut self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- buf: &[u8],
- ) -> task03::Poll<Result<usize, Error>> {
+ fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8])
+ -> task03::Poll<Result<usize, Error>>
+ {
poll_01_to_03(self.in_notify(cx, |x| x.poll_write(buf)))
}
- fn poll_flush(
- mut self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- ) -> task03::Poll<Result<(), Error>> {
+ fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>)
+ -> task03::Poll<Result<(), Error>>
+ {
poll_01_to_03(self.in_notify(cx, AsyncWrite01::poll_flush))
}
- fn poll_close(
- mut self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- ) -> task03::Poll<Result<(), Error>> {
+ fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>)
+ -> task03::Poll<Result<(), Error>>
+ {
poll_01_to_03(self.in_notify(cx, AsyncWrite01::shutdown))
}
}
diff --git a/src/compat/compat03as01.rs b/src/compat/compat03as01.rs
index 5d3a6e9..3f1eebb 100644
--- a/src/compat/compat03as01.rs
+++ b/src/compat/compat03as01.rs
@@ -1,19 +1,31 @@
-use crate::task::{self as task03, ArcWake as ArcWake03, WakerRef};
use futures_01::{
- task as task01, Async as Async01, Future as Future01, Poll as Poll01, Stream as Stream01,
+ task as task01, Async as Async01, Future as Future01, Poll as Poll01,
+ Stream as Stream01,
};
#[cfg(feature = "sink")]
-use futures_01::{AsyncSink as AsyncSink01, Sink as Sink01, StartSend as StartSend01};
+use futures_01::{
+ AsyncSink as AsyncSink01, Sink as Sink01, StartSend as StartSend01,
+};
use futures_core::{
+ task::{RawWaker, RawWakerVTable},
future::TryFuture as TryFuture03,
stream::TryStream as TryStream03,
- task::{RawWaker, RawWakerVTable},
};
#[cfg(feature = "sink")]
use futures_sink::Sink as Sink03;
+use crate::task::{
+ self as task03,
+ ArcWake as ArcWake03,
+ WakerRef,
+};
#[cfg(feature = "sink")]
use std::marker::PhantomData;
-use std::{mem, pin::Pin, sync::Arc, task::Context};
+use std::{
+ mem,
+ pin::Pin,
+ sync::Arc,
+ task::Context,
+};
/// Converts a futures 0.3 [`TryFuture`](futures_core::future::TryFuture) or
/// [`TryStream`](futures_core::stream::TryStream) into a futures 0.1
@@ -68,7 +80,10 @@ impl<T> Compat<T> {
impl<T, Item> CompatSink<T, Item> {
/// Creates a new [`CompatSink`].
pub fn new(inner: T) -> Self {
- Self { inner, _phantom: PhantomData }
+ Self {
+ inner,
+ _phantom: PhantomData,
+ }
}
/// Get a reference to 0.3 Sink contained within.
@@ -87,7 +102,9 @@ impl<T, Item> CompatSink<T, Item> {
}
}
-fn poll_03_to_01<T, E>(x: task03::Poll<Result<T, E>>) -> Result<Async01<T>, E> {
+fn poll_03_to_01<T, E>(x: task03::Poll<Result<T, E>>)
+ -> Result<Async01<T>, E>
+{
match x? {
task03::Poll::Ready(t) => Ok(Async01::Ready(t)),
task03::Poll::Pending => Ok(Async01::NotReady),
@@ -130,10 +147,17 @@ where
type SinkItem = Item;
type SinkError = T::Error;
- fn start_send(&mut self, item: Self::SinkItem) -> StartSend01<Self::SinkItem, Self::SinkError> {
- with_sink_context(self, |mut inner, cx| match inner.as_mut().poll_ready(cx)? {
- task03::Poll::Ready(()) => inner.start_send(item).map(|()| AsyncSink01::Ready),
- task03::Poll::Pending => Ok(AsyncSink01::NotReady(item)),
+ fn start_send(
+ &mut self,
+ item: Self::SinkItem,
+ ) -> StartSend01<Self::SinkItem, Self::SinkError> {
+ with_sink_context(self, |mut inner, cx| {
+ match inner.as_mut().poll_ready(cx)? {
+ task03::Poll::Ready(()) => {
+ inner.start_send(item).map(|()| AsyncSink01::Ready)
+ }
+ task03::Poll::Pending => Ok(AsyncSink01::NotReady(item)),
+ }
})
}
@@ -166,9 +190,9 @@ impl Current {
// Lazily create the `Arc` only when the waker is actually cloned.
// FIXME: remove `transmute` when a `Waker` -> `RawWaker` conversion
// function is landed in `core`.
- mem::transmute::<task03::Waker, RawWaker>(task03::waker(Arc::new(
- ptr_to_current(ptr).clone(),
- )))
+ mem::transmute::<task03::Waker, RawWaker>(
+ task03::waker(Arc::new(ptr_to_current(ptr).clone()))
+ )
}
unsafe fn drop(_: *const ()) {}
unsafe fn wake(ptr: *const ()) {
@@ -219,7 +243,9 @@ mod io {
use futures_io::{AsyncRead as AsyncRead03, AsyncWrite as AsyncWrite03};
use tokio_io::{AsyncRead as AsyncRead01, AsyncWrite as AsyncWrite01};
- fn poll_03_to_io<T>(x: task03::Poll<Result<T, std::io::Error>>) -> Result<T, std::io::Error> {
+ fn poll_03_to_io<T>(x: task03::Poll<Result<T, std::io::Error>>)
+ -> Result<T, std::io::Error>
+ {
match x {
task03::Poll::Ready(Ok(t)) => Ok(t),
task03::Poll::Pending => Err(std::io::ErrorKind::WouldBlock.into()),
@@ -236,7 +262,17 @@ mod io {
}
}
- impl<R: AsyncRead03 + Unpin> AsyncRead01 for Compat<R> {}
+ impl<R: AsyncRead03 + Unpin> AsyncRead01 for Compat<R> {
+ #[cfg(feature = "read-initializer")]
+ unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
+ let initializer = self.inner.initializer();
+ let does_init = initializer.should_initialize();
+ if does_init {
+ initializer.initialize(buf);
+ }
+ does_init
+ }
+ }
impl<W: AsyncWrite03 + Unpin> std::io::Write for Compat<W> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
diff --git a/src/compat/executor.rs b/src/compat/executor.rs
index ea0c67a..82cb496 100644
--- a/src/compat/executor.rs
+++ b/src/compat/executor.rs
@@ -17,7 +17,6 @@ pub trait Executor01CompatExt: Executor01<Executor01Future> + Clone + Send + 'st
/// futures 0.3 [`Spawn`](futures_task::Spawn).
///
/// ```
- /// # if cfg!(miri) { return; } // Miri does not support epoll
/// use futures::task::SpawnExt;
/// use futures::future::{FutureExt, TryFutureExt};
/// use futures_util::compat::Executor01CompatExt;
@@ -67,7 +66,9 @@ where
fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError03> {
let future = future.unit_error().compat();
- self.executor01.execute(future).map_err(|_| SpawnError03::shutdown())
+ self.executor01
+ .execute(future)
+ .map_err(|_| SpawnError03::shutdown())
}
}
diff --git a/src/compat/mod.rs b/src/compat/mod.rs
index 4812803..c5edcc5 100644
--- a/src/compat/mod.rs
+++ b/src/compat/mod.rs
@@ -4,16 +4,16 @@
//! library is activated.
mod executor;
-pub use self::executor::{Executor01As03, Executor01CompatExt, Executor01Future};
+pub use self::executor::{Executor01CompatExt, Executor01Future, Executor01As03};
mod compat01as03;
-#[cfg(feature = "io-compat")]
-#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
-pub use self::compat01as03::{AsyncRead01CompatExt, AsyncWrite01CompatExt};
pub use self::compat01as03::{Compat01As03, Future01CompatExt, Stream01CompatExt};
#[cfg(feature = "sink")]
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
pub use self::compat01as03::{Compat01As03Sink, Sink01CompatExt};
+#[cfg(feature = "io-compat")]
+#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
+pub use self::compat01as03::{AsyncRead01CompatExt, AsyncWrite01CompatExt};
mod compat03as01;
pub use self::compat03as01::Compat;
diff --git a/src/fns.rs b/src/fns.rs
index 37ee03e..cb62391 100644
--- a/src/fns.rs
+++ b/src/fns.rs
@@ -1,5 +1,5 @@
-use core::fmt::{self, Debug};
use core::marker::PhantomData;
+use core::fmt::{self, Debug};
pub trait FnOnce1<A> {
type Output;
@@ -8,7 +8,7 @@ pub trait FnOnce1<A> {
impl<T, A, R> FnOnce1<A> for T
where
- T: FnOnce(A) -> R,
+ T: FnOnce(A) -> R
{
type Output = R;
fn call_once(self, arg: A) -> R {
@@ -22,7 +22,7 @@ pub trait FnMut1<A>: FnOnce1<A> {
impl<T, A, R> FnMut1<A> for T
where
- T: FnMut(A) -> R,
+ T: FnMut(A) -> R
{
fn call_mut(&mut self, arg: A) -> R {
self(arg)
@@ -37,7 +37,7 @@ pub trait Fn1<A>: FnMut1<A> {
impl<T, A, R> Fn1<A> for T
where
- T: Fn(A) -> R,
+ T: Fn(A) -> R
{
fn call(&self, arg: A) -> R {
self(arg)
@@ -143,7 +143,7 @@ pub struct InspectFn<F>(F);
#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
impl<F, A> FnOnce1<A> for InspectFn<F>
where
- F: for<'a> FnOnce1<&'a A, Output = ()>,
+ F: for<'a> FnOnce1<&'a A, Output=()>,
{
type Output = A;
fn call_once(self, arg: A) -> Self::Output {
@@ -154,7 +154,7 @@ where
#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
impl<F, A> FnMut1<A> for InspectFn<F>
where
- F: for<'a> FnMut1<&'a A, Output = ()>,
+ F: for<'a> FnMut1<&'a A, Output=()>,
{
fn call_mut(&mut self, arg: A) -> Self::Output {
self.0.call_mut(&arg);
@@ -164,7 +164,7 @@ where
#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
impl<F, A> Fn1<A> for InspectFn<F>
where
- F: for<'a> Fn1<&'a A, Output = ()>,
+ F: for<'a> Fn1<&'a A, Output=()>,
{
fn call(&self, arg: A) -> Self::Output {
self.0.call(&arg);
@@ -244,33 +244,27 @@ pub struct InspectOkFn<F>(F);
impl<'a, F, T, E> FnOnce1<&'a Result<T, E>> for InspectOkFn<F>
where
- F: FnOnce1<&'a T, Output = ()>,
+ F: FnOnce1<&'a T, Output=()>
{
type Output = ();
fn call_once(self, arg: &'a Result<T, E>) -> Self::Output {
- if let Ok(x) = arg {
- self.0.call_once(x)
- }
+ if let Ok(x) = arg { self.0.call_once(x) }
}
}
impl<'a, F, T, E> FnMut1<&'a Result<T, E>> for InspectOkFn<F>
where
- F: FnMut1<&'a T, Output = ()>,
+ F: FnMut1<&'a T, Output=()>,
{
fn call_mut(&mut self, arg: &'a Result<T, E>) -> Self::Output {
- if let Ok(x) = arg {
- self.0.call_mut(x)
- }
+ if let Ok(x) = arg { self.0.call_mut(x) }
}
}
impl<'a, F, T, E> Fn1<&'a Result<T, E>> for InspectOkFn<F>
where
- F: Fn1<&'a T, Output = ()>,
+ F: Fn1<&'a T, Output=()>,
{
fn call(&self, arg: &'a Result<T, E>) -> Self::Output {
- if let Ok(x) = arg {
- self.0.call(x)
- }
+ if let Ok(x) = arg { self.0.call(x) }
}
}
pub(crate) fn inspect_ok_fn<F>(f: F) -> InspectOkFn<F> {
@@ -282,33 +276,27 @@ pub struct InspectErrFn<F>(F);
impl<'a, F, T, E> FnOnce1<&'a Result<T, E>> for InspectErrFn<F>
where
- F: FnOnce1<&'a E, Output = ()>,
+ F: FnOnce1<&'a E, Output=()>
{
type Output = ();
fn call_once(self, arg: &'a Result<T, E>) -> Self::Output {
- if let Err(x) = arg {
- self.0.call_once(x)
- }
+ if let Err(x) = arg { self.0.call_once(x) }
}
}
impl<'a, F, T, E> FnMut1<&'a Result<T, E>> for InspectErrFn<F>
where
- F: FnMut1<&'a E, Output = ()>,
+ F: FnMut1<&'a E, Output=()>,
{
fn call_mut(&mut self, arg: &'a Result<T, E>) -> Self::Output {
- if let Err(x) = arg {
- self.0.call_mut(x)
- }
+ if let Err(x) = arg { self.0.call_mut(x) }
}
}
impl<'a, F, T, E> Fn1<&'a Result<T, E>> for InspectErrFn<F>
where
- F: Fn1<&'a E, Output = ()>,
+ F: Fn1<&'a E, Output=()>,
{
fn call(&self, arg: &'a Result<T, E>) -> Self::Output {
- if let Err(x) = arg {
- self.0.call(x)
- }
+ if let Err(x) = arg { self.0.call(x) }
}
}
pub(crate) fn inspect_err_fn<F>(f: F) -> InspectErrFn<F> {
@@ -325,7 +313,7 @@ pub struct UnwrapOrElseFn<F>(F);
impl<F, T, E> FnOnce1<Result<T, E>> for UnwrapOrElseFn<F>
where
- F: FnOnce1<E, Output = T>,
+ F: FnOnce1<E, Output=T>,
{
type Output = T;
fn call_once(self, arg: Result<T, E>) -> Self::Output {
@@ -334,7 +322,7 @@ where
}
impl<F, T, E> FnMut1<Result<T, E>> for UnwrapOrElseFn<F>
where
- F: FnMut1<E, Output = T>,
+ F: FnMut1<E, Output=T>,
{
fn call_mut(&mut self, arg: Result<T, E>) -> Self::Output {
arg.unwrap_or_else(|x| self.0.call_mut(x))
@@ -342,7 +330,7 @@ where
}
impl<F, T, E> Fn1<Result<T, E>> for UnwrapOrElseFn<F>
where
- F: Fn1<E, Output = T>,
+ F: Fn1<E, Output=T>,
{
fn call(&self, arg: Result<T, E>) -> Self::Output {
arg.unwrap_or_else(|x| self.0.call(x))
@@ -359,10 +347,7 @@ impl<T> Default for IntoFn<T> {
Self(PhantomData)
}
}
-impl<A, T> FnOnce1<A> for IntoFn<T>
-where
- A: Into<T>,
-{
+impl<A, T> FnOnce1<A> for IntoFn<T> where A: Into<T> {
type Output = T;
fn call_once(self, arg: A) -> Self::Output {
arg.into()
diff --git a/src/future/abortable.rs b/src/future/abortable.rs
index d017ab7..3f2e5a0 100644
--- a/src/future/abortable.rs
+++ b/src/future/abortable.rs
@@ -1,8 +1,110 @@
use super::assert_future;
-use crate::future::{AbortHandle, Abortable, Aborted};
+use crate::task::AtomicWaker;
use futures_core::future::Future;
+use futures_core::task::{Context, Poll};
+use core::fmt;
+use core::pin::Pin;
+use core::sync::atomic::{AtomicBool, Ordering};
+use alloc::sync::Arc;
+use pin_project_lite::pin_project;
-/// Creates a new `Abortable` future and an `AbortHandle` which can be used to stop it.
+pin_project! {
+ /// A future which can be remotely short-circuited using an `AbortHandle`.
+ #[derive(Debug, Clone)]
+ #[must_use = "futures do nothing unless you `.await` or poll them"]
+ pub struct Abortable<Fut> {
+ #[pin]
+ future: Fut,
+ inner: Arc<AbortInner>,
+ }
+}
+
+impl<Fut> Abortable<Fut> where Fut: Future {
+ /// Creates a new `Abortable` future using an existing `AbortRegistration`.
+ /// `AbortRegistration`s can be acquired through `AbortHandle::new`.
+ ///
+ /// When `abort` is called on the handle tied to `reg` or if `abort` has
+ /// already been called, the future will complete immediately without making
+ /// any further progress.
+ ///
+ /// Example:
+ ///
+ /// ```
+ /// # futures::executor::block_on(async {
+ /// use futures::future::{Abortable, AbortHandle, Aborted};
+ ///
+ /// let (abort_handle, abort_registration) = AbortHandle::new_pair();
+ /// let future = Abortable::new(async { 2 }, abort_registration);
+ /// abort_handle.abort();
+ /// assert_eq!(future.await, Err(Aborted));
+ /// # });
+ /// ```
+ pub fn new(future: Fut, reg: AbortRegistration) -> Self {
+ assert_future::<Result<Fut::Output, Aborted>, _>(Self {
+ future,
+ inner: reg.inner,
+ })
+ }
+}
+
+/// A registration handle for a `Abortable` future.
+/// Values of this type can be acquired from `AbortHandle::new` and are used
+/// in calls to `Abortable::new`.
+#[derive(Debug)]
+pub struct AbortRegistration {
+ inner: Arc<AbortInner>,
+}
+
+/// A handle to a `Abortable` future.
+#[derive(Debug, Clone)]
+pub struct AbortHandle {
+ inner: Arc<AbortInner>,
+}
+
+impl AbortHandle {
+ /// Creates an (`AbortHandle`, `AbortRegistration`) pair which can be used
+ /// to abort a running future.
+ ///
+ /// This function is usually paired with a call to `Abortable::new`.
+ ///
+ /// Example:
+ ///
+ /// ```
+ /// # futures::executor::block_on(async {
+ /// use futures::future::{Abortable, AbortHandle, Aborted};
+ ///
+ /// let (abort_handle, abort_registration) = AbortHandle::new_pair();
+ /// let future = Abortable::new(async { 2 }, abort_registration);
+ /// abort_handle.abort();
+ /// assert_eq!(future.await, Err(Aborted));
+ /// # });
+ /// ```
+ pub fn new_pair() -> (Self, AbortRegistration) {
+ let inner = Arc::new(AbortInner {
+ waker: AtomicWaker::new(),
+ cancel: AtomicBool::new(false),
+ });
+
+ (
+ Self {
+ inner: inner.clone(),
+ },
+ AbortRegistration {
+ inner,
+ },
+ )
+ }
+}
+
+// Inner type storing the waker to awaken and a bool indicating that it
+// should be cancelled.
+#[derive(Debug)]
+struct AbortInner {
+ waker: AtomicWaker,
+ cancel: AtomicBool,
+}
+
+/// Creates a new `Abortable` future and a `AbortHandle` which can be used to stop it.
///
/// This function is a convenient (but less flexible) alternative to calling
/// `AbortHandle::new` and `Abortable::new` manually.
@@ -10,10 +112,66 @@ use futures_core::future::Future;
/// This function is only available when the `std` or `alloc` feature of this
/// library is activated, and it is activated by default.
pub fn abortable<Fut>(future: Fut) -> (Abortable<Fut>, AbortHandle)
-where
- Fut: Future,
+ where Fut: Future
{
let (handle, reg) = AbortHandle::new_pair();
- let abortable = assert_future::<Result<Fut::Output, Aborted>, _>(Abortable::new(future, reg));
- (abortable, handle)
+ (
+ Abortable::new(future, reg),
+ handle,
+ )
+}
+
+/// Indicator that the `Abortable` future was aborted.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub struct Aborted;
+
+impl fmt::Display for Aborted {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "`Abortable` future has been aborted")
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for Aborted {}
+
+impl<Fut> Future for Abortable<Fut> where Fut: Future {
+ type Output = Result<Fut::Output, Aborted>;
+
+ fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ // Check if the future has been aborted
+ if self.inner.cancel.load(Ordering::Relaxed) {
+ return Poll::Ready(Err(Aborted))
+ }
+
+ // attempt to complete the future
+ if let Poll::Ready(x) = self.as_mut().project().future.poll(cx) {
+ return Poll::Ready(Ok(x))
+ }
+
+ // Register to receive a wakeup if the future is aborted in the... future
+ self.inner.waker.register(cx.waker());
+
+ // Check to see if the future was aborted between the first check and
+ // registration.
+ // Checking with `Relaxed` is sufficient because `register` introduces an
+ // `AcqRel` barrier.
+ if self.inner.cancel.load(Ordering::Relaxed) {
+ return Poll::Ready(Err(Aborted))
+ }
+
+ Poll::Pending
+ }
+}
+
+impl AbortHandle {
+ /// Abort the `Abortable` future associated with this handle.
+ ///
+ /// Notifies the Abortable future associated with this handle that it
+ /// should abort. Note that if the future is currently being polled on
+ /// another thread, it will not immediately stop running. Instead, it will
+ /// continue to run until its poll method returns.
+ pub fn abort(&self) {
+ self.inner.cancel.store(true, Ordering::Relaxed);
+ self.inner.waker.wake();
+ }
}
diff --git a/src/future/either.rs b/src/future/either.rs
index 9602de7..5f5b614 100644
--- a/src/future/either.rs
+++ b/src/future/either.rs
@@ -5,25 +5,8 @@ use futures_core::stream::{FusedStream, Stream};
#[cfg(feature = "sink")]
use futures_sink::Sink;
-/// Combines two different futures, streams, or sinks having the same associated types into a single type.
-///
-/// This is useful when conditionally choosing between two distinct future types:
-///
-/// ```rust
-/// use futures::future::Either;
-///
-/// # futures::executor::block_on(async {
-/// let cond = true;
-///
-/// let fut = if cond {
-/// Either::Left(async move { 12 })
-/// } else {
-/// Either::Right(async move { 44 })
-/// };
-///
-/// assert_eq!(fut.await, 12);
-/// # })
-/// ```
+/// Combines two different futures, streams, or sinks having the same associated types into a single
+/// type.
#[derive(Debug, Clone)]
pub enum Either<A, B> {
/// First branch of the type
@@ -184,6 +167,8 @@ mod if_std {
use core::pin::Pin;
use core::task::{Context, Poll};
+ #[cfg(feature = "read-initializer")]
+ use futures_io::Initializer;
use futures_io::{
AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, Result, SeekFrom,
};
@@ -193,6 +178,14 @@ mod if_std {
A: AsyncRead,
B: AsyncRead,
{
+ #[cfg(feature = "read-initializer")]
+ unsafe fn initializer(&self) -> Initializer {
+ match self {
+ Either::Left(x) => x.initializer(),
+ Either::Right(x) => x.initializer(),
+ }
+ }
+
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
diff --git a/src/future/future/catch_unwind.rs b/src/future/future/catch_unwind.rs
index 0e09d6e..3f16577 100644
--- a/src/future/future/catch_unwind.rs
+++ b/src/future/future/catch_unwind.rs
@@ -1,6 +1,6 @@
use core::any::Any;
use core::pin::Pin;
-use std::panic::{catch_unwind, AssertUnwindSafe, UnwindSafe};
+use std::panic::{catch_unwind, UnwindSafe, AssertUnwindSafe};
use futures_core::future::Future;
use futures_core::task::{Context, Poll};
@@ -16,18 +16,14 @@ pin_project! {
}
}
-impl<Fut> CatchUnwind<Fut>
-where
- Fut: Future + UnwindSafe,
-{
+impl<Fut> CatchUnwind<Fut> where Fut: Future + UnwindSafe {
pub(super) fn new(future: Fut) -> Self {
Self { future }
}
}
impl<Fut> Future for CatchUnwind<Fut>
-where
- Fut: Future + UnwindSafe,
+ where Fut: Future + UnwindSafe,
{
type Output = Result<Fut::Output, Box<dyn Any + Send>>;
diff --git a/src/future/future/flatten.rs b/src/future/future/flatten.rs
index bd767af..0c48a4f 100644
--- a/src/future/future/flatten.rs
+++ b/src/future/future/flatten.rs
@@ -2,9 +2,9 @@ use core::pin::Pin;
use futures_core::future::{FusedFuture, Future};
use futures_core::ready;
use futures_core::stream::{FusedStream, Stream};
-use futures_core::task::{Context, Poll};
#[cfg(feature = "sink")]
use futures_sink::Sink;
+use futures_core::task::{Context, Poll};
use pin_project_lite::pin_project;
pin_project! {
@@ -24,9 +24,8 @@ impl<Fut1, Fut2> Flatten<Fut1, Fut2> {
}
impl<Fut> FusedFuture for Flatten<Fut, Fut::Output>
-where
- Fut: Future,
- Fut::Output: Future,
+ where Fut: Future,
+ Fut::Output: Future,
{
fn is_terminated(&self) -> bool {
match self {
@@ -37,9 +36,8 @@ where
}
impl<Fut> Future for Flatten<Fut, Fut::Output>
-where
- Fut: Future,
- Fut::Output: Future,
+ where Fut: Future,
+ Fut::Output: Future,
{
type Output = <Fut::Output as Future>::Output;
@@ -49,12 +47,12 @@ where
FlattenProj::First { f } => {
let f = ready!(f.poll(cx));
self.set(Self::Second { f });
- }
+ },
FlattenProj::Second { f } => {
let output = ready!(f.poll(cx));
self.set(Self::Empty);
break output;
- }
+ },
FlattenProj::Empty => panic!("Flatten polled after completion"),
}
})
@@ -62,9 +60,8 @@ where
}
impl<Fut> FusedStream for Flatten<Fut, Fut::Output>
-where
- Fut: Future,
- Fut::Output: Stream,
+ where Fut: Future,
+ Fut::Output: Stream,
{
fn is_terminated(&self) -> bool {
match self {
@@ -75,32 +72,32 @@ where
}
impl<Fut> Stream for Flatten<Fut, Fut::Output>
-where
- Fut: Future,
- Fut::Output: Stream,
+ where Fut: Future,
+ Fut::Output: Stream,
{
type Item = <Fut::Output as Stream>::Item;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
Poll::Ready(loop {
match self.as_mut().project() {
- FlattenProj::First { f } => {
+ FlattenProj::First { f } => {
let f = ready!(f.poll(cx));
self.set(Self::Second { f });
- }
+ },
FlattenProj::Second { f } => {
let output = ready!(f.poll_next(cx));
if output.is_none() {
self.set(Self::Empty);
}
break output;
- }
+ },
FlattenProj::Empty => break None,
}
})
}
}
+
#[cfg(feature = "sink")]
impl<Fut, Item> Sink<Item> for Flatten<Fut, Fut::Output>
where
@@ -109,16 +106,19 @@ where
{
type Error = <Fut::Output as Sink<Item>>::Error;
- fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_ready(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
Poll::Ready(loop {
match self.as_mut().project() {
FlattenProj::First { f } => {
let f = ready!(f.poll(cx));
self.set(Self::Second { f });
- }
+ },
FlattenProj::Second { f } => {
break ready!(f.poll_ready(cx));
- }
+ },
FlattenProj::Empty => panic!("poll_ready called after eof"),
}
})
@@ -140,7 +140,10 @@ where
}
}
- fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_close(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
let res = match self.as_mut().project() {
FlattenProj::Second { f } => f.poll_close(cx),
_ => Poll::Ready(Ok(())),
diff --git a/src/future/future/fuse.rs b/src/future/future/fuse.rs
index 597aec1..f4284ba 100644
--- a/src/future/future/fuse.rs
+++ b/src/future/future/fuse.rs
@@ -1,5 +1,5 @@
use core::pin::Pin;
-use futures_core::future::{FusedFuture, Future};
+use futures_core::future::{Future, FusedFuture};
use futures_core::ready;
use futures_core::task::{Context, Poll};
use pin_project_lite::pin_project;
@@ -86,7 +86,7 @@ impl<Fut: Future> Future for Fuse<Fut> {
let output = ready!(fut.poll(cx));
self.project().inner.set(None);
output
- }
+ },
None => return Poll::Pending,
})
}
diff --git a/src/future/future/remote_handle.rs b/src/future/future/remote_handle.rs
index 1358902..0d33ea5 100644
--- a/src/future/future/remote_handle.rs
+++ b/src/future/future/remote_handle.rs
@@ -1,23 +1,23 @@
use {
crate::future::{CatchUnwind, FutureExt},
- futures_channel::oneshot::{self, Receiver, Sender},
+ futures_channel::oneshot::{self, Sender, Receiver},
futures_core::{
future::Future,
- ready,
task::{Context, Poll},
+ ready,
},
- pin_project_lite::pin_project,
std::{
any::Any,
fmt,
panic::{self, AssertUnwindSafe},
pin::Pin,
sync::{
- atomic::{AtomicBool, Ordering},
Arc,
+ atomic::{AtomicBool, Ordering},
},
thread,
},
+ pin_project_lite::pin_project,
};
/// The handle to a remote future returned by
@@ -36,7 +36,7 @@ use {
/// must be careful with regard to unwind safety because the thread in which the future
/// is polled will keep running after the panic and the thread running the [RemoteHandle]
/// will unwind.
-#[must_use = "dropping a remote handle cancels the underlying future"]
+#[must_use = "futures do nothing unless you `.await` or poll them"]
#[derive(Debug)]
#[cfg_attr(docsrs, doc(cfg(feature = "channel")))]
pub struct RemoteHandle<T> {
@@ -85,7 +85,9 @@ pin_project! {
impl<Fut: Future + fmt::Debug> fmt::Debug for Remote<Fut> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_tuple("Remote").field(&self.future).finish()
+ f.debug_tuple("Remote")
+ .field(&self.future)
+ .finish()
}
}
diff --git a/src/future/future/shared.rs b/src/future/future/shared.rs
index 9b31932..74311a0 100644
--- a/src/future/future/shared.rs
+++ b/src/future/future/shared.rs
@@ -29,12 +29,6 @@ struct Notifier {
/// A weak reference to a [`Shared`] that can be upgraded much like an `Arc`.
pub struct WeakShared<Fut: Future>(Weak<Inner<Fut>>);
-impl<Fut: Future> Clone for WeakShared<Fut> {
- fn clone(&self) -> Self {
- Self(self.0.clone())
- }
-}
-
// The future itself is polled behind the `Arc`, so it won't be moved
// when `Shared` is moved.
impl<Fut: Future> Unpin for Shared<Fut> {}
@@ -96,7 +90,10 @@ impl<Fut: Future> Shared<Fut> {
}),
};
- Self { inner: Some(Arc::new(inner)), waker_key: NULL_WAKER_KEY }
+ Self {
+ inner: Some(Arc::new(inner)),
+ waker_key: NULL_WAKER_KEY,
+ }
}
}
@@ -226,7 +223,10 @@ where
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = &mut *self;
- let inner = this.inner.take().expect("Shared future polled again after completion");
+ let inner = this
+ .inner
+ .take()
+ .expect("Shared future polled again after completion");
// Fast path for when the wrapped future has already completed
if inner.notifier.state.load(Acquire) == COMPLETE {
@@ -286,7 +286,11 @@ where
match future.poll(&mut cx) {
Poll::Pending => {
- if inner.notifier.state.compare_exchange(POLLING, IDLE, SeqCst, SeqCst).is_ok()
+ if inner
+ .notifier
+ .state
+ .compare_exchange(POLLING, IDLE, SeqCst, SeqCst)
+ .is_ok()
{
// Success
drop(_reset);
@@ -326,7 +330,10 @@ where
Fut: Future,
{
fn clone(&self) -> Self {
- Self { inner: self.inner.clone(), waker_key: NULL_WAKER_KEY }
+ Self {
+ inner: self.inner.clone(),
+ waker_key: NULL_WAKER_KEY,
+ }
}
}
@@ -360,12 +367,16 @@ impl ArcWake for Notifier {
}
}
-impl<Fut: Future> WeakShared<Fut> {
+impl<Fut: Future> WeakShared<Fut>
+{
/// Attempts to upgrade this [`WeakShared`] into a [`Shared`].
///
/// Returns [`None`] if all clones of the [`Shared`] have been dropped or polled
/// to completion.
pub fn upgrade(&self) -> Option<Shared<Fut>> {
- Some(Shared { inner: Some(self.0.upgrade()?), waker_key: NULL_WAKER_KEY })
+ Some(Shared {
+ inner: Some(self.0.upgrade()?),
+ waker_key: NULL_WAKER_KEY,
+ })
}
}
diff --git a/src/future/join.rs b/src/future/join.rs
index 740ffbc..a818343 100644
--- a/src/future/join.rs
+++ b/src/future/join.rs
@@ -213,5 +213,14 @@ where
Fut5: Future,
{
let f = Join5::new(future1, future2, future3, future4, future5);
- assert_future::<(Fut1::Output, Fut2::Output, Fut3::Output, Fut4::Output, Fut5::Output), _>(f)
+ assert_future::<
+ (
+ Fut1::Output,
+ Fut2::Output,
+ Fut3::Output,
+ Fut4::Output,
+ Fut5::Output,
+ ),
+ _,
+ >(f)
}
diff --git a/src/future/join_all.rs b/src/future/join_all.rs
index 2e52ac1..7ccf869 100644
--- a/src/future/join_all.rs
+++ b/src/future/join_all.rs
@@ -1,50 +1,33 @@
//! Definition of the `JoinAll` combinator, waiting for all of a list of futures
//! to finish.
-use alloc::boxed::Box;
-use alloc::vec::Vec;
use core::fmt;
use core::future::Future;
use core::iter::FromIterator;
use core::mem;
use core::pin::Pin;
use core::task::{Context, Poll};
+use alloc::boxed::Box;
+use alloc::vec::Vec;
-use super::{assert_future, MaybeDone};
-
-#[cfg(not(futures_no_atomic_cas))]
-use crate::stream::{Collect, FuturesOrdered, StreamExt};
+use super::{MaybeDone, assert_future};
fn iter_pin_mut<T>(slice: Pin<&mut [T]>) -> impl Iterator<Item = Pin<&mut T>> {
// Safety: `std` _could_ make this unsound if it were to decide Pin's
// invariants aren't required to transmit through slices. Otherwise this has
// the same safety as a normal field pin projection.
- unsafe { slice.get_unchecked_mut() }.iter_mut().map(|t| unsafe { Pin::new_unchecked(t) })
+ unsafe { slice.get_unchecked_mut() }
+ .iter_mut()
+ .map(|t| unsafe { Pin::new_unchecked(t) })
}
-#[must_use = "futures do nothing unless you `.await` or poll them"]
/// Future for the [`join_all`] function.
+#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct JoinAll<F>
where
F: Future,
{
- kind: JoinAllKind<F>,
-}
-
-#[cfg(not(futures_no_atomic_cas))]
-const SMALL: usize = 30;
-
-pub(crate) enum JoinAllKind<F>
-where
- F: Future,
-{
- Small {
- elems: Pin<Box<[MaybeDone<F>]>>,
- },
- #[cfg(not(futures_no_atomic_cas))]
- Big {
- fut: Collect<FuturesOrdered<F>, Vec<F::Output>>,
- },
+ elems: Pin<Box<[MaybeDone<F>]>>,
}
impl<F> fmt::Debug for JoinAll<F>
@@ -53,13 +36,9 @@ where
F::Output: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self.kind {
- JoinAllKind::Small { ref elems } => {
- f.debug_struct("JoinAll").field("elems", elems).finish()
- }
- #[cfg(not(futures_no_atomic_cas))]
- JoinAllKind::Big { ref fut, .. } => fmt::Debug::fmt(fut, f),
- }
+ f.debug_struct("JoinAll")
+ .field("elems", &self.elems)
+ .finish()
}
}
@@ -75,9 +54,10 @@ where
///
/// # See Also
///
-/// `join_all` will switch to the more powerful [`FuturesOrdered`] for performance
-/// reasons if the number of futures is large. You may want to look into using it or
-/// it's counterpart [`FuturesUnordered`][crate::stream::FuturesUnordered] directly.
+/// This is purposefully a very simple API for basic use-cases. In a lot of
+/// cases you will want to use the more powerful
+/// [`FuturesOrdered`][crate::stream::FuturesOrdered] APIs, or, if order does
+/// not matter, [`FuturesUnordered`][crate::stream::FuturesUnordered].
///
/// Some examples for additional functionality provided by these are:
///
@@ -99,33 +79,13 @@ where
/// assert_eq!(join_all(futures).await, [1, 2, 3]);
/// # });
/// ```
-pub fn join_all<I>(iter: I) -> JoinAll<I::Item>
+pub fn join_all<I>(i: I) -> JoinAll<I::Item>
where
I: IntoIterator,
I::Item: Future,
{
- #[cfg(futures_no_atomic_cas)]
- {
- let elems = iter.into_iter().map(MaybeDone::Future).collect::<Box<[_]>>().into();
- let kind = JoinAllKind::Small { elems };
- assert_future::<Vec<<I::Item as Future>::Output>, _>(JoinAll { kind })
- }
- #[cfg(not(futures_no_atomic_cas))]
- {
- let iter = iter.into_iter();
- let kind = match iter.size_hint().1 {
- None => JoinAllKind::Big { fut: iter.collect::<FuturesOrdered<_>>().collect() },
- Some(max) => {
- if max <= SMALL {
- let elems = iter.map(MaybeDone::Future).collect::<Box<[_]>>().into();
- JoinAllKind::Small { elems }
- } else {
- JoinAllKind::Big { fut: iter.collect::<FuturesOrdered<_>>().collect() }
- }
- }
- };
- assert_future::<Vec<<I::Item as Future>::Output>, _>(JoinAll { kind })
- }
+ let elems: Box<[_]> = i.into_iter().map(MaybeDone::Future).collect();
+ assert_future::<Vec<<I::Item as Future>::Output>, _>(JoinAll { elems: elems.into() })
}
impl<F> Future for JoinAll<F>
@@ -135,27 +95,22 @@ where
type Output = Vec<F::Output>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- match &mut self.kind {
- JoinAllKind::Small { elems } => {
- let mut all_done = true;
-
- for elem in iter_pin_mut(elems.as_mut()) {
- if elem.poll(cx).is_pending() {
- all_done = false;
- }
- }
+ let mut all_done = true;
- if all_done {
- let mut elems = mem::replace(elems, Box::pin([]));
- let result =
- iter_pin_mut(elems.as_mut()).map(|e| e.take_output().unwrap()).collect();
- Poll::Ready(result)
- } else {
- Poll::Pending
- }
+ for elem in iter_pin_mut(self.elems.as_mut()) {
+ if elem.poll(cx).is_pending() {
+ all_done = false;
}
- #[cfg(not(futures_no_atomic_cas))]
- JoinAllKind::Big { fut } => Pin::new(fut).poll(cx),
+ }
+
+ if all_done {
+ let mut elems = mem::replace(&mut self.elems, Box::pin([]));
+ let result = iter_pin_mut(elems.as_mut())
+ .map(|e| e.take_output().unwrap())
+ .collect();
+ Poll::Ready(result)
+ } else {
+ Poll::Pending
}
}
}
diff --git a/src/future/lazy.rs b/src/future/lazy.rs
index e9a8cf2..42812d3 100644
--- a/src/future/lazy.rs
+++ b/src/future/lazy.rs
@@ -7,7 +7,7 @@ use futures_core::task::{Context, Poll};
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Lazy<F> {
- f: Option<F>,
+ f: Option<F>
}
// safe because we never generate `Pin<&mut F>`
@@ -33,24 +33,19 @@ impl<F> Unpin for Lazy<F> {}
/// # });
/// ```
pub fn lazy<F, R>(f: F) -> Lazy<F>
-where
- F: FnOnce(&mut Context<'_>) -> R,
+ where F: FnOnce(&mut Context<'_>) -> R,
{
assert_future::<R, _>(Lazy { f: Some(f) })
}
impl<F, R> FusedFuture for Lazy<F>
-where
- F: FnOnce(&mut Context<'_>) -> R,
+ where F: FnOnce(&mut Context<'_>) -> R,
{
- fn is_terminated(&self) -> bool {
- self.f.is_none()
- }
+ fn is_terminated(&self) -> bool { self.f.is_none() }
}
impl<F, R> Future for Lazy<F>
-where
- F: FnOnce(&mut Context<'_>) -> R,
+ where F: FnOnce(&mut Context<'_>) -> R,
{
type Output = R;
diff --git a/src/future/mod.rs b/src/future/mod.rs
index 374e365..84e457c 100644
--- a/src/future/mod.rs
+++ b/src/future/mod.rs
@@ -21,7 +21,7 @@ pub use futures_task::{FutureObj, LocalFutureObj, UnsafeFutureObj};
#[allow(clippy::module_inception)]
mod future;
pub use self::future::{
- Flatten, Fuse, FutureExt, Inspect, IntoStream, Map, MapInto, NeverError, Then, UnitError,
+ Flatten, Fuse, FutureExt, Inspect, IntoStream, Map, NeverError, Then, UnitError, MapInto,
};
#[deprecated(note = "This is now an alias for [Flatten](Flatten)")]
@@ -40,8 +40,8 @@ pub use self::future::{Shared, WeakShared};
mod try_future;
pub use self::try_future::{
- AndThen, ErrInto, InspectErr, InspectOk, IntoFuture, MapErr, MapOk, MapOkOrElse, OkInto,
- OrElse, TryFlatten, TryFlattenStream, TryFutureExt, UnwrapOrElse,
+ AndThen, ErrInto, OkInto, InspectErr, InspectOk, IntoFuture, MapErr, MapOk, OrElse, TryFlattenStream,
+ TryFutureExt, UnwrapOrElse, MapOkOrElse, TryFlatten,
};
#[cfg(feature = "sink")]
@@ -68,9 +68,6 @@ pub use self::option::OptionFuture;
mod poll_fn;
pub use self::poll_fn::{poll_fn, PollFn};
-mod poll_immediate;
-pub use self::poll_immediate::{poll_immediate, PollImmediate};
-
mod ready;
pub use self::ready::{err, ok, ready, Ready};
@@ -111,15 +108,12 @@ pub use self::select_ok::{select_ok, SelectOk};
mod either;
pub use self::either::Either;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-mod abortable;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-pub use crate::abortable::{AbortHandle, AbortRegistration, Abortable, Aborted};
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-pub use abortable::abortable;
+cfg_target_has_atomic! {
+ #[cfg(feature = "alloc")]
+ mod abortable;
+ #[cfg(feature = "alloc")]
+ pub use self::abortable::{abortable, Abortable, AbortHandle, AbortRegistration, Aborted};
+}
// Just a helper function to ensure the futures we're returning all have the
// right implementations.
diff --git a/src/future/option.rs b/src/future/option.rs
index 0bc3777..85939d6 100644
--- a/src/future/option.rs
+++ b/src/future/option.rs
@@ -1,7 +1,7 @@
//! Definition of the `Option` (optional step) combinator
use core::pin::Pin;
-use futures_core::future::{FusedFuture, Future};
+use futures_core::future::{Future, FusedFuture};
use futures_core::task::{Context, Poll};
use pin_project_lite::pin_project;
@@ -31,16 +31,13 @@ pin_project! {
}
}
-impl<F> Default for OptionFuture<F> {
- fn default() -> Self {
- Self { inner: None }
- }
-}
-
impl<F: Future> Future for OptionFuture<F> {
type Output = Option<F::Output>;
- fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ fn poll(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Self::Output> {
match self.project().inner.as_pin_mut() {
Some(x) => x.poll(cx).map(Some),
None => Poll::Ready(None),
diff --git a/src/future/pending.rs b/src/future/pending.rs
index 92c78d5..4311b9a 100644
--- a/src/future/pending.rs
+++ b/src/future/pending.rs
@@ -34,7 +34,9 @@ impl<T> FusedFuture for Pending<T> {
/// # });
/// ```
pub fn pending<T>() -> Pending<T> {
- assert_future::<T, _>(Pending { _data: marker::PhantomData })
+ assert_future::<T, _>(Pending {
+ _data: marker::PhantomData,
+ })
}
impl<T> Future for Pending<T> {
@@ -45,7 +47,8 @@ impl<T> Future for Pending<T> {
}
}
-impl<T> Unpin for Pending<T> {}
+impl<T> Unpin for Pending<T> {
+}
impl<T> Clone for Pending<T> {
fn clone(&self) -> Self {
diff --git a/src/future/poll_fn.rs b/src/future/poll_fn.rs
index 1931157..6ac1ab8 100644
--- a/src/future/poll_fn.rs
+++ b/src/future/poll_fn.rs
@@ -35,7 +35,7 @@ impl<F> Unpin for PollFn<F> {}
/// ```
pub fn poll_fn<T, F>(f: F) -> PollFn<F>
where
- F: FnMut(&mut Context<'_>) -> Poll<T>,
+ F: FnMut(&mut Context<'_>) -> Poll<T>
{
assert_future::<T, _>(PollFn { f })
}
@@ -47,8 +47,7 @@ impl<F> fmt::Debug for PollFn<F> {
}
impl<T, F> Future for PollFn<F>
-where
- F: FnMut(&mut Context<'_>) -> Poll<T>,
+ where F: FnMut(&mut Context<'_>) -> Poll<T>,
{
type Output = T;
diff --git a/src/future/poll_immediate.rs b/src/future/poll_immediate.rs
deleted file mode 100644
index 5ae555c..0000000
--- a/src/future/poll_immediate.rs
+++ /dev/null
@@ -1,126 +0,0 @@
-use super::assert_future;
-use core::pin::Pin;
-use futures_core::task::{Context, Poll};
-use futures_core::{FusedFuture, Future, Stream};
-use pin_project_lite::pin_project;
-
-pin_project! {
- /// Future for the [`poll_immediate`](poll_immediate()) function.
- ///
- /// It will never return [Poll::Pending](core::task::Poll::Pending)
- #[derive(Debug, Clone)]
- #[must_use = "futures do nothing unless you `.await` or poll them"]
- pub struct PollImmediate<T> {
- #[pin]
- future: Option<T>
- }
-}
-
-impl<T, F> Future for PollImmediate<F>
-where
- F: Future<Output = T>,
-{
- type Output = Option<T>;
-
- #[inline]
- fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<T>> {
- let mut this = self.project();
- let inner =
- this.future.as_mut().as_pin_mut().expect("PollImmediate polled after completion");
- match inner.poll(cx) {
- Poll::Ready(t) => {
- this.future.set(None);
- Poll::Ready(Some(t))
- }
- Poll::Pending => Poll::Ready(None),
- }
- }
-}
-
-impl<T: Future> FusedFuture for PollImmediate<T> {
- fn is_terminated(&self) -> bool {
- self.future.is_none()
- }
-}
-
-/// A [Stream](crate::stream::Stream) implementation that can be polled repeatedly until the future is done.
-/// The stream will never return [Poll::Pending](core::task::Poll::Pending)
-/// so polling it in a tight loop is worse than using a blocking synchronous function.
-/// ```
-/// # futures::executor::block_on(async {
-/// use futures::task::Poll;
-/// use futures::{StreamExt, future, pin_mut};
-/// use future::FusedFuture;
-///
-/// let f = async { 1_u32 };
-/// pin_mut!(f);
-/// let mut r = future::poll_immediate(f);
-/// assert_eq!(r.next().await, Some(Poll::Ready(1)));
-///
-/// let f = async {futures::pending!(); 42_u8};
-/// pin_mut!(f);
-/// let mut p = future::poll_immediate(f);
-/// assert_eq!(p.next().await, Some(Poll::Pending));
-/// assert!(!p.is_terminated());
-/// assert_eq!(p.next().await, Some(Poll::Ready(42)));
-/// assert!(p.is_terminated());
-/// assert_eq!(p.next().await, None);
-/// # });
-/// ```
-impl<T, F> Stream for PollImmediate<F>
-where
- F: Future<Output = T>,
-{
- type Item = Poll<T>;
-
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
- let mut this = self.project();
- match this.future.as_mut().as_pin_mut() {
- // inner is gone, so we can signal that the stream is closed.
- None => Poll::Ready(None),
- Some(fut) => Poll::Ready(Some(fut.poll(cx).map(|t| {
- this.future.set(None);
- t
- }))),
- }
- }
-}
-
-/// Creates a future that is immediately ready with an Option of a value.
-/// Specifically this means that [poll](core::future::Future::poll()) always returns [Poll::Ready](core::task::Poll::Ready).
-///
-/// # Caution
-///
-/// When consuming the future by this function, note the following:
-///
-/// - This function does not guarantee that the future will run to completion, so it is generally incompatible with passing the non-cancellation-safe future by value.
-/// - Even if the future is cancellation-safe, creating and dropping new futures frequently may lead to performance problems.
-///
-/// # Examples
-///
-/// ```
-/// # futures::executor::block_on(async {
-/// use futures::future;
-///
-/// let r = future::poll_immediate(async { 1_u32 });
-/// assert_eq!(r.await, Some(1));
-///
-/// let p = future::poll_immediate(future::pending::<i32>());
-/// assert_eq!(p.await, None);
-/// # });
-/// ```
-///
-/// ### Reusing a future
-///
-/// ```
-/// # futures::executor::block_on(async {
-/// use futures::{future, pin_mut};
-/// let f = async {futures::pending!(); 42_u8};
-/// pin_mut!(f);
-/// assert_eq!(None, future::poll_immediate(&mut f).await);
-/// assert_eq!(42, f.await);
-/// # });
-/// ```
-pub fn poll_immediate<F: Future>(f: F) -> PollImmediate<F> {
- assert_future::<Option<F::Output>, PollImmediate<F>>(PollImmediate { future: Some(f) })
-}
diff --git a/src/future/select.rs b/src/future/select.rs
index bd44f20..043ed17 100644
--- a/src/future/select.rs
+++ b/src/future/select.rs
@@ -1,8 +1,8 @@
use super::assert_future;
-use crate::future::{Either, FutureExt};
use core::pin::Pin;
-use futures_core::future::{FusedFuture, Future};
+use futures_core::future::{Future, FusedFuture};
use futures_core::task::{Context, Poll};
+use crate::future::{Either, FutureExt};
/// Future for the [`select()`] function.
#[must_use = "futures do nothing unless you `.await` or poll them"]
@@ -37,13 +37,13 @@ impl<A: Unpin, B: Unpin> Unpin for Select<A, B> {}
/// future::Either,
/// future::self,
/// };
-///
+///
/// // These two futures have different types even though their outputs have the same type.
/// let future1 = async {
/// future::pending::<()>().await; // will never finish
/// 1
/// };
-/// let future2 = async {
+/// let future2 = async {
/// future::ready(2).await
/// };
///
@@ -82,13 +82,9 @@ impl<A: Unpin, B: Unpin> Unpin for Select<A, B> {}
/// }
/// ```
pub fn select<A, B>(future1: A, future2: B) -> Select<A, B>
-where
- A: Future + Unpin,
- B: Future + Unpin,
+ where A: Future + Unpin, B: Future + Unpin
{
- assert_future::<Either<(A::Output, B), (B::Output, A)>, _>(Select {
- inner: Some((future1, future2)),
- })
+ assert_future::<Either<(A::Output, B), (B::Output, A)>, _>(Select { inner: Some((future1, future2)) })
}
impl<A, B> Future for Select<A, B>
@@ -108,7 +104,7 @@ where
self.inner = Some((a, b));
Poll::Pending
}
- },
+ }
}
}
}
diff --git a/src/future/select_all.rs b/src/future/select_all.rs
index 106e508..0db90a7 100644
--- a/src/future/select_all.rs
+++ b/src/future/select_all.rs
@@ -1,9 +1,9 @@
use super::assert_future;
use crate::future::FutureExt;
-use alloc::vec::Vec;
use core::iter::FromIterator;
use core::mem;
use core::pin::Pin;
+use alloc::vec::Vec;
use futures_core::future::Future;
use futures_core::task::{Context, Poll};
@@ -32,29 +32,25 @@ impl<Fut: Unpin> Unpin for SelectAll<Fut> {}
///
/// This function will panic if the iterator specified contains no items.
pub fn select_all<I>(iter: I) -> SelectAll<I::Item>
-where
- I: IntoIterator,
- I::Item: Future + Unpin,
+ where I: IntoIterator,
+ I::Item: Future + Unpin,
{
- let ret = SelectAll { inner: iter.into_iter().collect() };
+ let ret = SelectAll {
+ inner: iter.into_iter().collect()
+ };
assert!(!ret.inner.is_empty());
assert_future::<(<I::Item as Future>::Output, usize, Vec<I::Item>), _>(ret)
}
-impl<Fut> SelectAll<Fut> {
- /// Consumes this combinator, returning the underlying futures.
- pub fn into_inner(self) -> Vec<Fut> {
- self.inner
- }
-}
-
impl<Fut: Future + Unpin> Future for SelectAll<Fut> {
type Output = (Fut::Output, usize, Vec<Fut>);
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- let item = self.inner.iter_mut().enumerate().find_map(|(i, f)| match f.poll_unpin(cx) {
- Poll::Pending => None,
- Poll::Ready(e) => Some((i, e)),
+ let item = self.inner.iter_mut().enumerate().find_map(|(i, f)| {
+ match f.poll_unpin(cx) {
+ Poll::Pending => None,
+ Poll::Ready(e) => Some((i, e)),
+ }
});
match item {
Some((idx, res)) => {
diff --git a/src/future/select_ok.rs b/src/future/select_ok.rs
index 0ad83c6..52d393c 100644
--- a/src/future/select_ok.rs
+++ b/src/future/select_ok.rs
@@ -1,9 +1,9 @@
use super::assert_future;
use crate::future::TryFutureExt;
-use alloc::vec::Vec;
use core::iter::FromIterator;
use core::mem;
use core::pin::Pin;
+use alloc::vec::Vec;
use futures_core::future::{Future, TryFuture};
use futures_core::task::{Context, Poll};
@@ -30,16 +30,14 @@ impl<Fut: Unpin> Unpin for SelectOk<Fut> {}
///
/// This function will panic if the iterator specified contains no items.
pub fn select_ok<I>(iter: I) -> SelectOk<I::Item>
-where
- I: IntoIterator,
- I::Item: TryFuture + Unpin,
+ where I: IntoIterator,
+ I::Item: TryFuture + Unpin,
{
- let ret = SelectOk { inner: iter.into_iter().collect() };
+ let ret = SelectOk {
+ inner: iter.into_iter().collect()
+ };
assert!(!ret.inner.is_empty(), "iterator provided to select_ok was empty");
- assert_future::<
- Result<(<I::Item as TryFuture>::Ok, Vec<I::Item>), <I::Item as TryFuture>::Error>,
- _,
- >(ret)
+ assert_future::<Result<(<I::Item as TryFuture>::Ok, Vec<I::Item>), <I::Item as TryFuture>::Error>, _>(ret)
}
impl<Fut: TryFuture + Unpin> Future for SelectOk<Fut> {
@@ -48,11 +46,12 @@ impl<Fut: TryFuture + Unpin> Future for SelectOk<Fut> {
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
// loop until we've either exhausted all errors, a success was hit, or nothing is ready
loop {
- let item =
- self.inner.iter_mut().enumerate().find_map(|(i, f)| match f.try_poll_unpin(cx) {
+ let item = self.inner.iter_mut().enumerate().find_map(|(i, f)| {
+ match f.try_poll_unpin(cx) {
Poll::Pending => None,
Poll::Ready(e) => Some((i, e)),
- });
+ }
+ });
match item {
Some((idx, res)) => {
// always remove Ok or Err, if it's not the last Err continue looping
@@ -60,18 +59,18 @@ impl<Fut: TryFuture + Unpin> Future for SelectOk<Fut> {
match res {
Ok(e) => {
let rest = mem::replace(&mut self.inner, Vec::new());
- return Poll::Ready(Ok((e, rest)));
+ return Poll::Ready(Ok((e, rest)))
}
Err(e) => {
if self.inner.is_empty() {
- return Poll::Ready(Err(e));
+ return Poll::Ready(Err(e))
}
}
}
}
None => {
// based on the filter above, nothing is ready, return
- return Poll::Pending;
+ return Poll::Pending
}
}
}
diff --git a/src/future/try_future/into_future.rs b/src/future/try_future/into_future.rs
index 9f093d0..e88d603 100644
--- a/src/future/try_future/into_future.rs
+++ b/src/future/try_future/into_future.rs
@@ -21,16 +21,17 @@ impl<Fut> IntoFuture<Fut> {
}
impl<Fut: TryFuture + FusedFuture> FusedFuture for IntoFuture<Fut> {
- fn is_terminated(&self) -> bool {
- self.future.is_terminated()
- }
+ fn is_terminated(&self) -> bool { self.future.is_terminated() }
}
impl<Fut: TryFuture> Future for IntoFuture<Fut> {
type Output = Result<Fut::Ok, Fut::Error>;
#[inline]
- fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ fn poll(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Self::Output> {
self.project().future.try_poll(cx)
}
}
diff --git a/src/future/try_future/try_flatten.rs b/src/future/try_future/try_flatten.rs
index 1ce4559..5241b27 100644
--- a/src/future/try_future/try_flatten.rs
+++ b/src/future/try_future/try_flatten.rs
@@ -2,9 +2,9 @@ use core::pin::Pin;
use futures_core::future::{FusedFuture, Future, TryFuture};
use futures_core::ready;
use futures_core::stream::{FusedStream, Stream, TryStream};
-use futures_core::task::{Context, Poll};
#[cfg(feature = "sink")]
use futures_sink::Sink;
+use futures_core::task::{Context, Poll};
use pin_project_lite::pin_project;
pin_project! {
@@ -24,9 +24,8 @@ impl<Fut1, Fut2> TryFlatten<Fut1, Fut2> {
}
impl<Fut> FusedFuture for TryFlatten<Fut, Fut::Ok>
-where
- Fut: TryFuture,
- Fut::Ok: TryFuture<Error = Fut::Error>,
+ where Fut: TryFuture,
+ Fut::Ok: TryFuture<Error=Fut::Error>,
{
fn is_terminated(&self) -> bool {
match self {
@@ -37,27 +36,28 @@ where
}
impl<Fut> Future for TryFlatten<Fut, Fut::Ok>
-where
- Fut: TryFuture,
- Fut::Ok: TryFuture<Error = Fut::Error>,
+ where Fut: TryFuture,
+ Fut::Ok: TryFuture<Error=Fut::Error>,
{
type Output = Result<<Fut::Ok as TryFuture>::Ok, Fut::Error>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Poll::Ready(loop {
match self.as_mut().project() {
- TryFlattenProj::First { f } => match ready!(f.try_poll(cx)) {
- Ok(f) => self.set(Self::Second { f }),
- Err(e) => {
- self.set(Self::Empty);
- break Err(e);
+ TryFlattenProj::First { f } => {
+ match ready!(f.try_poll(cx)) {
+ Ok(f) => self.set(Self::Second { f }),
+ Err(e) => {
+ self.set(Self::Empty);
+ break Err(e);
+ }
}
},
TryFlattenProj::Second { f } => {
let output = ready!(f.try_poll(cx));
self.set(Self::Empty);
break output;
- }
+ },
TryFlattenProj::Empty => panic!("TryFlatten polled after completion"),
}
})
@@ -65,9 +65,8 @@ where
}
impl<Fut> FusedStream for TryFlatten<Fut, Fut::Ok>
-where
- Fut: TryFuture,
- Fut::Ok: TryStream<Error = Fut::Error>,
+ where Fut: TryFuture,
+ Fut::Ok: TryStream<Error=Fut::Error>,
{
fn is_terminated(&self) -> bool {
match self {
@@ -78,20 +77,21 @@ where
}
impl<Fut> Stream for TryFlatten<Fut, Fut::Ok>
-where
- Fut: TryFuture,
- Fut::Ok: TryStream<Error = Fut::Error>,
+ where Fut: TryFuture,
+ Fut::Ok: TryStream<Error=Fut::Error>,
{
type Item = Result<<Fut::Ok as TryStream>::Ok, Fut::Error>;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
Poll::Ready(loop {
match self.as_mut().project() {
- TryFlattenProj::First { f } => match ready!(f.try_poll(cx)) {
- Ok(f) => self.set(Self::Second { f }),
- Err(e) => {
- self.set(Self::Empty);
- break Some(Err(e));
+ TryFlattenProj::First { f } => {
+ match ready!(f.try_poll(cx)) {
+ Ok(f) => self.set(Self::Second { f }),
+ Err(e) => {
+ self.set(Self::Empty);
+ break Some(Err(e));
+ }
}
},
TryFlattenProj::Second { f } => {
@@ -100,34 +100,40 @@ where
self.set(Self::Empty);
}
break output;
- }
+ },
TryFlattenProj::Empty => break None,
}
})
}
}
+
#[cfg(feature = "sink")]
impl<Fut, Item> Sink<Item> for TryFlatten<Fut, Fut::Ok>
where
Fut: TryFuture,
- Fut::Ok: Sink<Item, Error = Fut::Error>,
+ Fut::Ok: Sink<Item, Error=Fut::Error>,
{
type Error = Fut::Error;
- fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_ready(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
Poll::Ready(loop {
match self.as_mut().project() {
- TryFlattenProj::First { f } => match ready!(f.try_poll(cx)) {
- Ok(f) => self.set(Self::Second { f }),
- Err(e) => {
- self.set(Self::Empty);
- break Err(e);
+ TryFlattenProj::First { f } => {
+ match ready!(f.try_poll(cx)) {
+ Ok(f) => self.set(Self::Second { f }),
+ Err(e) => {
+ self.set(Self::Empty);
+ break Err(e);
+ }
}
},
TryFlattenProj::Second { f } => {
break ready!(f.poll_ready(cx));
- }
+ },
TryFlattenProj::Empty => panic!("poll_ready called after eof"),
}
})
@@ -149,7 +155,10 @@ where
}
}
- fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_close(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
let res = match self.as_mut().project() {
TryFlattenProj::Second { f } => f.poll_close(cx),
_ => Poll::Ready(Ok(())),
diff --git a/src/future/try_future/try_flatten_err.rs b/src/future/try_future/try_flatten_err.rs
index 39b7d9f..2e67f11 100644
--- a/src/future/try_future/try_flatten_err.rs
+++ b/src/future/try_future/try_flatten_err.rs
@@ -21,9 +21,8 @@ impl<Fut1, Fut2> TryFlattenErr<Fut1, Fut2> {
}
impl<Fut> FusedFuture for TryFlattenErr<Fut, Fut::Error>
-where
- Fut: TryFuture,
- Fut::Error: TryFuture<Ok = Fut::Ok>,
+ where Fut: TryFuture,
+ Fut::Error: TryFuture<Ok=Fut::Ok>,
{
fn is_terminated(&self) -> bool {
match self {
@@ -34,27 +33,28 @@ where
}
impl<Fut> Future for TryFlattenErr<Fut, Fut::Error>
-where
- Fut: TryFuture,
- Fut::Error: TryFuture<Ok = Fut::Ok>,
+ where Fut: TryFuture,
+ Fut::Error: TryFuture<Ok=Fut::Ok>,
{
type Output = Result<Fut::Ok, <Fut::Error as TryFuture>::Error>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Poll::Ready(loop {
match self.as_mut().project() {
- TryFlattenErrProj::First { f } => match ready!(f.try_poll(cx)) {
- Err(f) => self.set(Self::Second { f }),
- Ok(e) => {
- self.set(Self::Empty);
- break Ok(e);
+ TryFlattenErrProj::First { f } => {
+ match ready!(f.try_poll(cx)) {
+ Err(f) => self.set(Self::Second { f }),
+ Ok(e) => {
+ self.set(Self::Empty);
+ break Ok(e);
+ }
}
},
TryFlattenErrProj::Second { f } => {
let output = ready!(f.try_poll(cx));
self.set(Self::Empty);
break output;
- }
+ },
TryFlattenErrProj::Empty => panic!("TryFlattenErr polled after completion"),
}
})
diff --git a/src/future/try_join_all.rs b/src/future/try_join_all.rs
index 29244af..371f753 100644
--- a/src/future/try_join_all.rs
+++ b/src/future/try_join_all.rs
@@ -1,14 +1,14 @@
//! Definition of the `TryJoinAll` combinator, waiting for all of a list of
//! futures to finish with either success or error.
-use alloc::boxed::Box;
-use alloc::vec::Vec;
use core::fmt;
use core::future::Future;
use core::iter::FromIterator;
use core::mem;
use core::pin::Pin;
use core::task::{Context, Poll};
+use alloc::boxed::Box;
+use alloc::vec::Vec;
use super::{assert_future, TryFuture, TryMaybeDone};
@@ -16,13 +16,15 @@ fn iter_pin_mut<T>(slice: Pin<&mut [T]>) -> impl Iterator<Item = Pin<&mut T>> {
// Safety: `std` _could_ make this unsound if it were to decide Pin's
// invariants aren't required to transmit through slices. Otherwise this has
// the same safety as a normal field pin projection.
- unsafe { slice.get_unchecked_mut() }.iter_mut().map(|t| unsafe { Pin::new_unchecked(t) })
+ unsafe { slice.get_unchecked_mut() }
+ .iter_mut()
+ .map(|t| unsafe { Pin::new_unchecked(t) })
}
enum FinalState<E = ()> {
Pending,
AllDone,
- Error(E),
+ Error(E)
}
/// Future for the [`try_join_all`] function.
@@ -41,7 +43,9 @@ where
F::Error: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("TryJoinAll").field("elems", &self.elems).finish()
+ f.debug_struct("TryJoinAll")
+ .field("elems", &self.elems)
+ .finish()
}
}
@@ -89,9 +93,9 @@ where
I::Item: TryFuture,
{
let elems: Box<[_]> = i.into_iter().map(TryMaybeDone::Future).collect();
- assert_future::<Result<Vec<<I::Item as TryFuture>::Ok>, <I::Item as TryFuture>::Error>, _>(
- TryJoinAll { elems: elems.into() },
- )
+ assert_future::<Result<Vec<<I::Item as TryFuture>::Ok>, <I::Item as TryFuture>::Error>, _>(TryJoinAll {
+ elems: elems.into(),
+ })
}
impl<F> Future for TryJoinAll<F>
@@ -106,7 +110,7 @@ where
for elem in iter_pin_mut(self.elems.as_mut()) {
match elem.try_poll(cx) {
Poll::Pending => state = FinalState::Pending,
- Poll::Ready(Ok(())) => {}
+ Poll::Ready(Ok(())) => {},
Poll::Ready(Err(e)) => {
state = FinalState::Error(e);
break;
@@ -118,14 +122,15 @@ where
FinalState::Pending => Poll::Pending,
FinalState::AllDone => {
let mut elems = mem::replace(&mut self.elems, Box::pin([]));
- let results =
- iter_pin_mut(elems.as_mut()).map(|e| e.take_output().unwrap()).collect();
+ let results = iter_pin_mut(elems.as_mut())
+ .map(|e| e.take_output().unwrap())
+ .collect();
Poll::Ready(Ok(results))
- }
+ },
FinalState::Error(e) => {
let _ = mem::replace(&mut self.elems, Box::pin([]));
Poll::Ready(Err(e))
- }
+ },
}
}
}
diff --git a/src/future/try_maybe_done.rs b/src/future/try_maybe_done.rs
index 24044d2..dfd2900 100644
--- a/src/future/try_maybe_done.rs
+++ b/src/future/try_maybe_done.rs
@@ -49,13 +49,13 @@ impl<Fut: TryFuture> TryMaybeDone<Fut> {
#[inline]
pub fn take_output(self: Pin<&mut Self>) -> Option<Fut::Ok> {
match &*self {
- Self::Done(_) => {}
+ Self::Done(_) => {},
Self::Future(_) | Self::Gone => return None,
}
unsafe {
match mem::replace(self.get_unchecked_mut(), Self::Gone) {
TryMaybeDone::Done(output) => Some(output),
- _ => unreachable!(),
+ _ => unreachable!()
}
}
}
@@ -76,14 +76,16 @@ impl<Fut: TryFuture> Future for TryMaybeDone<Fut> {
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
unsafe {
match self.as_mut().get_unchecked_mut() {
- TryMaybeDone::Future(f) => match ready!(Pin::new_unchecked(f).try_poll(cx)) {
- Ok(res) => self.set(Self::Done(res)),
- Err(e) => {
- self.set(Self::Gone);
- return Poll::Ready(Err(e));
+ TryMaybeDone::Future(f) => {
+ match ready!(Pin::new_unchecked(f).try_poll(cx)) {
+ Ok(res) => self.set(Self::Done(res)),
+ Err(e) => {
+ self.set(Self::Gone);
+ return Poll::Ready(Err(e));
+ }
}
},
- TryMaybeDone::Done(_) => {}
+ TryMaybeDone::Done(_) => {},
TryMaybeDone::Gone => panic!("TryMaybeDone polled after value taken"),
}
}
diff --git a/src/future/try_select.rs b/src/future/try_select.rs
index 4d0b7ff..b26eed3 100644
--- a/src/future/try_select.rs
+++ b/src/future/try_select.rs
@@ -1,7 +1,7 @@
-use crate::future::{Either, TryFutureExt};
use core::pin::Pin;
use futures_core::future::{Future, TryFuture};
use futures_core::task::{Context, Poll};
+use crate::future::{Either, TryFutureExt};
/// Future for the [`try_select()`] function.
#[must_use = "futures do nothing unless you `.await` or poll them"]
@@ -48,23 +48,22 @@ impl<A: Unpin, B: Unpin> Unpin for TrySelect<A, B> {}
/// }
/// ```
pub fn try_select<A, B>(future1: A, future2: B) -> TrySelect<A, B>
-where
- A: TryFuture + Unpin,
- B: TryFuture + Unpin,
+ where A: TryFuture + Unpin, B: TryFuture + Unpin
{
- super::assert_future::<
- Result<Either<(A::Ok, B), (B::Ok, A)>, Either<(A::Error, B), (B::Error, A)>>,
- _,
- >(TrySelect { inner: Some((future1, future2)) })
+ super::assert_future::<Result<
+ Either<(A::Ok, B), (B::Ok, A)>,
+ Either<(A::Error, B), (B::Error, A)>,
+ >, _>(TrySelect { inner: Some((future1, future2)) })
}
impl<A: Unpin, B: Unpin> Future for TrySelect<A, B>
-where
- A: TryFuture,
- B: TryFuture,
+ where A: TryFuture, B: TryFuture
{
#[allow(clippy::type_complexity)]
- type Output = Result<Either<(A::Ok, B), (B::Ok, A)>, Either<(A::Error, B), (B::Error, A)>>;
+ type Output = Result<
+ Either<(A::Ok, B), (B::Ok, A)>,
+ Either<(A::Error, B), (B::Error, A)>,
+ >;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let (mut a, mut b) = self.inner.take().expect("cannot poll Select twice");
@@ -78,7 +77,7 @@ where
self.inner = Some((a, b));
Poll::Pending
}
- },
+ }
}
}
}
diff --git a/src/io/allow_std.rs b/src/io/allow_std.rs
index ec30ee3..9aa8eb4 100644
--- a/src/io/allow_std.rs
+++ b/src/io/allow_std.rs
@@ -1,7 +1,9 @@
use futures_core::task::{Context, Poll};
-use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, SeekFrom};
-use std::pin::Pin;
+#[cfg(feature = "read-initializer")]
+use futures_io::Initializer;
+use futures_io::{AsyncRead, AsyncWrite, AsyncSeek, AsyncBufRead, IoSlice, IoSliceMut, SeekFrom};
use std::{fmt, io};
+use std::pin::Pin;
/// A simple wrapper type which allows types which implement only
/// implement `std::io::Read` or `std::io::Write`
@@ -33,7 +35,7 @@ macro_rules! try_with_interrupt {
}
}
}
- };
+ }
}
impl<T> AllowStdIo<T> {
@@ -58,10 +60,7 @@ impl<T> AllowStdIo<T> {
}
}
-impl<T> io::Write for AllowStdIo<T>
-where
- T: io::Write,
-{
+impl<T> io::Write for AllowStdIo<T> where T: io::Write {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
}
@@ -79,23 +78,16 @@ where
}
}
-impl<T> AsyncWrite for AllowStdIo<T>
-where
- T: io::Write,
-{
- fn poll_write(
- mut self: Pin<&mut Self>,
- _: &mut Context<'_>,
- buf: &[u8],
- ) -> Poll<io::Result<usize>> {
+impl<T> AsyncWrite for AllowStdIo<T> where T: io::Write {
+ fn poll_write(mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &[u8])
+ -> Poll<io::Result<usize>>
+ {
Poll::Ready(Ok(try_with_interrupt!(self.0.write(buf))))
}
- fn poll_write_vectored(
- mut self: Pin<&mut Self>,
- _: &mut Context<'_>,
- bufs: &[IoSlice<'_>],
- ) -> Poll<io::Result<usize>> {
+ fn poll_write_vectored(mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &[IoSlice<'_>])
+ -> Poll<io::Result<usize>>
+ {
Poll::Ready(Ok(try_with_interrupt!(self.0.write_vectored(bufs))))
}
@@ -109,16 +101,17 @@ where
}
}
-impl<T> io::Read for AllowStdIo<T>
-where
- T: io::Read,
-{
+impl<T> io::Read for AllowStdIo<T> where T: io::Read {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.0.read(buf)
}
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
self.0.read_vectored(bufs)
}
+ #[cfg(feature = "read-initializer")]
+ unsafe fn initializer(&self) -> Initializer {
+ self.0.initializer()
+ }
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
self.0.read_to_end(buf)
}
@@ -130,53 +123,40 @@ where
}
}
-impl<T> AsyncRead for AllowStdIo<T>
-where
- T: io::Read,
-{
- fn poll_read(
- mut self: Pin<&mut Self>,
- _: &mut Context<'_>,
- buf: &mut [u8],
- ) -> Poll<io::Result<usize>> {
+impl<T> AsyncRead for AllowStdIo<T> where T: io::Read {
+ fn poll_read(mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &mut [u8])
+ -> Poll<io::Result<usize>>
+ {
Poll::Ready(Ok(try_with_interrupt!(self.0.read(buf))))
}
- fn poll_read_vectored(
- mut self: Pin<&mut Self>,
- _: &mut Context<'_>,
- bufs: &mut [IoSliceMut<'_>],
- ) -> Poll<io::Result<usize>> {
+ fn poll_read_vectored(mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>])
+ -> Poll<io::Result<usize>>
+ {
Poll::Ready(Ok(try_with_interrupt!(self.0.read_vectored(bufs))))
}
+
+ #[cfg(feature = "read-initializer")]
+ unsafe fn initializer(&self) -> Initializer {
+ self.0.initializer()
+ }
}
-impl<T> io::Seek for AllowStdIo<T>
-where
- T: io::Seek,
-{
+impl<T> io::Seek for AllowStdIo<T> where T: io::Seek {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
self.0.seek(pos)
}
}
-impl<T> AsyncSeek for AllowStdIo<T>
-where
- T: io::Seek,
-{
- fn poll_seek(
- mut self: Pin<&mut Self>,
- _: &mut Context<'_>,
- pos: SeekFrom,
- ) -> Poll<io::Result<u64>> {
+impl<T> AsyncSeek for AllowStdIo<T> where T: io::Seek {
+ fn poll_seek(mut self: Pin<&mut Self>, _: &mut Context<'_>, pos: SeekFrom)
+ -> Poll<io::Result<u64>>
+ {
Poll::Ready(Ok(try_with_interrupt!(self.0.seek(pos))))
}
}
-impl<T> io::BufRead for AllowStdIo<T>
-where
- T: io::BufRead,
-{
+impl<T> io::BufRead for AllowStdIo<T> where T: io::BufRead {
fn fill_buf(&mut self) -> io::Result<&[u8]> {
self.0.fill_buf()
}
@@ -185,11 +165,10 @@ where
}
}
-impl<T> AsyncBufRead for AllowStdIo<T>
-where
- T: io::BufRead,
-{
- fn poll_fill_buf(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
+impl<T> AsyncBufRead for AllowStdIo<T> where T: io::BufRead {
+ fn poll_fill_buf(mut self: Pin<&mut Self>, _: &mut Context<'_>)
+ -> Poll<io::Result<&[u8]>>
+ {
let this: *mut Self = &mut *self as *mut _;
Poll::Ready(Ok(try_with_interrupt!(unsafe { &mut *this }.0.fill_buf())))
}
diff --git a/src/io/buf_reader.rs b/src/io/buf_reader.rs
index 0334a9f..270a086 100644
--- a/src/io/buf_reader.rs
+++ b/src/io/buf_reader.rs
@@ -1,12 +1,13 @@
-use super::DEFAULT_BUF_SIZE;
-use futures_core::future::Future;
use futures_core::ready;
use futures_core::task::{Context, Poll};
+#[cfg(feature = "read-initializer")]
+use futures_io::Initializer;
use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSliceMut, SeekFrom};
use pin_project_lite::pin_project;
use std::io::{self, Read};
use std::pin::Pin;
use std::{cmp, fmt};
+use super::DEFAULT_BUF_SIZE;
pin_project! {
/// The `BufReader` struct adds buffering to any reader.
@@ -50,7 +51,12 @@ impl<R: AsyncRead> BufReader<R> {
let mut buffer = Vec::with_capacity(capacity);
buffer.set_len(capacity);
super::initialize(&inner, &mut buffer);
- Self { inner, buffer: buffer.into_boxed_slice(), pos: 0, cap: 0 }
+ Self {
+ inner,
+ buffer: buffer.into_boxed_slice(),
+ pos: 0,
+ cap: 0,
+ }
}
}
@@ -72,40 +78,6 @@ impl<R: AsyncRead> BufReader<R> {
}
}
-impl<R: AsyncRead + AsyncSeek> BufReader<R> {
- /// Seeks relative to the current position. If the new position lies within the buffer,
- /// the buffer will not be flushed, allowing for more efficient seeks.
- /// This method does not return the location of the underlying reader, so the caller
- /// must track this information themselves if it is required.
- pub fn seek_relative(self: Pin<&mut Self>, offset: i64) -> SeeKRelative<'_, R> {
- SeeKRelative { inner: self, offset, first: true }
- }
-
- /// Attempts to seek relative to the current position. If the new position lies within the buffer,
- /// the buffer will not be flushed, allowing for more efficient seeks.
- /// This method does not return the location of the underlying reader, so the caller
- /// must track this information themselves if it is required.
- pub fn poll_seek_relative(
- self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- offset: i64,
- ) -> Poll<io::Result<()>> {
- let pos = self.pos as u64;
- if offset < 0 {
- if let Some(new_pos) = pos.checked_sub((-offset) as u64) {
- *self.project().pos = new_pos as usize;
- return Poll::Ready(Ok(()));
- }
- } else if let Some(new_pos) = pos.checked_add(offset as u64) {
- if new_pos <= self.cap as u64 {
- *self.project().pos = new_pos as usize;
- return Poll::Ready(Ok(()));
- }
- }
- self.poll_seek(cx, SeekFrom::Current(offset)).map(|res| res.map(|_| ()))
- }
-}
-
impl<R: AsyncRead> AsyncRead for BufReader<R> {
fn poll_read(
mut self: Pin<&mut Self>,
@@ -142,10 +114,19 @@ impl<R: AsyncRead> AsyncRead for BufReader<R> {
self.consume(nread);
Poll::Ready(Ok(nread))
}
+
+ // we can't skip unconditionally because of the large buffer case in read.
+ #[cfg(feature = "read-initializer")]
+ unsafe fn initializer(&self) -> Initializer {
+ self.inner.initializer()
+ }
}
impl<R: AsyncRead> AsyncBufRead for BufReader<R> {
- fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
+ fn poll_fill_buf(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<io::Result<&[u8]>> {
let this = self.project();
// If we've reached the end of our internal buffer then we need to fetch
@@ -190,10 +171,6 @@ impl<R: AsyncRead + AsyncSeek> AsyncSeek for BufReader<R> {
/// `.into_inner()` immediately after a seek yields the underlying reader
/// at the same position.
///
- /// To seek without discarding the internal buffer, use
- /// [`BufReader::seek_relative`](BufReader::seek_relative) or
- /// [`BufReader::poll_seek_relative`](BufReader::poll_seek_relative).
- ///
/// See [`AsyncSeek`](futures_io::AsyncSeek) for more details.
///
/// Note: In the edge case where you're seeking with `SeekFrom::Current(n)`
@@ -215,8 +192,7 @@ impl<R: AsyncRead + AsyncSeek> AsyncSeek for BufReader<R> {
// support seeking by i64::min_value() so we need to handle underflow when subtracting
// remainder.
if let Some(offset) = n.checked_sub(remainder) {
- result =
- ready!(self.as_mut().project().inner.poll_seek(cx, SeekFrom::Current(offset)))?;
+ result = ready!(self.as_mut().project().inner.poll_seek(cx, SeekFrom::Current(offset)))?;
} else {
// seek backwards by our remainder, and then by the offset
ready!(self.as_mut().project().inner.poll_seek(cx, SeekFrom::Current(-remainder)))?;
@@ -231,33 +207,3 @@ impl<R: AsyncRead + AsyncSeek> AsyncSeek for BufReader<R> {
Poll::Ready(Ok(result))
}
}
-
-/// Future for the [`BufReader::seek_relative`](self::BufReader::seek_relative) method.
-#[derive(Debug)]
-#[must_use = "futures do nothing unless polled"]
-pub struct SeeKRelative<'a, R> {
- inner: Pin<&'a mut BufReader<R>>,
- offset: i64,
- first: bool,
-}
-
-impl<R> Future for SeeKRelative<'_, R>
-where
- R: AsyncRead + AsyncSeek,
-{
- type Output = io::Result<()>;
-
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- let offset = self.offset;
- if self.first {
- self.first = false;
- self.inner.as_mut().poll_seek_relative(cx, offset)
- } else {
- self.inner
- .as_mut()
- .as_mut()
- .poll_seek(cx, SeekFrom::Current(offset))
- .map(|res| res.map(|_| ()))
- }
- }
-}
diff --git a/src/io/buf_writer.rs b/src/io/buf_writer.rs
index cb74863..991a365 100644
--- a/src/io/buf_writer.rs
+++ b/src/io/buf_writer.rs
@@ -1,4 +1,3 @@
-use super::DEFAULT_BUF_SIZE;
use futures_core::ready;
use futures_core::task::{Context, Poll};
use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, SeekFrom};
@@ -6,7 +5,7 @@ use pin_project_lite::pin_project;
use std::fmt;
use std::io::{self, Write};
use std::pin::Pin;
-use std::ptr;
+use super::DEFAULT_BUF_SIZE;
pin_project! {
/// Wraps a writer and buffers its output.
@@ -47,10 +46,14 @@ impl<W: AsyncWrite> BufWriter<W> {
/// Creates a new `BufWriter` with the specified buffer capacity.
pub fn with_capacity(cap: usize, inner: W) -> Self {
- Self { inner, buf: Vec::with_capacity(cap), written: 0 }
+ Self {
+ inner,
+ buf: Vec::with_capacity(cap),
+ written: 0,
+ }
}
- pub(super) fn flush_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
+ fn flush_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
let mut this = self.project();
let len = this.buf.len();
@@ -84,68 +87,6 @@ impl<W: AsyncWrite> BufWriter<W> {
pub fn buffer(&self) -> &[u8] {
&self.buf
}
-
- /// Capacity of `buf`. how many chars can be held in buffer
- pub(super) fn capacity(&self) -> usize {
- self.buf.capacity()
- }
-
- /// Remaining number of bytes to reach `buf` 's capacity
- #[inline]
- pub(super) fn spare_capacity(&self) -> usize {
- self.buf.capacity() - self.buf.len()
- }
-
- /// Write a byte slice directly into buffer
- ///
- /// Will truncate the number of bytes written to `spare_capacity()` so you want to
- /// calculate the size of your slice to avoid losing bytes
- ///
- /// Based on `std::io::BufWriter`
- pub(super) fn write_to_buf(self: Pin<&mut Self>, buf: &[u8]) -> usize {
- let available = self.spare_capacity();
- let amt_to_buffer = available.min(buf.len());
-
- // SAFETY: `amt_to_buffer` is <= buffer's spare capacity by construction.
- unsafe {
- self.write_to_buffer_unchecked(&buf[..amt_to_buffer]);
- }
-
- amt_to_buffer
- }
-
- /// Write byte slice directly into `self.buf`
- ///
- /// Based on `std::io::BufWriter`
- #[inline]
- unsafe fn write_to_buffer_unchecked(self: Pin<&mut Self>, buf: &[u8]) {
- debug_assert!(buf.len() <= self.spare_capacity());
- let this = self.project();
- let old_len = this.buf.len();
- let buf_len = buf.len();
- let src = buf.as_ptr();
- let dst = this.buf.as_mut_ptr().add(old_len);
- ptr::copy_nonoverlapping(src, dst, buf_len);
- this.buf.set_len(old_len + buf_len);
- }
-
- /// Write directly using `inner`, bypassing buffering
- pub(super) fn inner_poll_write(
- self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- buf: &[u8],
- ) -> Poll<io::Result<usize>> {
- self.project().inner.poll_write(cx, buf)
- }
-
- /// Write directly using `inner`, bypassing buffering
- pub(super) fn inner_poll_write_vectored(
- self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- bufs: &[IoSlice<'_>],
- ) -> Poll<io::Result<usize>> {
- self.project().inner.poll_write_vectored(cx, bufs)
- }
}
impl<W: AsyncWrite> AsyncWrite for BufWriter<W> {
diff --git a/src/io/chain.rs b/src/io/chain.rs
index 728a3d2..1b6a335 100644
--- a/src/io/chain.rs
+++ b/src/io/chain.rs
@@ -1,5 +1,7 @@
use futures_core::ready;
use futures_core::task::{Context, Poll};
+#[cfg(feature = "read-initializer")]
+use futures_io::Initializer;
use futures_io::{AsyncBufRead, AsyncRead, IoSliceMut};
use pin_project_lite::pin_project;
use std::fmt;
@@ -24,7 +26,11 @@ where
U: AsyncRead,
{
pub(super) fn new(first: T, second: U) -> Self {
- Self { first, second, done_first: false }
+ Self {
+ first,
+ second,
+ done_first: false,
+ }
}
/// Gets references to the underlying readers in this `Chain`.
@@ -109,6 +115,16 @@ where
}
this.second.poll_read_vectored(cx, bufs)
}
+
+ #[cfg(feature = "read-initializer")]
+ unsafe fn initializer(&self) -> Initializer {
+ let initializer = self.first.initializer();
+ if initializer.should_initialize() {
+ initializer
+ } else {
+ self.second.initializer()
+ }
+ }
}
impl<T, U> AsyncBufRead for Chain<T, U>
diff --git a/src/io/copy.rs b/src/io/copy.rs
index c80add2..bc59255 100644
--- a/src/io/copy.rs
+++ b/src/io/copy.rs
@@ -1,10 +1,10 @@
-use super::{copy_buf, BufReader, CopyBuf};
use futures_core::future::Future;
use futures_core::task::{Context, Poll};
use futures_io::{AsyncRead, AsyncWrite};
-use pin_project_lite::pin_project;
use std::io;
use std::pin::Pin;
+use super::{BufReader, copy_buf, CopyBuf};
+use pin_project_lite::pin_project;
/// Creates a future which copies all the bytes from one object to another.
///
@@ -36,7 +36,9 @@ where
R: AsyncRead,
W: AsyncWrite + Unpin + ?Sized,
{
- Copy { inner: copy_buf(BufReader::new(reader), writer) }
+ Copy {
+ inner: copy_buf(BufReader::new(reader), writer),
+ }
}
pin_project! {
diff --git a/src/io/copy_buf.rs b/src/io/copy_buf.rs
index 50f7abd..6adf594 100644
--- a/src/io/copy_buf.rs
+++ b/src/io/copy_buf.rs
@@ -2,9 +2,9 @@ use futures_core::future::Future;
use futures_core::ready;
use futures_core::task::{Context, Poll};
use futures_io::{AsyncBufRead, AsyncWrite};
-use pin_project_lite::pin_project;
use std::io;
use std::pin::Pin;
+use pin_project_lite::pin_project;
/// Creates a future which copies all the bytes from one object to another.
///
@@ -36,7 +36,11 @@ where
R: AsyncBufRead,
W: AsyncWrite + Unpin + ?Sized,
{
- CopyBuf { reader, writer, amt: 0 }
+ CopyBuf {
+ reader,
+ writer,
+ amt: 0,
+ }
}
pin_project! {
@@ -52,9 +56,8 @@ pin_project! {
}
impl<R, W> Future for CopyBuf<'_, R, W>
-where
- R: AsyncBufRead,
- W: AsyncWrite + Unpin + ?Sized,
+ where R: AsyncBufRead,
+ W: AsyncWrite + Unpin + ?Sized,
{
type Output = io::Result<u64>;
@@ -69,7 +72,7 @@ where
let i = ready!(Pin::new(&mut this.writer).poll_write(cx, buffer))?;
if i == 0 {
- return Poll::Ready(Err(io::ErrorKind::WriteZero.into()));
+ return Poll::Ready(Err(io::ErrorKind::WriteZero.into()))
}
*this.amt += i as u64;
this.reader.as_mut().consume(i);
diff --git a/src/io/cursor.rs b/src/io/cursor.rs
index b6fb372..084fb08 100644
--- a/src/io/cursor.rs
+++ b/src/io/cursor.rs
@@ -43,7 +43,9 @@ impl<T> Cursor<T> {
/// # force_inference(&buff);
/// ```
pub fn new(inner: T) -> Self {
- Self { inner: io::Cursor::new(inner) }
+ Self {
+ inner: io::Cursor::new(inner),
+ }
}
/// Consumes this cursor, returning the underlying value.
@@ -197,19 +199,15 @@ where
macro_rules! delegate_async_write_to_stdio {
() => {
- fn poll_write(
- mut self: Pin<&mut Self>,
- _: &mut Context<'_>,
- buf: &[u8],
- ) -> Poll<io::Result<usize>> {
+ fn poll_write(mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &[u8])
+ -> Poll<io::Result<usize>>
+ {
Poll::Ready(io::Write::write(&mut self.inner, buf))
}
- fn poll_write_vectored(
- mut self: Pin<&mut Self>,
- _: &mut Context<'_>,
- bufs: &[IoSlice<'_>],
- ) -> Poll<io::Result<usize>> {
+ fn poll_write_vectored(mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &[IoSlice<'_>])
+ -> Poll<io::Result<usize>>
+ {
Poll::Ready(io::Write::write_vectored(&mut self.inner, bufs))
}
@@ -220,7 +218,7 @@ macro_rules! delegate_async_write_to_stdio {
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.poll_flush(cx)
}
- };
+ }
}
impl AsyncWrite for Cursor<&mut [u8]> {
diff --git a/src/io/empty.rs b/src/io/empty.rs
index 02f6103..ab2395a 100644
--- a/src/io/empty.rs
+++ b/src/io/empty.rs
@@ -1,4 +1,6 @@
use futures_core::task::{Context, Poll};
+#[cfg(feature = "read-initializer")]
+use futures_io::Initializer;
use futures_io::{AsyncBufRead, AsyncRead};
use std::fmt;
use std::io;
@@ -41,6 +43,12 @@ impl AsyncRead for Empty {
) -> Poll<io::Result<usize>> {
Poll::Ready(Ok(0))
}
+
+ #[cfg(feature = "read-initializer")]
+ #[inline]
+ unsafe fn initializer(&self) -> Initializer {
+ Initializer::nop()
+ }
}
impl AsyncBufRead for Empty {
diff --git a/src/io/fill_buf.rs b/src/io/fill_buf.rs
index a1484c0..6fb3ec7 100644
--- a/src/io/fill_buf.rs
+++ b/src/io/fill_buf.rs
@@ -20,8 +20,7 @@ impl<'a, R: AsyncBufRead + ?Sized + Unpin> FillBuf<'a, R> {
}
impl<'a, R> Future for FillBuf<'a, R>
-where
- R: AsyncBufRead + ?Sized + Unpin,
+ where R: AsyncBufRead + ?Sized + Unpin,
{
type Output = io::Result<&'a [u8]>;
@@ -30,7 +29,7 @@ where
let reader = this.reader.take().expect("Polled FillBuf after completion");
match Pin::new(&mut *reader).poll_fill_buf(cx) {
- // With polonius it is possible to remove this inner match and just have the correct
+ // With polinius it is possible to remove this inner match and just have the correct
// lifetime of the reference inferred based on which branch is taken
Poll::Ready(Ok(_)) => match Pin::new(reader).poll_fill_buf(cx) {
Poll::Ready(Ok(slice)) => Poll::Ready(Ok(slice)),
diff --git a/src/io/flush.rs b/src/io/flush.rs
index b75d14c..ece0a7c 100644
--- a/src/io/flush.rs
+++ b/src/io/flush.rs
@@ -20,8 +20,7 @@ impl<'a, W: AsyncWrite + ?Sized + Unpin> Flush<'a, W> {
}
impl<W> Future for Flush<'_, W>
-where
- W: AsyncWrite + ?Sized + Unpin,
+ where W: AsyncWrite + ?Sized + Unpin,
{
type Output = io::Result<()>;
diff --git a/src/io/into_sink.rs b/src/io/into_sink.rs
index 6a41ee2..885ba2f 100644
--- a/src/io/into_sink.rs
+++ b/src/io/into_sink.rs
@@ -2,9 +2,9 @@ use futures_core::ready;
use futures_core::task::{Context, Poll};
use futures_io::AsyncWrite;
use futures_sink::Sink;
-use pin_project_lite::pin_project;
use std::io;
use std::pin::Pin;
+use pin_project_lite::pin_project;
#[derive(Debug)]
struct Block<Item> {
@@ -36,7 +36,8 @@ impl<W: AsyncWrite, Item: AsRef<[u8]>> IntoSink<W, Item> {
fn poll_flush_buffer(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
- ) -> Poll<Result<(), io::Error>> {
+ ) -> Poll<Result<(), io::Error>>
+ {
let mut this = self.project();
if let Some(buffer) = this.buffer {
@@ -52,29 +53,47 @@ impl<W: AsyncWrite, Item: AsRef<[u8]>> IntoSink<W, Item> {
*this.buffer = None;
Poll::Ready(Ok(()))
}
+
}
impl<W: AsyncWrite, Item: AsRef<[u8]>> Sink<Item> for IntoSink<W, Item> {
type Error = io::Error;
- fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_ready(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>>
+ {
ready!(self.poll_flush_buffer(cx))?;
Poll::Ready(Ok(()))
}
- fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
+ #[allow(clippy::debug_assert_with_mut_call)]
+ fn start_send(
+ self: Pin<&mut Self>,
+ item: Item,
+ ) -> Result<(), Self::Error>
+ {
debug_assert!(self.buffer.is_none());
*self.project().buffer = Some(Block { offset: 0, bytes: item });
Ok(())
}
- fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_flush(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>>
+ {
ready!(self.as_mut().poll_flush_buffer(cx))?;
ready!(self.project().writer.poll_flush(cx))?;
Poll::Ready(Ok(()))
}
- fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_close(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>>
+ {
ready!(self.as_mut().poll_flush_buffer(cx))?;
ready!(self.project().writer.poll_close(cx))?;
Poll::Ready(Ok(()))
diff --git a/src/io/line_writer.rs b/src/io/line_writer.rs
deleted file mode 100644
index 71cd668..0000000
--- a/src/io/line_writer.rs
+++ /dev/null
@@ -1,155 +0,0 @@
-use super::buf_writer::BufWriter;
-use futures_core::ready;
-use futures_core::task::{Context, Poll};
-use futures_io::AsyncWrite;
-use futures_io::IoSlice;
-use pin_project_lite::pin_project;
-use std::io;
-use std::pin::Pin;
-
-pin_project! {
-/// Wrap a writer, like [`BufWriter`] does, but prioritizes buffering lines
-///
-/// This was written based on `std::io::LineWriter` which goes into further details
-/// explaining the code.
-///
-/// Buffering is actually done using `BufWriter`. This class will leverage `BufWriter`
-/// to write on-each-line.
-#[derive(Debug)]
-pub struct LineWriter<W: AsyncWrite> {
- #[pin]
- buf_writer: BufWriter<W>,
-}
-}
-
-impl<W: AsyncWrite> LineWriter<W> {
- /// Create a new `LineWriter` with default buffer capacity. The default is currently 1KB
- /// which was taken from `std::io::LineWriter`
- pub fn new(inner: W) -> LineWriter<W> {
- LineWriter::with_capacity(1024, inner)
- }
-
- /// Creates a new `LineWriter` with the specified buffer capacity.
- pub fn with_capacity(capacity: usize, inner: W) -> LineWriter<W> {
- LineWriter { buf_writer: BufWriter::with_capacity(capacity, inner) }
- }
-
- /// Flush `buf_writer` if last char is "new line"
- fn flush_if_completed_line(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
- let this = self.project();
- match this.buf_writer.buffer().last().copied() {
- Some(b'\n') => this.buf_writer.flush_buf(cx),
- _ => Poll::Ready(Ok(())),
- }
- }
-
- /// Returns a reference to `buf_writer`'s internally buffered data.
- pub fn buffer(&self) -> &[u8] {
- self.buf_writer.buffer()
- }
-
- /// Acquires a reference to the underlying sink or stream that this combinator is
- /// pulling from.
- pub fn get_ref(&self) -> &W {
- self.buf_writer.get_ref()
- }
-}
-
-impl<W: AsyncWrite> AsyncWrite for LineWriter<W> {
- fn poll_write(
- mut self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- buf: &[u8],
- ) -> Poll<io::Result<usize>> {
- let mut this = self.as_mut().project();
- let newline_index = match memchr::memrchr(b'\n', buf) {
- None => {
- ready!(self.as_mut().flush_if_completed_line(cx)?);
- return self.project().buf_writer.poll_write(cx, buf);
- }
- Some(newline_index) => newline_index + 1,
- };
-
- ready!(this.buf_writer.as_mut().poll_flush(cx)?);
-
- let lines = &buf[..newline_index];
-
- let flushed = { ready!(this.buf_writer.as_mut().inner_poll_write(cx, lines))? };
-
- if flushed == 0 {
- return Poll::Ready(Ok(0));
- }
-
- let tail = if flushed >= newline_index {
- &buf[flushed..]
- } else if newline_index - flushed <= this.buf_writer.capacity() {
- &buf[flushed..newline_index]
- } else {
- let scan_area = &buf[flushed..];
- let scan_area = &scan_area[..this.buf_writer.capacity()];
- match memchr::memrchr(b'\n', scan_area) {
- Some(newline_index) => &scan_area[..newline_index + 1],
- None => scan_area,
- }
- };
-
- let buffered = this.buf_writer.as_mut().write_to_buf(tail);
- Poll::Ready(Ok(flushed + buffered))
- }
-
- fn poll_write_vectored(
- mut self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- bufs: &[IoSlice<'_>],
- ) -> Poll<io::Result<usize>> {
- let mut this = self.as_mut().project();
- // `is_write_vectored()` is handled in original code, but not in this crate
- // see https://github.com/rust-lang/rust/issues/70436
-
- let last_newline_buf_idx = bufs
- .iter()
- .enumerate()
- .rev()
- .find_map(|(i, buf)| memchr::memchr(b'\n', buf).map(|_| i));
- let last_newline_buf_idx = match last_newline_buf_idx {
- None => {
- ready!(self.as_mut().flush_if_completed_line(cx)?);
- return self.project().buf_writer.poll_write_vectored(cx, bufs);
- }
- Some(i) => i,
- };
-
- ready!(this.buf_writer.as_mut().poll_flush(cx)?);
-
- let (lines, tail) = bufs.split_at(last_newline_buf_idx + 1);
-
- let flushed = { ready!(this.buf_writer.as_mut().inner_poll_write_vectored(cx, lines))? };
- if flushed == 0 {
- return Poll::Ready(Ok(0));
- }
-
- let lines_len = lines.iter().map(|buf| buf.len()).sum();
- if flushed < lines_len {
- return Poll::Ready(Ok(flushed));
- }
-
- let buffered: usize = tail
- .iter()
- .filter(|buf| !buf.is_empty())
- .map(|buf| this.buf_writer.as_mut().write_to_buf(buf))
- .take_while(|&n| n > 0)
- .sum();
-
- Poll::Ready(Ok(flushed + buffered))
- }
-
- /// Forward to `buf_writer` 's `BufWriter::poll_flush()`
- fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
- self.as_mut().project().buf_writer.poll_flush(cx)
- }
-
- /// Forward to `buf_writer` 's `BufWriter::poll_close()`
- fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
- self.as_mut().project().buf_writer.poll_close(cx)
- }
-}
diff --git a/src/io/lines.rs b/src/io/lines.rs
index 13e70df..6ae7392 100644
--- a/src/io/lines.rs
+++ b/src/io/lines.rs
@@ -1,12 +1,12 @@
-use super::read_line::read_line_internal;
use futures_core::ready;
use futures_core::stream::Stream;
use futures_core::task::{Context, Poll};
use futures_io::AsyncBufRead;
-use pin_project_lite::pin_project;
use std::io;
use std::mem;
use std::pin::Pin;
+use super::read_line::read_line_internal;
+use pin_project_lite::pin_project;
pin_project! {
/// Stream for the [`lines`](super::AsyncBufReadExt::lines) method.
@@ -23,7 +23,12 @@ pin_project! {
impl<R: AsyncBufRead> Lines<R> {
pub(super) fn new(reader: R) -> Self {
- Self { reader, buf: String::new(), bytes: Vec::new(), read: 0 }
+ Self {
+ reader,
+ buf: String::new(),
+ bytes: Vec::new(),
+ read: 0,
+ }
}
}
@@ -34,7 +39,7 @@ impl<R: AsyncBufRead> Stream for Lines<R> {
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);
+ return Poll::Ready(None)
}
if this.buf.ends_with('\n') {
this.buf.pop();
diff --git a/src/io/mod.rs b/src/io/mod.rs
index 4dd2e02..1437930 100644
--- a/src/io/mod.rs
+++ b/src/io/mod.rs
@@ -21,14 +21,18 @@
use crate::compat::Compat;
use crate::future::assert_future;
use crate::stream::assert_stream;
-use std::{pin::Pin, ptr};
+use std::{ptr, pin::Pin};
// Re-export some types from `std::io` so that users don't have to deal
// with conflicts when `use`ing `futures::io` and `std::io`.
#[doc(no_inline)]
pub use std::io::{Error, ErrorKind, IoSlice, IoSliceMut, Result, SeekFrom};
+#[doc(no_inline)]
+#[cfg(feature = "read-initializer")]
+#[cfg_attr(docsrs, doc(cfg(feature = "read-initializer")))]
+pub use std::io::Initializer;
-pub use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite};
+pub use futures_io::{AsyncRead, AsyncWrite, AsyncSeek, AsyncBufRead};
// used by `BufReader` and `BufWriter`
// https://github.com/rust-lang/rust/blob/master/src/libstd/sys_common/io.rs#L1
@@ -36,9 +40,15 @@ const DEFAULT_BUF_SIZE: usize = 8 * 1024;
/// Initializes a buffer if necessary.
///
-/// A buffer is currently always initialized.
+/// A buffer is always initialized if `read-initializer` feature is disabled.
#[inline]
unsafe fn initialize<R: AsyncRead>(_reader: &R, buf: &mut [u8]) {
+ #[cfg(feature = "read-initializer")]
+ {
+ if !_reader.initializer().should_initialize() {
+ return;
+ }
+ }
ptr::write_bytes(buf.as_mut_ptr(), 0, buf.len())
}
@@ -46,14 +56,11 @@ mod allow_std;
pub use self::allow_std::AllowStdIo;
mod buf_reader;
-pub use self::buf_reader::{BufReader, SeeKRelative};
+pub use self::buf_reader::BufReader;
mod buf_writer;
pub use self::buf_writer::BufWriter;
-mod line_writer;
-pub use self::line_writer::LineWriter;
-
mod chain;
pub use self::chain::Chain;
@@ -119,7 +126,7 @@ mod sink;
pub use self::sink::{sink, Sink};
mod split;
-pub use self::split::{ReadHalf, ReuniteError, WriteHalf};
+pub use self::split::{ReadHalf, WriteHalf, ReuniteError};
mod take;
pub use self::take::Take;
@@ -199,8 +206,7 @@ pub trait AsyncReadExt: AsyncRead {
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>
- where
- Self: Unpin,
+ where Self: Unpin,
{
assert_future::<Result<usize>, _>(Read::new(self, buf))
}
@@ -211,8 +217,7 @@ pub trait AsyncReadExt: AsyncRead {
/// The returned future will resolve to the number of bytes read once the read
/// operation is completed.
fn read_vectored<'a>(&'a mut self, bufs: &'a mut [IoSliceMut<'a>]) -> ReadVectored<'a, Self>
- where
- Self: Unpin,
+ where Self: Unpin,
{
assert_future::<Result<usize>, _>(ReadVectored::new(self, bufs))
}
@@ -254,9 +259,11 @@ pub trait AsyncReadExt: AsyncRead {
/// assert_eq!(result.unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
/// # });
/// ```
- fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self>
- where
- Self: Unpin,
+ fn read_exact<'a>(
+ &'a mut self,
+ buf: &'a mut [u8],
+ ) -> ReadExact<'a, Self>
+ where Self: Unpin,
{
assert_future::<Result<()>, _>(ReadExact::new(self, buf))
}
@@ -280,9 +287,11 @@ pub trait AsyncReadExt: AsyncRead {
/// assert_eq!(output, vec![1, 2, 3, 4]);
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
- fn read_to_end<'a>(&'a mut self, buf: &'a mut Vec<u8>) -> ReadToEnd<'a, Self>
- where
- Self: Unpin,
+ fn read_to_end<'a>(
+ &'a mut self,
+ buf: &'a mut Vec<u8>,
+ ) -> ReadToEnd<'a, Self>
+ where Self: Unpin,
{
assert_future::<Result<usize>, _>(ReadToEnd::new(self, buf))
}
@@ -306,9 +315,11 @@ pub trait AsyncReadExt: AsyncRead {
/// assert_eq!(buffer, String::from("1234"));
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
- fn read_to_string<'a>(&'a mut self, buf: &'a mut String) -> ReadToString<'a, Self>
- where
- Self: Unpin,
+ fn read_to_string<'a>(
+ &'a mut self,
+ buf: &'a mut String,
+ ) -> ReadToString<'a, Self>
+ where Self: Unpin,
{
assert_future::<Result<usize>, _>(ReadToString::new(self, buf))
}
@@ -343,8 +354,7 @@ pub trait AsyncReadExt: AsyncRead {
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn split(self) -> (ReadHalf<Self>, WriteHalf<Self>)
- where
- Self: AsyncWrite + Sized,
+ where Self: AsyncWrite + Sized,
{
let (r, w) = split::split(self);
(assert_read(r), assert_write(w))
@@ -370,8 +380,7 @@ pub trait AsyncReadExt: AsyncRead {
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn take(self, limit: u64) -> Take<Self>
- where
- Self: Sized,
+ where Self: Sized
{
assert_read(Take::new(self, limit))
}
@@ -385,8 +394,7 @@ pub trait AsyncReadExt: AsyncRead {
#[cfg(feature = "io-compat")]
#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
fn compat(self) -> Compat<Self>
- where
- Self: Sized + Unpin,
+ where Self: Sized + Unpin,
{
Compat::new(self)
}
@@ -419,16 +427,14 @@ pub trait AsyncWriteExt: AsyncWrite {
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn flush(&mut self) -> Flush<'_, Self>
- where
- Self: Unpin,
+ where Self: Unpin,
{
assert_future::<Result<()>, _>(Flush::new(self))
}
/// Creates a future which will entirely close this `AsyncWrite`.
fn close(&mut self) -> Close<'_, Self>
- where
- Self: Unpin,
+ where Self: Unpin,
{
assert_future::<Result<()>, _>(Close::new(self))
}
@@ -438,8 +444,7 @@ pub trait AsyncWriteExt: AsyncWrite {
/// The returned future will resolve to the number of bytes written once the write
/// operation is completed.
fn write<'a>(&'a mut self, buf: &'a [u8]) -> Write<'a, Self>
- where
- Self: Unpin,
+ where Self: Unpin,
{
assert_future::<Result<usize>, _>(Write::new(self, buf))
}
@@ -450,8 +455,7 @@ pub trait AsyncWriteExt: AsyncWrite {
/// The returned future will resolve to the number of bytes written once the write
/// operation is completed.
fn write_vectored<'a>(&'a mut self, bufs: &'a [IoSlice<'a>]) -> WriteVectored<'a, Self>
- where
- Self: Unpin,
+ where Self: Unpin,
{
assert_future::<Result<usize>, _>(WriteVectored::new(self, bufs))
}
@@ -477,8 +481,7 @@ pub trait AsyncWriteExt: AsyncWrite {
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> WriteAll<'a, Self>
- where
- Self: Unpin,
+ where Self: Unpin,
{
assert_future::<Result<()>, _>(WriteAll::new(self, buf))
}
@@ -544,8 +547,7 @@ pub trait AsyncWriteExt: AsyncWrite {
#[cfg(feature = "io-compat")]
#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
fn compat_write(self) -> Compat<Self>
- where
- Self: Sized + Unpin,
+ where Self: Sized + Unpin,
{
Compat::new(self)
}
@@ -579,8 +581,7 @@ pub trait AsyncWriteExt: AsyncWrite {
#[cfg(feature = "sink")]
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
fn into_sink<Item: AsRef<[u8]>>(self) -> IntoSink<Self, Item>
- where
- Self: Sized,
+ where Self: Sized,
{
crate::sink::assert_sink::<Item, Error, _>(IntoSink::new(self))
}
@@ -596,22 +597,10 @@ pub trait AsyncSeekExt: AsyncSeek {
/// In the case of an error the buffer and the object will be discarded, with
/// the error yielded.
fn seek(&mut self, pos: SeekFrom) -> Seek<'_, Self>
- where
- Self: Unpin,
+ where Self: Unpin,
{
assert_future::<Result<u64>, _>(Seek::new(self, pos))
}
-
- /// Creates a future which will return the current seek position from the
- /// start of the stream.
- ///
- /// This is equivalent to `self.seek(SeekFrom::Current(0))`.
- fn stream_position(&mut self) -> Seek<'_, Self>
- where
- Self: Unpin,
- {
- self.seek(SeekFrom::Current(0))
- }
}
impl<S: AsyncSeek + ?Sized> AsyncSeekExt for S {}
@@ -642,8 +631,7 @@ pub trait AsyncBufReadExt: AsyncBufRead {
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn fill_buf(&mut self) -> FillBuf<'_, Self>
- where
- Self: Unpin,
+ where Self: Unpin,
{
assert_future::<Result<&[u8]>, _>(FillBuf::new(self))
}
@@ -666,8 +654,7 @@ pub trait AsyncBufReadExt: AsyncBufRead {
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn consume_unpin(&mut self, amt: usize)
- where
- Self: Unpin,
+ where Self: Unpin,
{
Pin::new(self).consume(amt)
}
@@ -713,9 +700,12 @@ pub trait AsyncBufReadExt: AsyncBufRead {
/// assert_eq!(buf, b"");
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
- fn read_until<'a>(&'a mut self, byte: u8, buf: &'a mut Vec<u8>) -> ReadUntil<'a, Self>
- where
- Self: Unpin,
+ fn read_until<'a>(
+ &'a mut self,
+ byte: u8,
+ buf: &'a mut Vec<u8>,
+ ) -> ReadUntil<'a, Self>
+ where Self: Unpin,
{
assert_future::<Result<usize>, _>(ReadUntil::new(self, byte, buf))
}
@@ -772,8 +762,7 @@ pub trait AsyncBufReadExt: AsyncBufRead {
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn read_line<'a>(&'a mut self, buf: &'a mut String) -> ReadLine<'a, Self>
- where
- Self: Unpin,
+ where Self: Unpin,
{
assert_future::<Result<usize>, _>(ReadLine::new(self, buf))
}
@@ -811,8 +800,7 @@ pub trait AsyncBufReadExt: AsyncBufRead {
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn lines(self) -> Lines<Self>
- where
- Self: Sized,
+ where Self: Sized,
{
assert_stream::<Result<String>, _>(Lines::new(self))
}
diff --git a/src/io/read_exact.rs b/src/io/read_exact.rs
index 02e38c3..f2e0440 100644
--- a/src/io/read_exact.rs
+++ b/src/io/read_exact.rs
@@ -1,6 +1,6 @@
use crate::io::AsyncRead;
-use futures_core::future::Future;
use futures_core::ready;
+use futures_core::future::Future;
use futures_core::task::{Context, Poll};
use std::io;
use std::mem;
@@ -34,7 +34,7 @@ impl<R: AsyncRead + ?Sized + Unpin> Future for ReadExact<'_, R> {
this.buf = rest;
}
if n == 0 {
- return Poll::Ready(Err(io::ErrorKind::UnexpectedEof.into()));
+ return Poll::Ready(Err(io::ErrorKind::UnexpectedEof.into()))
}
}
Poll::Ready(Ok(()))
diff --git a/src/io/read_line.rs b/src/io/read_line.rs
index c75af94..d402c96 100644
--- a/src/io/read_line.rs
+++ b/src/io/read_line.rs
@@ -1,12 +1,12 @@
-use super::read_until::read_until_internal;
-use futures_core::future::Future;
use futures_core::ready;
+use futures_core::future::Future;
use futures_core::task::{Context, Poll};
use futures_io::AsyncBufRead;
use std::io;
use std::mem;
use std::pin::Pin;
use std::str;
+use super::read_until::read_until_internal;
/// Future for the [`read_line`](super::AsyncBufReadExt::read_line) method.
#[derive(Debug)]
@@ -22,7 +22,12 @@ impl<R: ?Sized + Unpin> Unpin for ReadLine<'_, R> {}
impl<'a, R: AsyncBufRead + ?Sized + Unpin> ReadLine<'a, R> {
pub(super) fn new(reader: &'a mut R, buf: &'a mut String) -> Self {
- Self { reader, bytes: mem::replace(buf, String::new()).into_bytes(), buf, read: 0 }
+ Self {
+ reader,
+ bytes: mem::replace(buf, String::new()).into_bytes(),
+ buf,
+ read: 0,
+ }
}
}
diff --git a/src/io/read_to_end.rs b/src/io/read_to_end.rs
index 919d7d1..7bd2c89 100644
--- a/src/io/read_to_end.rs
+++ b/src/io/read_to_end.rs
@@ -20,7 +20,11 @@ impl<R: ?Sized + Unpin> Unpin for ReadToEnd<'_, R> {}
impl<'a, R: AsyncRead + ?Sized + Unpin> ReadToEnd<'a, R> {
pub(super) fn new(reader: &'a mut R, buf: &'a mut Vec<u8>) -> Self {
let start_len = buf.len();
- Self { reader, buf, start_len }
+ Self {
+ reader,
+ buf,
+ start_len,
+ }
}
}
@@ -52,7 +56,10 @@ pub(super) fn read_to_end_internal<R: AsyncRead + ?Sized>(
buf: &mut Vec<u8>,
start_len: usize,
) -> Poll<io::Result<usize>> {
- let mut g = Guard { len: buf.len(), buf };
+ let mut g = Guard {
+ len: buf.len(),
+ buf,
+ };
loop {
if g.len == g.buf.len() {
unsafe {
diff --git a/src/io/read_to_string.rs b/src/io/read_to_string.rs
index 457af59..9242654 100644
--- a/src/io/read_to_string.rs
+++ b/src/io/read_to_string.rs
@@ -1,6 +1,6 @@
use super::read_to_end::read_to_end_internal;
-use futures_core::future::Future;
use futures_core::ready;
+use futures_core::future::Future;
use futures_core::task::{Context, Poll};
use futures_io::AsyncRead;
use std::pin::Pin;
@@ -22,7 +22,12 @@ impl<R: ?Sized + Unpin> Unpin for ReadToString<'_, R> {}
impl<'a, R: AsyncRead + ?Sized + Unpin> ReadToString<'a, R> {
pub(super) fn new(reader: &'a mut R, buf: &'a mut String) -> Self {
let start_len = buf.len();
- Self { reader, bytes: mem::replace(buf, String::new()).into_bytes(), buf, start_len }
+ Self {
+ reader,
+ bytes: mem::replace(buf, String::new()).into_bytes(),
+ buf,
+ start_len,
+ }
}
}
@@ -36,7 +41,10 @@ fn read_to_string_internal<R: AsyncRead + ?Sized>(
let ret = ready!(read_to_end_internal(reader, cx, bytes, start_len));
if str::from_utf8(bytes).is_err() {
Poll::Ready(ret.and_then(|_| {
- Err(io::Error::new(io::ErrorKind::InvalidData, "stream did not contain valid UTF-8"))
+ Err(io::Error::new(
+ io::ErrorKind::InvalidData,
+ "stream did not contain valid UTF-8",
+ ))
}))
} else {
debug_assert!(buf.is_empty());
diff --git a/src/io/repeat.rs b/src/io/repeat.rs
index 2828bf0..4cefcb2 100644
--- a/src/io/repeat.rs
+++ b/src/io/repeat.rs
@@ -1,5 +1,7 @@
use futures_core::ready;
use futures_core::task::{Context, Poll};
+#[cfg(feature = "read-initializer")]
+use futures_io::Initializer;
use futures_io::{AsyncRead, IoSliceMut};
use std::fmt;
use std::io;
@@ -57,6 +59,12 @@ impl AsyncRead for Repeat {
}
Poll::Ready(Ok(nwritten))
}
+
+ #[cfg(feature = "read-initializer")]
+ #[inline]
+ unsafe fn initializer(&self) -> Initializer {
+ Initializer::nop()
+ }
}
impl fmt::Debug for Repeat {
diff --git a/src/io/split.rs b/src/io/split.rs
index 3f1b9af..185c21c 100644
--- a/src/io/split.rs
+++ b/src/io/split.rs
@@ -1,8 +1,8 @@
use crate::lock::BiLock;
-use core::fmt;
use futures_core::ready;
use futures_core::task::{Context, Poll};
use futures_io::{AsyncRead, AsyncWrite, IoSlice, IoSliceMut};
+use core::fmt;
use std::io;
use std::pin::Pin;
@@ -18,9 +18,12 @@ pub struct WriteHalf<T> {
handle: BiLock<T>,
}
-fn lock_and_then<T, U, E, F>(lock: &BiLock<T>, cx: &mut Context<'_>, f: F) -> Poll<Result<U, E>>
-where
- F: FnOnce(Pin<&mut T>, &mut Context<'_>) -> Poll<Result<U, E>>,
+fn lock_and_then<T, U, E, F>(
+ lock: &BiLock<T>,
+ cx: &mut Context<'_>,
+ f: F
+) -> Poll<Result<U, E>>
+ where F: FnOnce(Pin<&mut T>, &mut Context<'_>) -> Poll<Result<U, E>>
{
let mut l = ready!(lock.poll_lock(cx));
f(l.as_pin_mut(), cx)
@@ -36,9 +39,9 @@ impl<T: Unpin> ReadHalf<T> {
/// together. Succeeds only if the `ReadHalf<T>` and `WriteHalf<T>` are
/// a matching pair originating from the same call to `AsyncReadExt::split`.
pub fn reunite(self, other: WriteHalf<T>) -> Result<T, ReuniteError<T>> {
- self.handle
- .reunite(other.handle)
- .map_err(|err| ReuniteError(ReadHalf { handle: err.0 }, WriteHalf { handle: err.1 }))
+ self.handle.reunite(other.handle).map_err(|err| {
+ ReuniteError(ReadHalf { handle: err.0 }, WriteHalf { handle: err.1 })
+ })
}
}
@@ -52,37 +55,29 @@ impl<T: Unpin> WriteHalf<T> {
}
impl<R: AsyncRead> AsyncRead for ReadHalf<R> {
- fn poll_read(
- self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- buf: &mut [u8],
- ) -> Poll<io::Result<usize>> {
+ fn poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8])
+ -> Poll<io::Result<usize>>
+ {
lock_and_then(&self.handle, cx, |l, cx| l.poll_read(cx, buf))
}
- fn poll_read_vectored(
- self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- bufs: &mut [IoSliceMut<'_>],
- ) -> Poll<io::Result<usize>> {
+ fn poll_read_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>])
+ -> Poll<io::Result<usize>>
+ {
lock_and_then(&self.handle, cx, |l, cx| l.poll_read_vectored(cx, bufs))
}
}
impl<W: AsyncWrite> AsyncWrite for WriteHalf<W> {
- fn poll_write(
- self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- buf: &[u8],
- ) -> Poll<io::Result<usize>> {
+ fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8])
+ -> Poll<io::Result<usize>>
+ {
lock_and_then(&self.handle, cx, |l, cx| l.poll_write(cx, buf))
}
- fn poll_write_vectored(
- self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- bufs: &[IoSlice<'_>],
- ) -> Poll<io::Result<usize>> {
+ fn poll_write_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>])
+ -> Poll<io::Result<usize>>
+ {
lock_and_then(&self.handle, cx, |l, cx| l.poll_write_vectored(cx, bufs))
}
@@ -101,7 +96,9 @@ pub struct ReuniteError<T>(pub ReadHalf<T>, pub WriteHalf<T>);
impl<T> fmt::Debug for ReuniteError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_tuple("ReuniteError").field(&"...").finish()
+ f.debug_tuple("ReuniteError")
+ .field(&"...")
+ .finish()
}
}
diff --git a/src/io/take.rs b/src/io/take.rs
index 2c49480..687a697 100644
--- a/src/io/take.rs
+++ b/src/io/take.rs
@@ -1,9 +1,11 @@
use futures_core::ready;
use futures_core::task::{Context, Poll};
-use futures_io::{AsyncBufRead, AsyncRead};
+#[cfg(feature = "read-initializer")]
+use futures_io::Initializer;
+use futures_io::{AsyncRead, AsyncBufRead};
use pin_project_lite::pin_project;
-use std::pin::Pin;
use std::{cmp, io};
+use std::pin::Pin;
pin_project! {
/// Reader for the [`take`](super::AsyncReadExt::take) method.
@@ -12,13 +14,14 @@ pin_project! {
pub struct Take<R> {
#[pin]
inner: R,
- limit: u64,
+ // Add '_' to avoid conflicts with `limit` method.
+ limit_: u64,
}
}
impl<R: AsyncRead> Take<R> {
pub(super) fn new(inner: R, limit: u64) -> Self {
- Self { inner, limit }
+ Self { inner, limit_: limit }
}
/// Returns the remaining number of bytes that can be
@@ -45,7 +48,7 @@ impl<R: AsyncRead> Take<R> {
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
pub fn limit(&self) -> u64 {
- self.limit
+ self.limit_
}
/// Sets the number of bytes that can be read before this instance will
@@ -75,7 +78,7 @@ impl<R: AsyncRead> Take<R> {
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
pub fn set_limit(&mut self, limit: u64) {
- self.limit = limit
+ self.limit_ = limit
}
delegate_access_inner!(inner, R, ());
@@ -89,15 +92,20 @@ impl<R: AsyncRead> AsyncRead for Take<R> {
) -> Poll<Result<usize, io::Error>> {
let this = self.project();
- if *this.limit == 0 {
+ if *this.limit_ == 0 {
return Poll::Ready(Ok(0));
}
- let max = cmp::min(buf.len() as u64, *this.limit) as usize;
+ let max = cmp::min(buf.len() as u64, *this.limit_) as usize;
let n = ready!(this.inner.poll_read(cx, &mut buf[..max]))?;
- *this.limit -= n as u64;
+ *this.limit_ -= n as u64;
Poll::Ready(Ok(n))
}
+
+ #[cfg(feature = "read-initializer")]
+ unsafe fn initializer(&self) -> Initializer {
+ self.inner.initializer()
+ }
}
impl<R: AsyncBufRead> AsyncBufRead for Take<R> {
@@ -105,12 +113,12 @@ impl<R: AsyncBufRead> AsyncBufRead for Take<R> {
let this = self.project();
// Don't call into inner reader at all at EOF because it may still block
- if *this.limit == 0 {
+ if *this.limit_ == 0 {
return Poll::Ready(Ok(&[]));
}
let buf = ready!(this.inner.poll_fill_buf(cx)?);
- let cap = cmp::min(buf.len() as u64, *this.limit) as usize;
+ let cap = cmp::min(buf.len() as u64, *this.limit_) as usize;
Poll::Ready(Ok(&buf[..cap]))
}
@@ -118,8 +126,8 @@ impl<R: AsyncBufRead> AsyncBufRead for Take<R> {
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;
+ let amt = cmp::min(amt as u64, *this.limit_) as usize;
+ *this.limit_ -= amt as u64;
this.inner.consume(amt);
}
}
diff --git a/src/io/window.rs b/src/io/window.rs
index 77b7267..3424197 100644
--- a/src/io/window.rs
+++ b/src/io/window.rs
@@ -30,7 +30,10 @@ impl<T: AsRef<[u8]>> Window<T> {
/// Further methods can be called on the returned `Window<T>` to alter the
/// window into the data provided.
pub fn new(t: T) -> Self {
- Self { range: 0..t.as_ref().len(), inner: t }
+ Self {
+ range: 0..t.as_ref().len(),
+ inner: t,
+ }
}
/// Gets a shared reference to the underlying buffer inside of this
diff --git a/src/io/write_all_vectored.rs b/src/io/write_all_vectored.rs
index a8fc4c6..380604d 100644
--- a/src/io/write_all_vectored.rs
+++ b/src/io/write_all_vectored.rs
@@ -1,9 +1,10 @@
-use futures_core::future::Future;
use futures_core::ready;
+use futures_core::future::Future;
use futures_core::task::{Context, Poll};
use futures_io::AsyncWrite;
use futures_io::IoSlice;
use std::io;
+use std::mem;
use std::pin::Pin;
/// Future for the
@@ -18,9 +19,8 @@ pub struct WriteAllVectored<'a, W: ?Sized + Unpin> {
impl<W: ?Sized + Unpin> Unpin for WriteAllVectored<'_, W> {}
impl<'a, W: AsyncWrite + ?Sized + Unpin> WriteAllVectored<'a, W> {
- pub(super) fn new(writer: &'a mut W, mut bufs: &'a mut [IoSlice<'a>]) -> Self {
- IoSlice::advance_slices(&mut bufs, 0);
- Self { writer, bufs }
+ pub(super) fn new(writer: &'a mut W, bufs: &'a mut [IoSlice<'a>]) -> Self {
+ Self { writer, bufs: IoSlice::advance(bufs, 0) }
}
}
@@ -34,7 +34,7 @@ impl<W: AsyncWrite + ?Sized + Unpin> Future for WriteAllVectored<'_, W> {
if n == 0 {
return Poll::Ready(Err(io::ErrorKind::WriteZero.into()));
} else {
- IoSlice::advance_slices(&mut this.bufs, n);
+ this.bufs = IoSlice::advance(mem::take(&mut this.bufs), n);
}
}
@@ -56,7 +56,11 @@ mod tests {
/// Create a new writer that reads from at most `n_bufs` and reads
/// `per_call` bytes (in total) per call to write.
fn test_writer(n_bufs: usize, per_call: usize) -> TestWriter {
- TestWriter { n_bufs, per_call, written: Vec::new() }
+ TestWriter {
+ n_bufs,
+ per_call,
+ written: Vec::new(),
+ }
}
// TODO: maybe move this the future-test crate?
@@ -106,9 +110,10 @@ mod tests {
let expected = $expected;
match $e {
Poll::Ready(Ok(ok)) if ok == expected => {}
- got => {
- panic!("unexpected result, got: {:?}, wanted: Ready(Ok({:?}))", got, expected)
- }
+ got => panic!(
+ "unexpected result, got: {:?}, wanted: Ready(Ok({:?}))",
+ got, expected
+ ),
}
};
}
@@ -149,7 +154,11 @@ mod tests {
assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, bufs), 3);
// Read at most 3 bytes from three buffers.
- let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4]), IoSlice::new(&[5, 5])];
+ let bufs = &[
+ IoSlice::new(&[3]),
+ IoSlice::new(&[4]),
+ IoSlice::new(&[5, 5]),
+ ];
assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, bufs), 3);
assert_eq!(dst.written, &[1, 2, 2, 3, 4, 5]);
diff --git a/src/lib.rs b/src/lib.rs
index 9a10c93..44823cc 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,27 +1,31 @@
//! Combinators and utilities for working with `Future`s, `Stream`s, `Sink`s,
//! and the `AsyncRead` and `AsyncWrite` traits.
+#![cfg_attr(feature = "cfg-target-has-atomic", feature(cfg_target_has_atomic))]
+#![cfg_attr(feature = "read-initializer", feature(read_initializer))]
#![cfg_attr(feature = "write-all-vectored", feature(io_slice_advance))]
#![cfg_attr(not(feature = "std"), no_std)]
#![warn(
- missing_debug_implementations,
missing_docs,
+ missing_debug_implementations,
rust_2018_idioms,
- single_use_lifetimes,
unreachable_pub
)]
-#![doc(test(
- no_crate_inject,
- attr(
- deny(warnings, rust_2018_idioms, single_use_lifetimes),
- allow(dead_code, unused_assignments, unused_variables)
- )
-))]
+// It cannot be included in the published code because this lints have false positives in the minimum required version.
+#![cfg_attr(test, warn(single_use_lifetimes))]
+#![warn(clippy::all)]
+#![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))]
#![cfg_attr(docsrs, feature(doc_cfg))]
+#[cfg(all(feature = "cfg-target-has-atomic", not(feature = "unstable")))]
+compile_error!("The `cfg-target-has-atomic` feature requires the `unstable` feature as an explicit opt-in to unstable features");
+
#[cfg(all(feature = "bilock", not(feature = "unstable")))]
compile_error!("The `bilock` feature requires the `unstable` feature as an explicit opt-in to unstable features");
+#[cfg(all(feature = "read-initializer", not(feature = "unstable")))]
+compile_error!("The `read-initializer` feature requires the `unstable` feature as an explicit opt-in to unstable features");
+
#[cfg(feature = "alloc")]
extern crate alloc;
@@ -52,6 +56,13 @@ pub mod __private {
}
}
+macro_rules! cfg_target_has_atomic {
+ ($($item:item)*) => {$(
+ #[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
+ $item
+ )*};
+}
+
#[cfg(feature = "sink")]
macro_rules! delegate_sink {
($field:ident, $item:ty) => {
@@ -144,6 +155,11 @@ macro_rules! delegate_async_write {
#[cfg(feature = "std")]
macro_rules! delegate_async_read {
($field:ident) => {
+ #[cfg(feature = "read-initializer")]
+ unsafe fn initializer(&self) -> $crate::io::Initializer {
+ self.$field.initializer()
+ }
+
fn poll_read(
self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
@@ -292,19 +308,19 @@ macro_rules! delegate_all {
}
pub mod future;
-#[doc(no_inline)]
-pub use crate::future::{Future, FutureExt, TryFuture, TryFutureExt};
+#[doc(hidden)]
+pub use crate::future::{FutureExt, TryFutureExt};
pub mod stream;
-#[doc(no_inline)]
-pub use crate::stream::{Stream, StreamExt, TryStream, TryStreamExt};
+#[doc(hidden)]
+pub use crate::stream::{StreamExt, TryStreamExt};
#[cfg(feature = "sink")]
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
pub mod sink;
#[cfg(feature = "sink")]
-#[doc(no_inline)]
-pub use crate::sink::{Sink, SinkExt};
+#[doc(hidden)]
+pub use crate::sink::SinkExt;
pub mod task;
@@ -320,18 +336,11 @@ pub mod compat;
pub mod io;
#[cfg(feature = "io")]
#[cfg(feature = "std")]
-#[doc(no_inline)]
-pub use crate::io::{
- AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, AsyncWrite,
- AsyncWriteExt,
-};
+#[doc(hidden)]
+pub use crate::io::{AsyncBufReadExt, AsyncReadExt, AsyncSeekExt, AsyncWriteExt};
#[cfg(feature = "alloc")]
pub mod lock;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-mod abortable;
-
mod fns;
mod unfold_state;
diff --git a/src/lock/bilock.rs b/src/lock/bilock.rs
index 2f51ae7..600e16e 100644
--- a/src/lock/bilock.rs
+++ b/src/lock/bilock.rs
@@ -1,16 +1,16 @@
//! Futures-powered synchronization primitives.
-use alloc::boxed::Box;
-use alloc::sync::Arc;
+#[cfg(feature = "bilock")]
+use futures_core::future::Future;
+use futures_core::task::{Context, Poll, Waker};
use core::cell::UnsafeCell;
use core::fmt;
use core::ops::{Deref, DerefMut};
use core::pin::Pin;
use core::sync::atomic::AtomicUsize;
use core::sync::atomic::Ordering::SeqCst;
-#[cfg(feature = "bilock")]
-use futures_core::future::Future;
-use futures_core::task::{Context, Poll, Waker};
+use alloc::boxed::Box;
+use alloc::sync::Arc;
/// A type of futures-powered synchronization primitive which is a mutex between
/// two possible owners.
@@ -61,7 +61,10 @@ impl<T> BiLock<T> {
/// Similarly, reuniting the lock and extracting the inner value is only
/// possible when `T` is `Unpin`.
pub fn new(t: T) -> (Self, Self) {
- let arc = Arc::new(Inner { state: AtomicUsize::new(0), value: Some(UnsafeCell::new(t)) });
+ let arc = Arc::new(Inner {
+ state: AtomicUsize::new(0),
+ value: Some(UnsafeCell::new(t)),
+ });
(Self { arc: arc.clone() }, Self { arc })
}
@@ -100,11 +103,11 @@ impl<T> BiLock<T> {
let mut prev = Box::from_raw(n as *mut Waker);
*prev = cx.waker().clone();
waker = Some(prev);
- },
+ }
}
// type ascription for safety's sake!
- let me: Box<Waker> = waker.take().unwrap_or_else(|| Box::new(cx.waker().clone()));
+ let me: Box<Waker> = waker.take().unwrap_or_else(||Box::new(cx.waker().clone()));
let me = Box::into_raw(me) as usize;
match self.arc.state.compare_exchange(1, me, SeqCst, SeqCst) {
@@ -142,7 +145,9 @@ impl<T> BiLock<T> {
#[cfg(feature = "bilock")]
#[cfg_attr(docsrs, doc(cfg(feature = "bilock")))]
pub fn lock(&self) -> BiLockAcquire<'_, T> {
- BiLockAcquire { bilock: self }
+ BiLockAcquire {
+ bilock: self,
+ }
}
/// Attempts to put the two "halves" of a `BiLock<T>` back together and
@@ -176,7 +181,7 @@ impl<T> BiLock<T> {
// up as its now their turn.
n => unsafe {
Box::from_raw(n as *mut Waker).wake();
- },
+ }
}
}
}
@@ -200,7 +205,9 @@ pub struct ReuniteError<T>(pub BiLock<T>, pub BiLock<T>);
impl<T> fmt::Debug for ReuniteError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_tuple("ReuniteError").field(&"...").finish()
+ f.debug_tuple("ReuniteError")
+ .field(&"...")
+ .finish()
}
}
diff --git a/src/lock/mod.rs b/src/lock/mod.rs
index cf374c0..071eef6 100644
--- a/src/lock/mod.rs
+++ b/src/lock/mod.rs
@@ -3,23 +3,20 @@
//! This module is only available when the `std` or `alloc` feature of this
//! library is activated, and it is activated by default.
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "std")]
-mod mutex;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "std")]
-pub use self::mutex::{MappedMutexGuard, Mutex, MutexGuard, MutexLockFuture};
+cfg_target_has_atomic! {
+ #[cfg(feature = "std")]
+ mod mutex;
+ #[cfg(feature = "std")]
+ pub use self::mutex::{MappedMutexGuard, Mutex, MutexLockFuture, MutexGuard};
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(any(feature = "bilock", feature = "sink", feature = "io"))]
-#[cfg_attr(docsrs, doc(cfg(feature = "bilock")))]
-#[cfg_attr(not(feature = "bilock"), allow(unreachable_pub))]
-mod bilock;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(any(feature = "sink", feature = "io"))]
-#[cfg(not(feature = "bilock"))]
-pub(crate) use self::bilock::BiLock;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "bilock")]
-#[cfg_attr(docsrs, doc(cfg(feature = "bilock")))]
-pub use self::bilock::{BiLock, BiLockAcquire, BiLockGuard, ReuniteError};
+ #[cfg(any(feature = "bilock", feature = "sink", feature = "io"))]
+ #[cfg_attr(docsrs, doc(cfg(feature = "bilock")))]
+ #[cfg_attr(not(feature = "bilock"), allow(unreachable_pub))]
+ mod bilock;
+ #[cfg(feature = "bilock")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "bilock")))]
+ pub use self::bilock::{BiLock, BiLockAcquire, BiLockGuard, ReuniteError};
+ #[cfg(any(feature = "sink", feature = "io"))]
+ #[cfg(not(feature = "bilock"))]
+ pub(crate) use self::bilock::BiLock;
+}
diff --git a/src/lock/mutex.rs b/src/lock/mutex.rs
index 85dcb15..a78de62 100644
--- a/src/lock/mutex.rs
+++ b/src/lock/mutex.rs
@@ -1,13 +1,13 @@
use futures_core::future::{FusedFuture, Future};
use futures_core::task::{Context, Poll, Waker};
use slab::Slab;
+use std::{fmt, mem};
use std::cell::UnsafeCell;
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use std::pin::Pin;
-use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Mutex as StdMutex;
-use std::{fmt, mem};
+use std::sync::atomic::{AtomicUsize, Ordering};
/// A futures-aware mutex.
///
@@ -53,7 +53,7 @@ enum Waiter {
impl Waiter {
fn register(&mut self, waker: &Waker) {
match self {
- Self::Waiting(w) if waker.will_wake(w) => {}
+ Self::Waiting(w) if waker.will_wake(w) => {},
_ => *self = Self::Waiting(waker.clone()),
}
}
@@ -61,11 +61,12 @@ impl Waiter {
fn wake(&mut self) {
match mem::replace(self, Self::Woken) {
Self::Waiting(waker) => waker.wake(),
- Self::Woken => {}
+ Self::Woken => {},
}
}
}
+#[allow(clippy::identity_op)] // https://github.com/rust-lang/rust-clippy/issues/3445
const IS_LOCKED: usize = 1 << 0;
const HAS_WAITERS: usize = 1 << 1;
@@ -112,7 +113,10 @@ impl<T: ?Sized> Mutex<T> {
/// This method returns a future that will resolve once the lock has been
/// successfully acquired.
pub fn lock(&self) -> MutexLockFuture<'_, T> {
- MutexLockFuture { mutex: Some(self), wait_key: WAIT_KEY_NONE }
+ MutexLockFuture {
+ mutex: Some(self),
+ wait_key: WAIT_KEY_NONE,
+ }
}
/// Returns a mutable reference to the underlying data.
@@ -141,7 +145,7 @@ impl<T: ?Sized> Mutex<T> {
if wait_key != WAIT_KEY_NONE {
let mut waiters = self.waiters.lock().unwrap();
match waiters.remove(wait_key) {
- Waiter::Waiting(_) => {}
+ Waiter::Waiting(_) => {},
Waiter::Woken => {
// We were awoken, but then dropped before we could
// wake up to acquire the lock. Wake up another
@@ -187,10 +191,13 @@ impl<T: ?Sized> fmt::Debug for MutexLockFuture<'_, T> {
f.debug_struct("MutexLockFuture")
.field("was_acquired", &self.mutex.is_none())
.field("mutex", &self.mutex)
- .field(
- "wait_key",
- &(if self.wait_key == WAIT_KEY_NONE { None } else { Some(self.wait_key) }),
- )
+ .field("wait_key", &(
+ if self.wait_key == WAIT_KEY_NONE {
+ None
+ } else {
+ Some(self.wait_key)
+ }
+ ))
.finish()
}
}
@@ -288,7 +295,10 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("MutexGuard").field("value", &&**self).field("mutex", &self.mutex).finish()
+ f.debug_struct("MutexGuard")
+ .field("value", &&**self)
+ .field("mutex", &self.mutex)
+ .finish()
}
}
diff --git a/src/sink/buffer.rs b/src/sink/buffer.rs
index 4aa6c36..8c58f4f 100644
--- a/src/sink/buffer.rs
+++ b/src/sink/buffer.rs
@@ -1,10 +1,10 @@
-use alloc::collections::VecDeque;
-use core::pin::Pin;
use futures_core::ready;
-use futures_core::stream::{FusedStream, Stream};
+use futures_core::stream::{Stream, FusedStream};
use futures_core::task::{Context, Poll};
use futures_sink::Sink;
use pin_project_lite::pin_project;
+use core::pin::Pin;
+use alloc::collections::VecDeque;
pin_project! {
/// Sink for the [`buffer`](super::SinkExt::buffer) method.
@@ -22,12 +22,19 @@ pin_project! {
impl<Si: Sink<Item>, Item> Buffer<Si, Item> {
pub(super) fn new(sink: Si, capacity: usize) -> Self {
- Self { sink, buf: VecDeque::with_capacity(capacity), capacity }
+ Self {
+ sink,
+ buf: VecDeque::with_capacity(capacity),
+ capacity,
+ }
}
delegate_access_inner!(sink, Si, ());
- fn try_empty_buffer(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Si::Error>> {
+ fn try_empty_buffer(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Si::Error>> {
let mut this = self.project();
ready!(this.sink.as_mut().poll_ready(cx))?;
while let Some(item) = this.buf.pop_front() {
@@ -41,10 +48,7 @@ impl<Si: Sink<Item>, Item> Buffer<Si, Item> {
}
// Forwarding impl of Stream from the underlying sink
-impl<S, Item> Stream for Buffer<S, Item>
-where
- S: Sink<Item> + Stream,
-{
+impl<S, Item> Stream for Buffer<S, Item> where S: Sink<Item> + Stream {
type Item = S::Item;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<S::Item>> {
@@ -56,10 +60,7 @@ where
}
}
-impl<S, Item> FusedStream for Buffer<S, Item>
-where
- S: Sink<Item> + FusedStream,
-{
+impl<S, Item> FusedStream for Buffer<S, Item> where S: Sink<Item> + FusedStream {
fn is_terminated(&self) -> bool {
self.sink.is_terminated()
}
@@ -68,7 +69,10 @@ where
impl<Si: Sink<Item>, Item> Sink<Item> for Buffer<Si, Item> {
type Error = Si::Error;
- fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_ready(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
if self.capacity == 0 {
return self.project().sink.poll_ready(cx);
}
@@ -82,7 +86,10 @@ impl<Si: Sink<Item>, Item> Sink<Item> for Buffer<Si, Item> {
}
}
- fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
+ fn start_send(
+ self: Pin<&mut Self>,
+ item: Item,
+ ) -> Result<(), Self::Error> {
if self.capacity == 0 {
self.project().sink.start_send(item)
} else {
@@ -91,13 +98,21 @@ impl<Si: Sink<Item>, Item> Sink<Item> for Buffer<Si, Item> {
}
}
- fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ #[allow(clippy::debug_assert_with_mut_call)]
+ fn poll_flush(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
ready!(self.as_mut().try_empty_buffer(cx))?;
debug_assert!(self.buf.is_empty());
self.project().sink.poll_flush(cx)
}
- fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ #[allow(clippy::debug_assert_with_mut_call)]
+ fn poll_close(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
ready!(self.as_mut().try_empty_buffer(cx))?;
debug_assert!(self.buf.is_empty());
self.project().sink.poll_close(cx)
diff --git a/src/sink/close.rs b/src/sink/close.rs
index 43eea74..4fc99f5 100644
--- a/src/sink/close.rs
+++ b/src/sink/close.rs
@@ -19,14 +19,20 @@ impl<Si: Unpin + ?Sized, Item> Unpin for Close<'_, Si, Item> {}
/// The sink itself is returned after closing is complete.
impl<'a, Si: Sink<Item> + Unpin + ?Sized, Item> Close<'a, Si, Item> {
pub(super) fn new(sink: &'a mut Si) -> Self {
- Self { sink, _phantom: PhantomData }
+ Self {
+ sink,
+ _phantom: PhantomData,
+ }
}
}
impl<Si: Sink<Item> + Unpin + ?Sized, Item> Future for Close<'_, Si, Item> {
type Output = Result<(), Si::Error>;
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ fn poll(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Self::Output> {
Pin::new(&mut self.sink).poll_close(cx)
}
}
diff --git a/src/sink/drain.rs b/src/sink/drain.rs
index 5295115..33c5b31 100644
--- a/src/sink/drain.rs
+++ b/src/sink/drain.rs
@@ -35,19 +35,31 @@ impl<T> Unpin for Drain<T> {}
impl<T> Sink<T> for Drain<T> {
type Error = Never;
- fn poll_ready(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_ready(
+ self: Pin<&mut Self>,
+ _cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
- fn start_send(self: Pin<&mut Self>, _item: T) -> Result<(), Self::Error> {
+ fn start_send(
+ self: Pin<&mut Self>,
+ _item: T,
+ ) -> Result<(), Self::Error> {
Ok(())
}
- fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_flush(
+ self: Pin<&mut Self>,
+ _cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
- fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_close(
+ self: Pin<&mut Self>,
+ _cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
}
diff --git a/src/sink/err_into.rs b/src/sink/err_into.rs
index a64d133..3eb9940 100644
--- a/src/sink/err_into.rs
+++ b/src/sink/err_into.rs
@@ -1,6 +1,6 @@
use crate::sink::{SinkExt, SinkMapErr};
-use futures_core::stream::{FusedStream, Stream};
-use futures_sink::Sink;
+use futures_core::stream::{Stream, FusedStream};
+use futures_sink::{Sink};
use pin_project_lite::pin_project;
pin_project! {
@@ -14,21 +14,21 @@ pin_project! {
}
impl<Si, E, Item> SinkErrInto<Si, Item, E>
-where
- Si: Sink<Item>,
- Si::Error: Into<E>,
+ where Si: Sink<Item>,
+ Si::Error: Into<E>,
{
pub(super) fn new(sink: Si) -> Self {
- Self { sink: SinkExt::sink_map_err(sink, Into::into) }
+ Self {
+ sink: SinkExt::sink_map_err(sink, Into::into),
+ }
}
delegate_access_inner!(sink, Si, (.));
}
impl<Si, Item, E> Sink<Item> for SinkErrInto<Si, Item, E>
-where
- Si: Sink<Item>,
- Si::Error: Into<E>,
+ where Si: Sink<Item>,
+ Si::Error: Into<E>,
{
type Error = E;
@@ -37,9 +37,8 @@ where
// Forwarding impl of Stream from the underlying sink
impl<S, Item, E> Stream for SinkErrInto<S, Item, E>
-where
- S: Sink<Item> + Stream,
- S::Error: Into<E>,
+ where S: Sink<Item> + Stream,
+ S::Error: Into<E>
{
type Item = S::Item;
@@ -47,9 +46,8 @@ where
}
impl<S, Item, E> FusedStream for SinkErrInto<S, Item, E>
-where
- S: Sink<Item> + FusedStream,
- S::Error: Into<E>,
+ where S: Sink<Item> + FusedStream,
+ S::Error: Into<E>
{
fn is_terminated(&self) -> bool {
self.sink.is_terminated()
diff --git a/src/sink/fanout.rs b/src/sink/fanout.rs
index fe2038f..f351e86 100644
--- a/src/sink/fanout.rs
+++ b/src/sink/fanout.rs
@@ -50,32 +50,36 @@ impl<Si1, Si2> Fanout<Si1, Si2> {
impl<Si1: Debug, Si2: Debug> Debug for Fanout<Si1, Si2> {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
- f.debug_struct("Fanout").field("sink1", &self.sink1).field("sink2", &self.sink2).finish()
+ f.debug_struct("Fanout")
+ .field("sink1", &self.sink1)
+ .field("sink2", &self.sink2)
+ .finish()
}
}
impl<Si1, Si2, Item> Sink<Item> for Fanout<Si1, Si2>
-where
- Si1: Sink<Item>,
- Item: Clone,
- Si2: Sink<Item, Error = Si1::Error>,
+ where Si1: Sink<Item>,
+ Item: Clone,
+ Si2: Sink<Item, Error=Si1::Error>
{
type Error = Si1::Error;
- fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_ready(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
let this = self.project();
let sink1_ready = this.sink1.poll_ready(cx)?.is_ready();
let sink2_ready = this.sink2.poll_ready(cx)?.is_ready();
let ready = sink1_ready && sink2_ready;
- if ready {
- Poll::Ready(Ok(()))
- } else {
- Poll::Pending
- }
+ if ready { Poll::Ready(Ok(())) } else { Poll::Pending }
}
- fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
+ fn start_send(
+ self: Pin<&mut Self>,
+ item: Item,
+ ) -> Result<(), Self::Error> {
let this = self.project();
this.sink1.start_send(item.clone())?;
@@ -83,29 +87,27 @@ where
Ok(())
}
- fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_flush(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
let this = self.project();
let sink1_ready = this.sink1.poll_flush(cx)?.is_ready();
let sink2_ready = this.sink2.poll_flush(cx)?.is_ready();
let ready = sink1_ready && sink2_ready;
- if ready {
- Poll::Ready(Ok(()))
- } else {
- Poll::Pending
- }
+ if ready { Poll::Ready(Ok(())) } else { Poll::Pending }
}
- fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_close(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
let this = self.project();
let sink1_ready = this.sink1.poll_close(cx)?.is_ready();
let sink2_ready = this.sink2.poll_close(cx)?.is_ready();
let ready = sink1_ready && sink2_ready;
- if ready {
- Poll::Ready(Ok(()))
- } else {
- Poll::Pending
- }
+ if ready { Poll::Ready(Ok(())) } else { Poll::Pending }
}
}
diff --git a/src/sink/feed.rs b/src/sink/feed.rs
index 6701f7a..06df9a9 100644
--- a/src/sink/feed.rs
+++ b/src/sink/feed.rs
@@ -17,7 +17,10 @@ impl<Si: Unpin + ?Sized, Item> Unpin for Feed<'_, Si, Item> {}
impl<'a, Si: Sink<Item> + Unpin + ?Sized, Item> Feed<'a, Si, Item> {
pub(super) fn new(sink: &'a mut Si, item: Item) -> Self {
- Feed { sink, item: Some(item) }
+ Feed {
+ sink,
+ item: Some(item),
+ }
}
pub(super) fn sink_pin_mut(&mut self) -> Pin<&mut Si> {
@@ -32,7 +35,10 @@ impl<'a, Si: Sink<Item> + Unpin + ?Sized, Item> Feed<'a, Si, Item> {
impl<Si: Sink<Item> + Unpin + ?Sized, Item> Future for Feed<'_, Si, Item> {
type Output = Result<(), Si::Error>;
- fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ fn poll(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Self::Output> {
let this = self.get_mut();
let mut sink = Pin::new(&mut this.sink);
ready!(sink.as_mut().poll_ready(cx))?;
diff --git a/src/sink/flush.rs b/src/sink/flush.rs
index 35a8372..c06a221 100644
--- a/src/sink/flush.rs
+++ b/src/sink/flush.rs
@@ -23,14 +23,20 @@ impl<Si: Unpin + ?Sized, Item> Unpin for Flush<'_, Si, Item> {}
/// all current requests are processed.
impl<'a, Si: Sink<Item> + Unpin + ?Sized, Item> Flush<'a, Si, Item> {
pub(super) fn new(sink: &'a mut Si) -> Self {
- Self { sink, _phantom: PhantomData }
+ Self {
+ sink,
+ _phantom: PhantomData,
+ }
}
}
impl<Si: Sink<Item> + Unpin + ?Sized, Item> Future for Flush<'_, Si, Item> {
type Output = Result<(), Si::Error>;
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ fn poll(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Self::Output> {
Pin::new(&mut self.sink).poll_flush(cx)
}
}
diff --git a/src/sink/map_err.rs b/src/sink/map_err.rs
index 9d2ab7b..2829344 100644
--- a/src/sink/map_err.rs
+++ b/src/sink/map_err.rs
@@ -1,7 +1,7 @@
use core::pin::Pin;
-use futures_core::stream::{FusedStream, Stream};
+use futures_core::stream::{Stream, FusedStream};
use futures_core::task::{Context, Poll};
-use futures_sink::Sink;
+use futures_sink::{Sink};
use pin_project_lite::pin_project;
pin_project! {
@@ -28,25 +28,36 @@ impl<Si, F> SinkMapErr<Si, F> {
}
impl<Si, F, E, Item> Sink<Item> for SinkMapErr<Si, F>
-where
- Si: Sink<Item>,
- F: FnOnce(Si::Error) -> E,
+ where Si: Sink<Item>,
+ F: FnOnce(Si::Error) -> E,
{
type Error = E;
- fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_ready(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
self.as_mut().project().sink.poll_ready(cx).map_err(|e| self.as_mut().take_f()(e))
}
- fn start_send(mut self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
+ fn start_send(
+ mut self: Pin<&mut Self>,
+ item: Item,
+ ) -> Result<(), Self::Error> {
self.as_mut().project().sink.start_send(item).map_err(|e| self.as_mut().take_f()(e))
}
- fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_flush(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
self.as_mut().project().sink.poll_flush(cx).map_err(|e| self.as_mut().take_f()(e))
}
- fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_close(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
self.as_mut().project().sink.poll_close(cx).map_err(|e| self.as_mut().take_f()(e))
}
}
diff --git a/src/sink/mod.rs b/src/sink/mod.rs
index 147e9ad..e5b515b 100644
--- a/src/sink/mod.rs
+++ b/src/sink/mod.rs
@@ -243,8 +243,7 @@ pub trait SinkExt<Item>: Sink<Item> {
/// This future will drive the stream to keep producing items until it is
/// exhausted, sending each item to the sink. It will complete once both the
/// stream is exhausted, the sink has received all items, and the sink has
- /// been flushed. Note that the sink is **not** closed. If the stream produces
- /// an error, that error will be returned by this future without flushing the sink.
+ /// been flushed. Note that the sink is **not** closed.
///
/// Doing `sink.send_all(stream)` is roughly equivalent to
/// `stream.forward(sink)`. The returned future will exhaust all items from
diff --git a/src/sink/send.rs b/src/sink/send.rs
index 6d21f33..384c22c 100644
--- a/src/sink/send.rs
+++ b/src/sink/send.rs
@@ -17,14 +17,19 @@ impl<Si: Unpin + ?Sized, Item> Unpin for Send<'_, Si, Item> {}
impl<'a, Si: Sink<Item> + Unpin + ?Sized, Item> Send<'a, Si, Item> {
pub(super) fn new(sink: &'a mut Si, item: Item) -> Self {
- Self { feed: Feed::new(sink, item) }
+ Self {
+ feed: Feed::new(sink, item),
+ }
}
}
impl<Si: Sink<Item> + Unpin + ?Sized, Item> Future for Send<'_, Si, Item> {
type Output = Result<(), Si::Error>;
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ fn poll(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Self::Output> {
let this = &mut *self;
if this.feed.is_item_pending() {
diff --git a/src/sink/send_all.rs b/src/sink/send_all.rs
index 1302dd2..6a33459 100644
--- a/src/sink/send_all.rs
+++ b/src/sink/send_all.rs
@@ -1,9 +1,9 @@
-use crate::stream::{Fuse, StreamExt, TryStreamExt};
+use crate::stream::{StreamExt, TryStreamExt, Fuse};
use core::fmt;
use core::pin::Pin;
use futures_core::future::Future;
use futures_core::ready;
-use futures_core::stream::{Stream, TryStream};
+use futures_core::stream::{TryStream, Stream};
use futures_core::task::{Context, Poll};
use futures_sink::Sink;
@@ -40,16 +40,22 @@ impl<Si, St> Unpin for SendAll<'_, Si, St>
where
Si: Unpin + ?Sized,
St: TryStream + Unpin + ?Sized,
-{
-}
+{}
impl<'a, Si, St, Ok, Error> SendAll<'a, Si, St>
where
Si: Sink<Ok, Error = Error> + Unpin + ?Sized,
St: TryStream<Ok = Ok, Error = Error> + Stream + Unpin + ?Sized,
{
- pub(super) fn new(sink: &'a mut Si, stream: &'a mut St) -> Self {
- Self { sink, stream: stream.fuse(), buffered: None }
+ pub(super) fn new(
+ sink: &'a mut Si,
+ stream: &'a mut St,
+ ) -> Self {
+ Self {
+ sink,
+ stream: stream.fuse(),
+ buffered: None,
+ }
}
fn try_start_send(
@@ -59,7 +65,9 @@ where
) -> Poll<Result<(), Si::Error>> {
debug_assert!(self.buffered.is_none());
match Pin::new(&mut self.sink).poll_ready(cx)? {
- Poll::Ready(()) => Poll::Ready(Pin::new(&mut self.sink).start_send(item)),
+ Poll::Ready(()) => {
+ Poll::Ready(Pin::new(&mut self.sink).start_send(item))
+ }
Poll::Pending => {
self.buffered = Some(item);
Poll::Pending
@@ -75,7 +83,10 @@ where
{
type Output = Result<(), Error>;
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ fn poll(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Self::Output> {
let this = &mut *self;
// If we've got an item buffered already, we need to write it to the
// sink before we can do anything else
@@ -85,14 +96,16 @@ where
loop {
match this.stream.try_poll_next_unpin(cx)? {
- Poll::Ready(Some(item)) => ready!(this.try_start_send(cx, item))?,
+ Poll::Ready(Some(item)) => {
+ ready!(this.try_start_send(cx, item))?
+ }
Poll::Ready(None) => {
ready!(Pin::new(&mut this.sink).poll_flush(cx))?;
- return Poll::Ready(Ok(()));
+ return Poll::Ready(Ok(()))
}
Poll::Pending => {
ready!(Pin::new(&mut this.sink).poll_flush(cx))?;
- return Poll::Pending;
+ return Poll::Pending
}
}
}
diff --git a/src/sink/unfold.rs b/src/sink/unfold.rs
index 330a068..3903716 100644
--- a/src/sink/unfold.rs
+++ b/src/sink/unfold.rs
@@ -41,7 +41,10 @@ where
F: FnMut(T, Item) -> R,
R: Future<Output = Result<T, E>>,
{
- assert_sink::<Item, E, _>(Unfold { function, state: UnfoldState::Value { value: init } })
+ assert_sink::<Item, E, _>(Unfold {
+ function,
+ state: UnfoldState::Value { value: init },
+ })
}
impl<T, F, R, Item, E> Sink<Item> for Unfold<T, F, R>
diff --git a/src/sink/with.rs b/src/sink/with.rs
index 86d3dcc..73b87b7 100644
--- a/src/sink/with.rs
+++ b/src/sink/with.rs
@@ -27,22 +27,29 @@ where
Fut: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("With").field("sink", &self.sink).field("state", &self.state).finish()
+ f.debug_struct("With")
+ .field("sink", &self.sink)
+ .field("state", &self.state)
+ .finish()
}
}
impl<Si, Item, U, Fut, F> With<Si, Item, U, Fut, F>
-where
- Si: Sink<Item>,
- F: FnMut(U) -> Fut,
- Fut: Future,
+where Si: Sink<Item>,
+ F: FnMut(U) -> Fut,
+ Fut: Future,
{
pub(super) fn new<E>(sink: Si, f: F) -> Self
- where
- Fut: Future<Output = Result<Item, E>>,
- E: From<Si::Error>,
+ where
+ Fut: Future<Output = Result<Item, E>>,
+ E: From<Si::Error>,
{
- Self { state: None, sink, f, _phantom: PhantomData }
+ Self {
+ state: None,
+ sink,
+ f,
+ _phantom: PhantomData,
+ }
}
}
@@ -64,10 +71,9 @@ where
// Forwarding impl of Stream from the underlying sink
impl<S, Item, U, Fut, F> Stream for With<S, Item, U, Fut, F>
-where
- S: Stream + Sink<Item>,
- F: FnMut(U) -> Fut,
- Fut: Future,
+ where S: Stream + Sink<Item>,
+ F: FnMut(U) -> Fut,
+ Fut: Future
{
type Item = S::Item;
@@ -75,16 +81,18 @@ where
}
impl<Si, Item, U, Fut, F, E> With<Si, Item, U, Fut, F>
-where
- Si: Sink<Item>,
- F: FnMut(U) -> Fut,
- Fut: Future<Output = Result<Item, E>>,
- E: From<Si::Error>,
+ where Si: Sink<Item>,
+ F: FnMut(U) -> Fut,
+ Fut: Future<Output = Result<Item, E>>,
+ E: From<Si::Error>,
{
delegate_access_inner!(sink, Si, ());
/// Completes the processing of previous item if any.
- fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), E>> {
+ fn poll(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), E>> {
let mut this = self.project();
let item = match this.state.as_mut().as_pin_mut() {
@@ -98,21 +106,26 @@ where
}
impl<Si, Item, U, Fut, F, E> Sink<U> for With<Si, Item, U, Fut, F>
-where
- Si: Sink<Item>,
- F: FnMut(U) -> Fut,
- Fut: Future<Output = Result<Item, E>>,
- E: From<Si::Error>,
+ where Si: Sink<Item>,
+ F: FnMut(U) -> Fut,
+ Fut: Future<Output = Result<Item, E>>,
+ E: From<Si::Error>,
{
type Error = E;
- fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_ready(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
ready!(self.as_mut().poll(cx))?;
ready!(self.project().sink.poll_ready(cx)?);
Poll::Ready(Ok(()))
}
- fn start_send(self: Pin<&mut Self>, item: U) -> Result<(), Self::Error> {
+ fn start_send(
+ self: Pin<&mut Self>,
+ item: U,
+ ) -> Result<(), Self::Error> {
let mut this = self.project();
assert!(this.state.is_none());
@@ -120,13 +133,19 @@ where
Ok(())
}
- fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_flush(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
ready!(self.as_mut().poll(cx))?;
ready!(self.project().sink.poll_flush(cx)?);
Poll::Ready(Ok(()))
}
- fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_close(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
ready!(self.as_mut().poll(cx))?;
ready!(self.project().sink.poll_close(cx)?);
Poll::Ready(Ok(()))
diff --git a/src/sink/with_flat_map.rs b/src/sink/with_flat_map.rs
index 2ae877a..4b8d3a2 100644
--- a/src/sink/with_flat_map.rs
+++ b/src/sink/with_flat_map.rs
@@ -2,7 +2,7 @@ use core::fmt;
use core::marker::PhantomData;
use core::pin::Pin;
use futures_core::ready;
-use futures_core::stream::{FusedStream, Stream};
+use futures_core::stream::{Stream, FusedStream};
use futures_core::task::{Context, Poll};
use futures_sink::Sink;
use pin_project_lite::pin_project;
@@ -43,12 +43,21 @@ where
St: Stream<Item = Result<Item, Si::Error>>,
{
pub(super) fn new(sink: Si, f: F) -> Self {
- Self { sink, f, stream: None, buffer: None, _marker: PhantomData }
+ Self {
+ sink,
+ f,
+ stream: None,
+ buffer: None,
+ _marker: PhantomData,
+ }
}
delegate_access_inner!(sink, Si, ());
- fn try_empty_stream(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Si::Error>> {
+ fn try_empty_stream(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Si::Error>> {
let mut this = self.project();
if this.buffer.is_some() {
@@ -103,11 +112,17 @@ where
{
type Error = Si::Error;
- fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_ready(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
self.try_empty_stream(cx)
}
- fn start_send(self: Pin<&mut Self>, item: U) -> Result<(), Self::Error> {
+ fn start_send(
+ self: Pin<&mut Self>,
+ item: U,
+ ) -> Result<(), Self::Error> {
let mut this = self.project();
assert!(this.stream.is_none());
@@ -115,12 +130,18 @@ where
Ok(())
}
- fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_flush(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
ready!(self.as_mut().try_empty_stream(cx)?);
self.project().sink.poll_flush(cx)
}
- fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ fn poll_close(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<(), Self::Error>> {
ready!(self.as_mut().try_empty_stream(cx)?);
self.project().sink.poll_close(cx)
}
diff --git a/src/stream/abortable.rs b/src/stream/abortable.rs
deleted file mode 100644
index 1fea895..0000000
--- a/src/stream/abortable.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-use super::assert_stream;
-use crate::stream::{AbortHandle, Abortable};
-use crate::Stream;
-
-/// Creates a new `Abortable` stream and an `AbortHandle` which can be used to stop it.
-///
-/// This function is a convenient (but less flexible) alternative to calling
-/// `AbortHandle::new` and `Abortable::new` manually.
-///
-/// This function is only available when the `std` or `alloc` feature of this
-/// library is activated, and it is activated by default.
-pub fn abortable<St>(stream: St) -> (Abortable<St>, AbortHandle)
-where
- St: Stream,
-{
- let (handle, reg) = AbortHandle::new_pair();
- let abortable = assert_stream::<St::Item, _>(Abortable::new(stream, reg));
- (abortable, handle)
-}
diff --git a/src/stream/empty.rs b/src/stream/empty.rs
index e4fd873..c629a4b 100644
--- a/src/stream/empty.rs
+++ b/src/stream/empty.rs
@@ -8,14 +8,16 @@ use futures_core::task::{Context, Poll};
#[derive(Debug)]
#[must_use = "streams do nothing unless polled"]
pub struct Empty<T> {
- _phantom: PhantomData<T>,
+ _phantom: PhantomData<T>
}
/// Creates a stream which contains no elements.
///
/// The returned stream will always return `Ready(None)` when polled.
pub fn empty<T>() -> Empty<T> {
- assert_stream::<T, _>(Empty { _phantom: PhantomData })
+ assert_stream::<T, _>(Empty {
+ _phantom: PhantomData
+ })
}
impl<T> Unpin for Empty<T> {}
diff --git a/src/stream/futures_ordered.rs b/src/stream/futures_ordered.rs
index f596b3b..eda3b27 100644
--- a/src/stream/futures_ordered.rs
+++ b/src/stream/futures_ordered.rs
@@ -52,7 +52,10 @@ where
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let index = self.index;
- self.project().data.poll(cx).map(|output| OrderWrapper { data: output, index })
+ self.project().data.poll(cx).map(|output| OrderWrapper {
+ data: output,
+ index,
+ })
}
}
@@ -136,7 +139,10 @@ impl<Fut: Future> FuturesOrdered<Fut> {
/// must ensure that `FuturesOrdered::poll` is called in order to receive
/// task notifications.
pub fn push(&mut self, future: Fut) {
- let wrapped = OrderWrapper { data: future, index: self.next_incoming_index };
+ let wrapped = OrderWrapper {
+ data: future,
+ index: self.next_incoming_index,
+ };
self.next_incoming_index += 1;
self.in_progress_queue.push(wrapped);
}
diff --git a/src/stream/futures_unordered/iter.rs b/src/stream/futures_unordered/iter.rs
index 04db5ee..ef7b15a 100644
--- a/src/stream/futures_unordered/iter.rs
+++ b/src/stream/futures_unordered/iter.rs
@@ -1,83 +1,41 @@
-use super::task::Task;
use super::FuturesUnordered;
+use super::task::Task;
use core::marker::PhantomData;
use core::pin::Pin;
use core::sync::atomic::Ordering::Relaxed;
-/// Mutable iterator over all futures in the unordered set.
#[derive(Debug)]
+/// Mutable iterator over all futures in the unordered set.
pub struct IterPinMut<'a, Fut> {
pub(super) task: *const Task<Fut>,
pub(super) len: usize,
- pub(super) _marker: PhantomData<&'a mut FuturesUnordered<Fut>>,
+ pub(super) _marker: PhantomData<&'a mut FuturesUnordered<Fut>>
}
-/// Mutable iterator over all futures in the unordered set.
#[derive(Debug)]
-pub struct IterMut<'a, Fut: Unpin>(pub(super) IterPinMut<'a, Fut>);
+/// Mutable iterator over all futures in the unordered set.
+pub struct IterMut<'a, Fut: Unpin> (pub(super) IterPinMut<'a, Fut>);
-/// Immutable iterator over all futures in the unordered set.
#[derive(Debug)]
+/// Immutable iterator over all futures in the unordered set.
pub struct IterPinRef<'a, Fut> {
pub(super) task: *const Task<Fut>,
pub(super) len: usize,
pub(super) pending_next_all: *mut Task<Fut>,
- pub(super) _marker: PhantomData<&'a FuturesUnordered<Fut>>,
+ pub(super) _marker: PhantomData<&'a FuturesUnordered<Fut>>
}
-/// Immutable iterator over all the futures in the unordered set.
-#[derive(Debug)]
-pub struct Iter<'a, Fut: Unpin>(pub(super) IterPinRef<'a, Fut>);
-
-/// Owned iterator over all futures in the unordered set.
#[derive(Debug)]
-pub struct IntoIter<Fut: Unpin> {
- pub(super) len: usize,
- pub(super) inner: FuturesUnordered<Fut>,
-}
-
-impl<Fut: Unpin> Iterator for IntoIter<Fut> {
- type Item = Fut;
-
- fn next(&mut self) -> Option<Self::Item> {
- // `head_all` can be accessed directly and we don't need to spin on
- // `Task::next_all` since we have exclusive access to the set.
- let task = self.inner.head_all.get_mut();
-
- if (*task).is_null() {
- return None;
- }
-
- unsafe {
- // Moving out of the future is safe because it is `Unpin`
- let future = (*(**task).future.get()).take().unwrap();
-
- // Mutable access to a previously shared `FuturesUnordered` implies
- // that the other threads already released the object before the
- // current thread acquired it, so relaxed ordering can be used and
- // valid `next_all` checks can be skipped.
- let next = (**task).next_all.load(Relaxed);
- *task = next;
- self.len -= 1;
- Some(future)
- }
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- (self.len, Some(self.len))
- }
-}
-
-impl<Fut: Unpin> ExactSizeIterator for IntoIter<Fut> {}
+/// Immutable iterator over all the futures in the unordered set.
+pub struct Iter<'a, Fut: Unpin> (pub(super) IterPinRef<'a, Fut>);
impl<'a, Fut> Iterator for IterPinMut<'a, Fut> {
type Item = Pin<&'a mut Fut>;
- fn next(&mut self) -> Option<Self::Item> {
+ fn next(&mut self) -> Option<Pin<&'a mut Fut>> {
if self.task.is_null() {
return None;
}
-
unsafe {
let future = (*(*self.task).future.get()).as_mut().unwrap();
@@ -102,7 +60,7 @@ impl<Fut> ExactSizeIterator for IterPinMut<'_, Fut> {}
impl<'a, Fut: Unpin> Iterator for IterMut<'a, Fut> {
type Item = &'a mut Fut;
- fn next(&mut self) -> Option<Self::Item> {
+ fn next(&mut self) -> Option<&'a mut Fut> {
self.0.next().map(Pin::get_mut)
}
@@ -116,11 +74,10 @@ impl<Fut: Unpin> ExactSizeIterator for IterMut<'_, Fut> {}
impl<'a, Fut> Iterator for IterPinRef<'a, Fut> {
type Item = Pin<&'a Fut>;
- fn next(&mut self) -> Option<Self::Item> {
+ fn next(&mut self) -> Option<Pin<&'a Fut>> {
if self.task.is_null() {
return None;
}
-
unsafe {
let future = (*(*self.task).future.get()).as_ref().unwrap();
@@ -128,7 +85,10 @@ impl<'a, Fut> Iterator for IterPinRef<'a, Fut> {
// `head_all` was initially read for this iterator implies acquire
// ordering for all previously inserted nodes (and we don't need to
// read `len_all` again for any other nodes).
- let next = (*self.task).spin_next_all(self.pending_next_all, Relaxed);
+ let next = (*self.task).spin_next_all(
+ self.pending_next_all,
+ Relaxed,
+ );
self.task = next;
self.len -= 1;
Some(Pin::new_unchecked(future))
@@ -145,7 +105,7 @@ impl<Fut> ExactSizeIterator for IterPinRef<'_, Fut> {}
impl<'a, Fut: Unpin> Iterator for Iter<'a, Fut> {
type Item = &'a Fut;
- fn next(&mut self) -> Option<Self::Item> {
+ fn next(&mut self) -> Option<&'a Fut> {
self.0.next().map(Pin::get_ref)
}
@@ -155,14 +115,3 @@ impl<'a, Fut: Unpin> Iterator for Iter<'a, Fut> {
}
impl<Fut: Unpin> ExactSizeIterator for Iter<'_, Fut> {}
-
-// SAFETY: we do nothing thread-local and there is no interior mutability,
-// so the usual structural `Send`/`Sync` apply.
-unsafe impl<Fut: Send> Send for IterPinRef<'_, Fut> {}
-unsafe impl<Fut: Sync> Sync for IterPinRef<'_, Fut> {}
-
-unsafe impl<Fut: Send> Send for IterPinMut<'_, Fut> {}
-unsafe impl<Fut: Sync> Sync for IterPinMut<'_, Fut> {}
-
-unsafe impl<Fut: Send + Unpin> Send for IntoIter<Fut> {}
-unsafe impl<Fut: Sync + Unpin> Sync for IntoIter<Fut> {}
diff --git a/src/stream/futures_unordered/mod.rs b/src/stream/futures_unordered/mod.rs
index fdbd53d..8dcc551 100644
--- a/src/stream/futures_unordered/mod.rs
+++ b/src/stream/futures_unordered/mod.rs
@@ -3,8 +3,11 @@
//! This module is only available when the `std` or `alloc` feature of this
//! library is activated, and it is activated by default.
+use futures_core::future::Future;
+use futures_core::stream::{FusedStream, Stream};
+use futures_core::task::{Context, Poll};
+use futures_task::{FutureObj, LocalFutureObj, Spawn, LocalSpawn, SpawnError};
use crate::task::AtomicWaker;
-use alloc::sync::{Arc, Weak};
use core::cell::UnsafeCell;
use core::fmt::{self, Debug};
use core::iter::FromIterator;
@@ -13,22 +16,20 @@ use core::mem;
use core::pin::Pin;
use core::ptr;
use core::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release, SeqCst};
-use core::sync::atomic::{AtomicBool, AtomicPtr};
-use futures_core::future::Future;
-use futures_core::stream::{FusedStream, Stream};
-use futures_core::task::{Context, Poll};
-use futures_task::{FutureObj, LocalFutureObj, LocalSpawn, Spawn, SpawnError};
+use core::sync::atomic::{AtomicPtr, AtomicBool};
+use alloc::sync::{Arc, Weak};
mod abort;
mod iter;
-pub use self::iter::{IntoIter, Iter, IterMut, IterPinMut, IterPinRef};
+pub use self::iter::{Iter, IterMut, IterPinMut, IterPinRef};
mod task;
use self::task::Task;
mod ready_to_run_queue;
-use self::ready_to_run_queue::{Dequeue, ReadyToRunQueue};
+use self::ready_to_run_queue::{ReadyToRunQueue, Dequeue};
+
/// A set of futures which may complete in any order.
///
@@ -62,14 +63,18 @@ unsafe impl<Fut: Sync> Sync for FuturesUnordered<Fut> {}
impl<Fut> Unpin for FuturesUnordered<Fut> {}
impl Spawn for FuturesUnordered<FutureObj<'_, ()>> {
- fn spawn_obj(&self, future_obj: FutureObj<'static, ()>) -> Result<(), SpawnError> {
+ fn spawn_obj(&self, future_obj: FutureObj<'static, ()>)
+ -> Result<(), SpawnError>
+ {
self.push(future_obj);
Ok(())
}
}
impl LocalSpawn for FuturesUnordered<LocalFutureObj<'_, ()>> {
- fn spawn_local_obj(&self, future_obj: LocalFutureObj<'static, ()>) -> Result<(), SpawnError> {
+ fn spawn_local_obj(&self, future_obj: LocalFutureObj<'static, ()>)
+ -> Result<(), SpawnError>
+ {
self.push(future_obj);
Ok(())
}
@@ -97,7 +102,7 @@ impl LocalSpawn for FuturesUnordered<LocalFutureObj<'_, ()>> {
// Each task is wrapped in an `Arc` and thereby atomically reference counted.
// Also, each task contains an `AtomicBool` which acts as a flag that indicates
// whether the task is currently inserted in the atomic queue. When a wake-up
-// notification is received, the task will only be inserted into the ready to
+// notifiaction is received, the task will only be inserted into the ready to
// run queue if it isn't inserted already.
impl<Fut> Default for FuturesUnordered<Fut> {
@@ -121,9 +126,8 @@ impl<Fut> FuturesUnordered<Fut> {
next_ready_to_run: AtomicPtr::new(ptr::null_mut()),
queued: AtomicBool::new(true),
ready_to_run_queue: Weak::new(),
- woken: AtomicBool::new(false),
});
- let stub_ptr = Arc::as_ptr(&stub);
+ let stub_ptr = &*stub as *const Task<Fut>;
let ready_to_run_queue = Arc::new(ReadyToRunQueue {
waker: AtomicWaker::new(),
head: AtomicPtr::new(stub_ptr as *mut _),
@@ -168,7 +172,6 @@ impl<Fut> FuturesUnordered<Fut> {
next_ready_to_run: AtomicPtr::new(ptr::null_mut()),
queued: AtomicBool::new(true),
ready_to_run_queue: Arc::downgrade(&self.ready_to_run_queue),
- woken: AtomicBool::new(false),
});
// Reset the `is_terminated` flag if we've previously marked ourselves
@@ -188,26 +191,24 @@ impl<Fut> FuturesUnordered<Fut> {
}
/// Returns an iterator that allows inspecting each future in the set.
- pub fn iter(&self) -> Iter<'_, Fut>
- where
- Fut: Unpin,
- {
+ pub fn iter(&self) -> Iter<'_, Fut> where Fut: Unpin {
Iter(Pin::new(self).iter_pin_ref())
}
/// Returns an iterator that allows inspecting each future in the set.
- pub fn iter_pin_ref(self: Pin<&Self>) -> IterPinRef<'_, Fut> {
+ fn iter_pin_ref(self: Pin<&Self>) -> IterPinRef<'_, Fut> {
let (task, len) = self.atomic_load_head_and_len_all();
- let pending_next_all = self.pending_next_all();
- IterPinRef { task, len, pending_next_all, _marker: PhantomData }
+ IterPinRef {
+ task,
+ len,
+ pending_next_all: self.pending_next_all(),
+ _marker: PhantomData,
+ }
}
/// Returns an iterator that allows modifying each future in the set.
- pub fn iter_mut(&mut self) -> IterMut<'_, Fut>
- where
- Fut: Unpin,
- {
+ pub fn iter_mut(&mut self) -> IterMut<'_, Fut> where Fut: Unpin {
IterMut(Pin::new(self).iter_pin_mut())
}
@@ -216,9 +217,19 @@ impl<Fut> FuturesUnordered<Fut> {
// `head_all` can be accessed directly and we don't need to spin on
// `Task::next_all` since we have exclusive access to the set.
let task = *self.head_all.get_mut();
- let len = if task.is_null() { 0 } else { unsafe { *(*task).len_all.get() } };
+ let len = if task.is_null() {
+ 0
+ } else {
+ unsafe {
+ *(*task).len_all.get()
+ }
+ };
- IterPinMut { task, len, _marker: PhantomData }
+ IterPinMut {
+ task,
+ len,
+ _marker: PhantomData
+ }
}
/// Returns the current head node and number of futures in the list of all
@@ -238,7 +249,7 @@ impl<Fut> FuturesUnordered<Fut> {
(task, len)
}
- /// Releases the task. It destroys the future inside and either drops
+ /// Releases the task. It destorys the future inside and either drops
/// the `Arc<Task>` or transfers ownership to the ready to run queue.
/// The task this method is called on must have been unlinked before.
fn release_task(&mut self, task: Arc<Task<Fut>>) {
@@ -377,20 +388,35 @@ impl<Fut> FuturesUnordered<Fut> {
// The `ReadyToRunQueue` stub is never inserted into the `head_all`
// list, and its pointer value will remain valid for the lifetime of
// this `FuturesUnordered`, so we can make use of its value here.
- Arc::as_ptr(&self.ready_to_run_queue.stub) as *mut _
+ &*self.ready_to_run_queue.stub as *const _ as *mut _
}
}
impl<Fut: Future> Stream for FuturesUnordered<Fut> {
type Item = Fut::Output;
- fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
- let len = self.len();
+ fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>)
+ -> Poll<Option<Self::Item>>
+ {
+ // Variable to determine how many times it is allowed to poll underlying
+ // futures without yielding.
+ //
+ // A single call to `poll_next` may potentially do a lot of work before
+ // yielding. This happens in particular if the underlying futures are awoken
+ // frequently but continue to return `Pending`. This is problematic if other
+ // tasks are waiting on the executor, since they do not get to run. This value
+ // caps the number of calls to `poll` on underlying futures a single call to
+ // `poll_next` is allowed to make.
+ //
+ // The value is the length of FuturesUnordered. This ensures that each
+ // future is polled only once at most per iteration.
+ //
+ // See also https://github.com/rust-lang/futures-rs/issues/2047.
+ let yield_every = self.len();
// Keep track of how many child futures we have polled,
// in case we want to forcibly yield.
let mut polled = 0;
- let mut yielded = 0;
// Ensure `parent` is correctly set.
self.ready_to_run_queue.waker.register(cx.waker());
@@ -443,11 +469,14 @@ impl<Fut: Future> Stream for FuturesUnordered<Fut> {
// Double check that the call to `release_task` really
// happened. Calling it required the task to be unlinked.
- debug_assert_eq!(task.next_all.load(Relaxed), self.pending_next_all());
+ debug_assert_eq!(
+ task.next_all.load(Relaxed),
+ self.pending_next_all()
+ );
unsafe {
debug_assert!((*task.prev_all.get()).is_null());
}
- continue;
+ continue
}
};
@@ -487,7 +516,10 @@ impl<Fut: Future> Stream for FuturesUnordered<Fut> {
}
}
- let mut bomb = Bomb { task: Some(task), queue: &mut *self };
+ let mut bomb = Bomb {
+ task: Some(task),
+ queue: &mut *self,
+ };
// Poll the underlying future with the appropriate waker
// implementation. This is where a large bit of the unsafety
@@ -501,11 +533,7 @@ impl<Fut: Future> Stream for FuturesUnordered<Fut> {
// the internal allocation, appropriately accessing fields and
// deallocating the task if need be.
let res = {
- let task = bomb.task.as_ref().unwrap();
- // We are only interested in whether the future is awoken before it
- // finishes polling, so reset the flag here.
- task.woken.store(false, Relaxed);
- let waker = Task::waker_ref(task);
+ let waker = Task::waker_ref(bomb.task.as_ref().unwrap());
let mut cx = Context::from_waker(&waker);
// Safety: We won't move the future ever again
@@ -518,23 +546,20 @@ impl<Fut: Future> Stream for FuturesUnordered<Fut> {
match res {
Poll::Pending => {
let task = bomb.task.take().unwrap();
- // If the future was awoken during polling, we assume
- // the future wanted to explicitly yield.
- yielded += task.woken.load(Relaxed) as usize;
bomb.queue.link(task);
- // If a future yields, we respect it and yield here.
- // If all futures have been polled, we also yield here to
- // avoid starving other tasks waiting on the executor.
- // (polling the same future twice per iteration may cause
- // the problem: https://github.com/rust-lang/futures-rs/pull/2333)
- if yielded >= 2 || polled == len {
+ if polled == yield_every {
+ // We have polled a large number of futures in a row without yielding.
+ // To ensure we do not starve other tasks waiting on the executor,
+ // we yield here, but immediately wake ourselves up to continue.
cx.waker().wake_by_ref();
return Poll::Pending;
}
- continue;
+ continue
+ }
+ Poll::Ready(output) => {
+ return Poll::Ready(Some(output))
}
- Poll::Ready(output) => return Poll::Ready(Some(output)),
}
}
}
@@ -551,33 +576,19 @@ impl<Fut> Debug for FuturesUnordered<Fut> {
}
}
-impl<Fut> FuturesUnordered<Fut> {
- /// Clears the set, removing all futures.
- pub fn clear(&mut self) {
- self.clear_head_all();
-
- // we just cleared all the tasks, and we have &mut self, so this is safe.
- unsafe { self.ready_to_run_queue.clear() };
-
- self.is_terminated.store(false, Relaxed);
- }
-
- fn clear_head_all(&mut self) {
- while !self.head_all.get_mut().is_null() {
- let head = *self.head_all.get_mut();
- let task = unsafe { self.unlink(head) };
- self.release_task(task);
- }
- }
-}
-
impl<Fut> Drop for FuturesUnordered<Fut> {
fn drop(&mut self) {
// When a `FuturesUnordered` is dropped we want to drop all futures
// associated with it. At the same time though there may be tons of
// wakers flying around which contain `Task<Fut>` references
// inside them. We'll let those naturally get deallocated.
- self.clear_head_all();
+ unsafe {
+ while !self.head_all.get_mut().is_null() {
+ let head = *self.head_all.get_mut();
+ let task = self.unlink(head);
+ self.release_task(task);
+ }
+ }
// Note that at this point we could still have a bunch of tasks in the
// ready to run queue. None of those tasks, however, have futures
@@ -594,48 +605,13 @@ impl<Fut> Drop for FuturesUnordered<Fut> {
}
}
-impl<'a, Fut: Unpin> IntoIterator for &'a FuturesUnordered<Fut> {
- type Item = &'a Fut;
- type IntoIter = Iter<'a, Fut>;
-
- fn into_iter(self) -> Self::IntoIter {
- self.iter()
- }
-}
-
-impl<'a, Fut: Unpin> IntoIterator for &'a mut FuturesUnordered<Fut> {
- type Item = &'a mut Fut;
- type IntoIter = IterMut<'a, Fut>;
-
- fn into_iter(self) -> Self::IntoIter {
- self.iter_mut()
- }
-}
-
-impl<Fut: Unpin> IntoIterator for FuturesUnordered<Fut> {
- type Item = Fut;
- type IntoIter = IntoIter<Fut>;
-
- fn into_iter(mut self) -> Self::IntoIter {
- // `head_all` can be accessed directly and we don't need to spin on
- // `Task::next_all` since we have exclusive access to the set.
- let task = *self.head_all.get_mut();
- let len = if task.is_null() { 0 } else { unsafe { *(*task).len_all.get() } };
-
- IntoIter { len, inner: self }
- }
-}
-
impl<Fut> FromIterator<Fut> for FuturesUnordered<Fut> {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = Fut>,
{
let acc = Self::new();
- iter.into_iter().fold(acc, |acc, item| {
- acc.push(item);
- acc
- })
+ iter.into_iter().fold(acc, |acc, item| { acc.push(item); acc })
}
}
diff --git a/src/stream/futures_unordered/ready_to_run_queue.rs b/src/stream/futures_unordered/ready_to_run_queue.rs
index 4518705..2105195 100644
--- a/src/stream/futures_unordered/ready_to_run_queue.rs
+++ b/src/stream/futures_unordered/ready_to_run_queue.rs
@@ -1,9 +1,9 @@
use crate::task::AtomicWaker;
-use alloc::sync::Arc;
use core::cell::UnsafeCell;
use core::ptr;
use core::sync::atomic::AtomicPtr;
-use core::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release};
+use core::sync::atomic::Ordering::{Relaxed, Acquire, Release, AcqRel};
+use alloc::sync::Arc;
use super::abort::abort;
use super::task::Task;
@@ -83,28 +83,7 @@ impl<Fut> ReadyToRunQueue<Fut> {
}
pub(super) fn stub(&self) -> *const Task<Fut> {
- Arc::as_ptr(&self.stub)
- }
-
- // Clear the queue of tasks.
- //
- // Note that each task has a strong reference count associated with it
- // which is owned by the ready to run queue. This method just pulls out
- // tasks and drops their refcounts.
- //
- // # Safety
- //
- // - All tasks **must** have had their futures dropped already (by FuturesUnordered::clear)
- // - The caller **must** guarantee unique access to `self`
- pub(crate) unsafe fn clear(&self) {
- loop {
- // SAFETY: We have the guarantee of mutual exclusion required by `dequeue`.
- match self.dequeue() {
- Dequeue::Empty => break,
- Dequeue::Inconsistent => abort("inconsistent in drop"),
- Dequeue::Data(ptr) => drop(Arc::from_raw(ptr)),
- }
- }
+ &*self.stub
}
}
@@ -112,11 +91,19 @@ impl<Fut> Drop for ReadyToRunQueue<Fut> {
fn drop(&mut self) {
// Once we're in the destructor for `Inner<Fut>` we need to clear out
// the ready to run queue of tasks if there's anything left in there.
-
- // All tasks have had their futures dropped already by the `FuturesUnordered`
- // destructor above, and we have &mut self, so this is safe.
+ //
+ // Note that each task has a strong reference count associated with it
+ // which is owned by the ready to run queue. All tasks should have had
+ // their futures dropped already by the `FuturesUnordered` destructor
+ // above, so we're just pulling out tasks and dropping their refcounts.
unsafe {
- self.clear();
+ loop {
+ match self.dequeue() {
+ Dequeue::Empty => break,
+ Dequeue::Inconsistent => abort("inconsistent in drop"),
+ Dequeue::Data(ptr) => drop(Arc::from_raw(ptr)),
+ }
+ }
}
}
}
diff --git a/src/stream/futures_unordered/task.rs b/src/stream/futures_unordered/task.rs
index ec2114e..261408f 100644
--- a/src/stream/futures_unordered/task.rs
+++ b/src/stream/futures_unordered/task.rs
@@ -1,11 +1,11 @@
-use alloc::sync::{Arc, Weak};
use core::cell::UnsafeCell;
-use core::sync::atomic::Ordering::{self, Relaxed, SeqCst};
-use core::sync::atomic::{AtomicBool, AtomicPtr};
+use core::sync::atomic::{AtomicPtr, AtomicBool};
+use core::sync::atomic::Ordering::{self, SeqCst};
+use alloc::sync::{Arc, Weak};
-use super::abort::abort;
+use crate::task::{ArcWake, WakerRef, waker_ref};
use super::ReadyToRunQueue;
-use crate::task::{waker_ref, ArcWake, WakerRef};
+use super::abort::abort;
pub(super) struct Task<Fut> {
// The future
@@ -31,11 +31,6 @@ pub(super) struct Task<Fut> {
// Whether or not this task is currently in the ready to run queue
pub(super) queued: AtomicBool,
-
- // Whether the future was awoken during polling
- // It is possible for this flag to be set to true after the polling,
- // but it will be ignored.
- pub(super) woken: AtomicBool,
}
// `Task` can be sent across threads safely because it ensures that
@@ -53,8 +48,6 @@ impl<Fut> ArcWake for Task<Fut> {
None => return,
};
- arc_self.woken.store(true, Relaxed);
-
// It's our job to enqueue this task it into the ready to run queue. To
// do this we set the `queued` flag, and if successful we then do the
// actual queueing operation, ensuring that we're only queued once.
@@ -69,7 +62,7 @@ impl<Fut> ArcWake for Task<Fut> {
// still.
let prev = arc_self.queued.swap(true, SeqCst);
if !prev {
- inner.enqueue(Arc::as_ptr(arc_self));
+ inner.enqueue(&**arc_self);
inner.waker.wake();
}
}
diff --git a/src/stream/iter.rs b/src/stream/iter.rs
index 20471c2..033dae1 100644
--- a/src/stream/iter.rs
+++ b/src/stream/iter.rs
@@ -27,15 +27,15 @@ impl<I> Unpin for Iter<I> {}
/// # });
/// ```
pub fn iter<I>(i: I) -> Iter<I::IntoIter>
-where
- I: IntoIterator,
+ where I: IntoIterator,
{
- assert_stream::<I::Item, _>(Iter { iter: i.into_iter() })
+ assert_stream::<I::Item, _>(Iter {
+ iter: i.into_iter(),
+ })
}
impl<I> Stream for Iter<I>
-where
- I: Iterator,
+ where I: Iterator,
{
type Item = I::Item;
diff --git a/src/stream/mod.rs b/src/stream/mod.rs
index ec685b9..f3b2baa 100644
--- a/src/stream/mod.rs
+++ b/src/stream/mod.rs
@@ -19,8 +19,8 @@ pub use futures_core::stream::{FusedStream, Stream, TryStream};
mod stream;
pub use self::stream::{
Chain, Collect, Concat, Cycle, Enumerate, Filter, FilterMap, FlatMap, Flatten, Fold, ForEach,
- Fuse, Inspect, Map, Next, NextIf, NextIfEq, Peek, PeekMut, Peekable, Scan, SelectNextSome,
- Skip, SkipWhile, StreamExt, StreamFuture, Take, TakeUntil, TakeWhile, Then, Unzip, Zip,
+ Fuse, Inspect, Map, Next, Peek, Peekable, Scan, SelectNextSome, Skip, SkipWhile, StreamExt,
+ StreamFuture, Take, TakeUntil, TakeWhile, Then, Unzip, Zip,
};
#[cfg(feature = "std")]
@@ -36,11 +36,11 @@ pub use self::stream::ReadyChunks;
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
pub use self::stream::Forward;
-#[cfg(not(futures_no_atomic_cas))]
+#[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
#[cfg(feature = "alloc")]
pub use self::stream::{BufferUnordered, Buffered, ForEachConcurrent};
-#[cfg(not(futures_no_atomic_cas))]
+#[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
#[cfg(feature = "sink")]
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
#[cfg(feature = "alloc")]
@@ -58,13 +58,10 @@ pub use self::try_stream::{
#[cfg(feature = "std")]
pub use self::try_stream::IntoAsyncRead;
-#[cfg(not(futures_no_atomic_cas))]
+#[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
#[cfg(feature = "alloc")]
pub use self::try_stream::{TryBufferUnordered, TryBuffered, TryForEachConcurrent};
-#[cfg(feature = "alloc")]
-pub use self::try_stream::{TryChunks, TryChunksError};
-
// Primitive streams
mod iter;
@@ -88,50 +85,29 @@ pub use self::pending::{pending, Pending};
mod poll_fn;
pub use self::poll_fn::{poll_fn, PollFn};
-mod poll_immediate;
-pub use self::poll_immediate::{poll_immediate, PollImmediate};
-
mod select;
pub use self::select::{select, Select};
-mod select_with_strategy;
-pub use self::select_with_strategy::{select_with_strategy, PollNext, SelectWithStrategy};
-
mod unfold;
pub use self::unfold::{unfold, Unfold};
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-mod futures_ordered;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-pub use self::futures_ordered::FuturesOrdered;
-
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-pub mod futures_unordered;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-#[doc(inline)]
-pub use self::futures_unordered::FuturesUnordered;
-
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-pub mod select_all;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-#[doc(inline)]
-pub use self::select_all::{select_all, SelectAll};
-
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-mod abortable;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-pub use crate::abortable::{AbortHandle, AbortRegistration, Abortable, Aborted};
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-pub use abortable::abortable;
+cfg_target_has_atomic! {
+ #[cfg(feature = "alloc")]
+ mod futures_ordered;
+ #[cfg(feature = "alloc")]
+ pub use self::futures_ordered::FuturesOrdered;
+
+ #[cfg(feature = "alloc")]
+ pub mod futures_unordered;
+ #[cfg(feature = "alloc")]
+ #[doc(inline)]
+ pub use self::futures_unordered::FuturesUnordered;
+
+ #[cfg(feature = "alloc")]
+ mod select_all;
+ #[cfg(feature = "alloc")]
+ pub use self::select_all::{select_all, SelectAll};
+}
// Just a helper function to ensure the streams we're returning all have the
// right implementations.
diff --git a/src/stream/once.rs b/src/stream/once.rs
index ee21c8b..e16fe00 100644
--- a/src/stream/once.rs
+++ b/src/stream/once.rs
@@ -2,7 +2,7 @@ use super::assert_stream;
use core::pin::Pin;
use futures_core::future::Future;
use futures_core::ready;
-use futures_core::stream::{FusedStream, Stream};
+use futures_core::stream::{Stream, FusedStream};
use futures_core::task::{Context, Poll};
use pin_project_lite::pin_project;
diff --git a/src/stream/poll_immediate.rs b/src/stream/poll_immediate.rs
deleted file mode 100644
index c7e8a5b..0000000
--- a/src/stream/poll_immediate.rs
+++ /dev/null
@@ -1,80 +0,0 @@
-use core::pin::Pin;
-use futures_core::task::{Context, Poll};
-use futures_core::Stream;
-use pin_project_lite::pin_project;
-
-pin_project! {
- /// Stream for the [poll_immediate](poll_immediate()) function.
- ///
- /// It will never return [Poll::Pending](core::task::Poll::Pending)
- #[derive(Debug, Clone)]
- #[must_use = "futures do nothing unless you `.await` or poll them"]
- pub struct PollImmediate<S> {
- #[pin]
- stream: Option<S>
- }
-}
-
-impl<T, S> Stream for PollImmediate<S>
-where
- S: Stream<Item = T>,
-{
- type Item = Poll<T>;
-
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
- let mut this = self.project();
- let stream = match this.stream.as_mut().as_pin_mut() {
- // inner is gone, so we can continue to signal that the stream is closed.
- None => return Poll::Ready(None),
- Some(inner) => inner,
- };
-
- match stream.poll_next(cx) {
- Poll::Ready(Some(t)) => Poll::Ready(Some(Poll::Ready(t))),
- Poll::Ready(None) => {
- this.stream.set(None);
- Poll::Ready(None)
- }
- Poll::Pending => Poll::Ready(Some(Poll::Pending)),
- }
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.stream.as_ref().map_or((0, Some(0)), Stream::size_hint)
- }
-}
-
-impl<S: Stream> super::FusedStream for PollImmediate<S> {
- fn is_terminated(&self) -> bool {
- self.stream.is_none()
- }
-}
-
-/// Creates a new stream that always immediately returns [Poll::Ready](core::task::Poll::Ready) when awaiting it.
-///
-/// This is useful when immediacy is more important than waiting for the next item to be ready.
-///
-/// # Examples
-///
-/// ```
-/// # futures::executor::block_on(async {
-/// use futures::stream::{self, StreamExt};
-/// use futures::task::Poll;
-///
-/// let mut r = stream::poll_immediate(Box::pin(stream::iter(1_u32..3)));
-/// assert_eq!(r.next().await, Some(Poll::Ready(1)));
-/// assert_eq!(r.next().await, Some(Poll::Ready(2)));
-/// assert_eq!(r.next().await, None);
-///
-/// let mut p = stream::poll_immediate(Box::pin(stream::once(async {
-/// futures::pending!();
-/// 42_u8
-/// })));
-/// assert_eq!(p.next().await, Some(Poll::Pending));
-/// assert_eq!(p.next().await, Some(Poll::Ready(42)));
-/// assert_eq!(p.next().await, None);
-/// # });
-/// ```
-pub fn poll_immediate<S: Stream>(s: S) -> PollImmediate<S> {
- super::assert_stream::<Poll<S::Item>, PollImmediate<S>>(PollImmediate { stream: Some(s) })
-}
diff --git a/src/stream/repeat.rs b/src/stream/repeat.rs
index 3f9aa87..cf9f21b 100644
--- a/src/stream/repeat.rs
+++ b/src/stream/repeat.rs
@@ -1,6 +1,6 @@
use super::assert_stream;
use core::pin::Pin;
-use futures_core::stream::{FusedStream, Stream};
+use futures_core::stream::{Stream, FusedStream};
use futures_core::task::{Context, Poll};
/// Stream for the [`repeat`] function.
@@ -25,8 +25,7 @@ pub struct Repeat<T> {
/// # });
/// ```
pub fn repeat<T>(item: T) -> Repeat<T>
-where
- T: Clone,
+ where T: Clone
{
assert_stream::<T, _>(Repeat { item })
}
@@ -34,8 +33,7 @@ where
impl<T> Unpin for Repeat<T> {}
impl<T> Stream for Repeat<T>
-where
- T: Clone,
+ where T: Clone
{
type Item = T;
@@ -49,8 +47,7 @@ where
}
impl<T> FusedStream for Repeat<T>
-where
- T: Clone,
+ where T: Clone,
{
fn is_terminated(&self) -> bool {
false
diff --git a/src/stream/repeat_with.rs b/src/stream/repeat_with.rs
index f5a81b4..0255643 100644
--- a/src/stream/repeat_with.rs
+++ b/src/stream/repeat_with.rs
@@ -1,6 +1,6 @@
use super::assert_stream;
use core::pin::Pin;
-use futures_core::stream::{FusedStream, Stream};
+use futures_core::stream::{Stream, FusedStream};
use futures_core::task::{Context, Poll};
/// An stream that repeats elements of type `A` endlessly by
@@ -28,7 +28,8 @@ impl<A, F: FnMut() -> A> Stream for RepeatWith<F> {
}
}
-impl<A, F: FnMut() -> A> FusedStream for RepeatWith<F> {
+impl<A, F: FnMut() -> A> FusedStream for RepeatWith<F>
+{
fn is_terminated(&self) -> bool {
false
}
diff --git a/src/stream/select.rs b/src/stream/select.rs
index 0c1e3af..2942494 100644
--- a/src/stream/select.rs
+++ b/src/stream/select.rs
@@ -1,5 +1,5 @@
use super::assert_stream;
-use crate::stream::{select_with_strategy, PollNext, SelectWithStrategy};
+use crate::stream::{StreamExt, Fuse};
use core::pin::Pin;
use futures_core::stream::{FusedStream, Stream};
use futures_core::task::{Context, Poll};
@@ -11,7 +11,10 @@ pin_project! {
#[must_use = "streams do nothing unless polled"]
pub struct Select<St1, St2> {
#[pin]
- inner: SelectWithStrategy<St1, St2, fn(&mut PollNext)-> PollNext, PollNext>,
+ stream1: Fuse<St1>,
+ #[pin]
+ stream2: Fuse<St2>,
+ flag: bool,
}
}
@@ -19,42 +22,20 @@ pin_project! {
/// stream will be polled in a round-robin fashion, and whenever a stream is
/// ready to yield an item that item is yielded.
///
-/// After one of the two input streams completes, the remaining one will be
+/// After one of the two input stream completes, the remaining one will be
/// polled exclusively. The returned stream completes when both input
/// streams have completed.
///
/// Note that this function consumes both streams and returns a wrapped
/// version of them.
-///
-/// ## Examples
-///
-/// ```rust
-/// # futures::executor::block_on(async {
-/// use futures::stream::{ repeat, select, StreamExt };
-///
-/// let left = repeat(1);
-/// let right = repeat(2);
-///
-/// let mut out = select(left, right);
-///
-/// for _ in 0..100 {
-/// // We should be alternating.
-/// assert_eq!(1, out.select_next_some().await);
-/// assert_eq!(2, out.select_next_some().await);
-/// }
-/// # });
-/// ```
pub fn select<St1, St2>(stream1: St1, stream2: St2) -> Select<St1, St2>
-where
- St1: Stream,
- St2: Stream<Item = St1::Item>,
+ where St1: Stream,
+ St2: Stream<Item = St1::Item>
{
- fn round_robin(last: &mut PollNext) -> PollNext {
- last.toggle()
- }
-
assert_stream::<St1::Item, _>(Select {
- inner: select_with_strategy(stream1, stream2, round_robin),
+ stream1: stream1.fuse(),
+ stream2: stream2.fuse(),
+ flag: false,
})
}
@@ -62,7 +43,7 @@ impl<St1, St2> Select<St1, St2> {
/// Acquires a reference to the underlying streams that this combinator is
/// pulling from.
pub fn get_ref(&self) -> (&St1, &St2) {
- self.inner.get_ref()
+ (self.stream1.get_ref(), self.stream2.get_ref())
}
/// Acquires a mutable reference to the underlying streams that this
@@ -71,7 +52,7 @@ impl<St1, St2> Select<St1, St2> {
/// Note that care must be taken to avoid tampering with the state of the
/// stream which may otherwise confuse this combinator.
pub fn get_mut(&mut self) -> (&mut St1, &mut St2) {
- self.inner.get_mut()
+ (self.stream1.get_mut(), self.stream2.get_mut())
}
/// Acquires a pinned mutable reference to the underlying streams that this
@@ -81,7 +62,7 @@ impl<St1, St2> Select<St1, St2> {
/// stream which may otherwise confuse this combinator.
pub fn get_pin_mut(self: Pin<&mut Self>) -> (Pin<&mut St1>, Pin<&mut St2>) {
let this = self.project();
- this.inner.get_pin_mut()
+ (this.stream1.get_pin_mut(), this.stream2.get_pin_mut())
}
/// Consumes this combinator, returning the underlying streams.
@@ -89,29 +70,61 @@ impl<St1, St2> Select<St1, St2> {
/// Note that this may discard intermediate state of this combinator, so
/// care should be taken to avoid losing resources when this is called.
pub fn into_inner(self) -> (St1, St2) {
- self.inner.into_inner()
+ (self.stream1.into_inner(), self.stream2.into_inner())
}
}
impl<St1, St2> FusedStream for Select<St1, St2>
-where
- St1: Stream,
- St2: Stream<Item = St1::Item>,
+ where St1: Stream,
+ St2: Stream<Item = St1::Item>
{
fn is_terminated(&self) -> bool {
- self.inner.is_terminated()
+ self.stream1.is_terminated() && self.stream2.is_terminated()
}
}
impl<St1, St2> Stream for Select<St1, St2>
-where
- St1: Stream,
- St2: Stream<Item = St1::Item>,
+ where St1: Stream,
+ St2: Stream<Item = St1::Item>
{
type Item = St1::Item;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<St1::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<St1::Item>> {
let this = self.project();
- this.inner.poll_next(cx)
+ if !*this.flag {
+ poll_inner(this.flag, this.stream1, this.stream2, cx)
+ } else {
+ poll_inner(this.flag, this.stream2, this.stream1, cx)
+ }
+ }
+}
+
+fn poll_inner<St1, St2>(
+ flag: &mut bool,
+ a: Pin<&mut St1>,
+ b: Pin<&mut St2>,
+ cx: &mut Context<'_>
+) -> Poll<Option<St1::Item>>
+ where St1: Stream, St2: Stream<Item = St1::Item>
+{
+ let a_done = match a.poll_next(cx) {
+ Poll::Ready(Some(item)) => {
+ // give the other stream a chance to go first next time
+ *flag = !*flag;
+ return Poll::Ready(Some(item))
+ },
+ Poll::Ready(None) => true,
+ Poll::Pending => false,
+ };
+
+ match b.poll_next(cx) {
+ Poll::Ready(Some(item)) => {
+ Poll::Ready(Some(item))
+ }
+ Poll::Ready(None) if a_done => Poll::Ready(None),
+ Poll::Ready(None) | Poll::Pending => Poll::Pending,
}
}
diff --git a/src/stream/select_all.rs b/src/stream/select_all.rs
index 3474331..c0b92fa 100644
--- a/src/stream/select_all.rs
+++ b/src/stream/select_all.rs
@@ -5,32 +5,27 @@ use core::iter::FromIterator;
use core::pin::Pin;
use futures_core::ready;
-use futures_core::stream::{FusedStream, Stream};
+use futures_core::stream::{Stream, FusedStream};
use futures_core::task::{Context, Poll};
-use pin_project_lite::pin_project;
-
use super::assert_stream;
-use crate::stream::{futures_unordered, FuturesUnordered, StreamExt, StreamFuture};
+use crate::stream::{StreamExt, StreamFuture, FuturesUnordered};
-pin_project! {
- /// An unbounded set of streams
- ///
- /// This "combinator" provides the ability to maintain a set of streams
- /// and drive them all to completion.
- ///
- /// Streams are pushed into this set and their realized values are
- /// yielded as they become ready. Streams will only be polled when they
- /// generate notifications. This allows to coordinate a large number of streams.
- ///
- /// Note that you can create a ready-made `SelectAll` via the
- /// `select_all` function in the `stream` module, or you can start with an
- /// empty set with the `SelectAll::new` constructor.
- #[must_use = "streams do nothing unless polled"]
- pub struct SelectAll<St> {
- #[pin]
- inner: FuturesUnordered<StreamFuture<St>>,
- }
+/// An unbounded set of streams
+///
+/// This "combinator" provides the ability to maintain a set of streams
+/// and drive them all to completion.
+///
+/// Streams are pushed into this set and their realized values are
+/// yielded as they become ready. Streams will only be polled when they
+/// generate notifications. This allows to coordinate a large number of streams.
+///
+/// Note that you can create a ready-made `SelectAll` via the
+/// `select_all` function in the `stream` module, or you can start with an
+/// empty set with the `SelectAll::new` constructor.
+#[must_use = "streams do nothing unless polled"]
+pub struct SelectAll<St> {
+ inner: FuturesUnordered<StreamFuture<St>>,
}
impl<St: Debug> Debug for SelectAll<St> {
@@ -69,21 +64,6 @@ impl<St: Stream + Unpin> SelectAll<St> {
pub fn push(&mut self, stream: St) {
self.inner.push(stream.into_future());
}
-
- /// Returns an iterator that allows inspecting each stream in the set.
- pub fn iter(&self) -> Iter<'_, St> {
- Iter(self.inner.iter())
- }
-
- /// Returns an iterator that allows modifying each stream in the set.
- pub fn iter_mut(&mut self) -> IterMut<'_, St> {
- IterMut(self.inner.iter_mut())
- }
-
- /// Clears the set, removing all streams.
- pub fn clear(&mut self) {
- self.inner.clear()
- }
}
impl<St: Stream + Unpin> Default for SelectAll<St> {
@@ -95,7 +75,10 @@ impl<St: Stream + Unpin> Default for SelectAll<St> {
impl<St: Stream + Unpin> Stream for SelectAll<St> {
type Item = St::Item;
- fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
loop {
match ready!(self.inner.poll_next_unpin(cx)) {
Some((Some(item), remaining)) => {
@@ -128,14 +111,13 @@ impl<St: Stream + Unpin> FusedStream for SelectAll<St> {
/// streams internally, in the order they become available.
///
/// Note that the returned set can also be used to dynamically push more
-/// streams into the set as they become available.
+/// futures into the set as they become available.
///
/// This function is only available when the `std` or `alloc` feature of this
/// library is activated, and it is activated by default.
pub fn select_all<I>(streams: I) -> SelectAll<I::Item>
-where
- I: IntoIterator,
- I::Item: Stream + Unpin,
+ where I: IntoIterator,
+ I::Item: Stream + Unpin
{
let mut set = SelectAll::new();
@@ -159,96 +141,3 @@ impl<St: Stream + Unpin> Extend<St> for SelectAll<St> {
}
}
}
-
-impl<St: Stream + Unpin> IntoIterator for SelectAll<St> {
- type Item = St;
- type IntoIter = IntoIter<St>;
-
- fn into_iter(self) -> Self::IntoIter {
- IntoIter(self.inner.into_iter())
- }
-}
-
-impl<'a, St: Stream + Unpin> IntoIterator for &'a SelectAll<St> {
- type Item = &'a St;
- type IntoIter = Iter<'a, St>;
-
- fn into_iter(self) -> Self::IntoIter {
- self.iter()
- }
-}
-
-impl<'a, St: Stream + Unpin> IntoIterator for &'a mut SelectAll<St> {
- type Item = &'a mut St;
- type IntoIter = IterMut<'a, St>;
-
- fn into_iter(self) -> Self::IntoIter {
- self.iter_mut()
- }
-}
-
-/// Immutable iterator over all streams in the unordered set.
-#[derive(Debug)]
-pub struct Iter<'a, St: Unpin>(futures_unordered::Iter<'a, StreamFuture<St>>);
-
-/// Mutable iterator over all streams in the unordered set.
-#[derive(Debug)]
-pub struct IterMut<'a, St: Unpin>(futures_unordered::IterMut<'a, StreamFuture<St>>);
-
-/// Owned iterator over all streams in the unordered set.
-#[derive(Debug)]
-pub struct IntoIter<St: Unpin>(futures_unordered::IntoIter<StreamFuture<St>>);
-
-impl<'a, St: Stream + Unpin> Iterator for Iter<'a, St> {
- type Item = &'a St;
-
- fn next(&mut self) -> Option<Self::Item> {
- let st = self.0.next()?;
- let next = st.get_ref();
- // This should always be true because FuturesUnordered removes completed futures.
- debug_assert!(next.is_some());
- next
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.0.size_hint()
- }
-}
-
-impl<St: Stream + Unpin> ExactSizeIterator for Iter<'_, St> {}
-
-impl<'a, St: Stream + Unpin> Iterator for IterMut<'a, St> {
- type Item = &'a mut St;
-
- fn next(&mut self) -> Option<Self::Item> {
- let st = self.0.next()?;
- let next = st.get_mut();
- // This should always be true because FuturesUnordered removes completed futures.
- debug_assert!(next.is_some());
- next
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.0.size_hint()
- }
-}
-
-impl<St: Stream + Unpin> ExactSizeIterator for IterMut<'_, St> {}
-
-impl<St: Stream + Unpin> Iterator for IntoIter<St> {
- type Item = St;
-
- fn next(&mut self) -> Option<Self::Item> {
- let st = self.0.next()?;
- let next = st.into_inner();
- // This should always be true because FuturesUnordered removes completed futures.
- debug_assert!(next.is_some());
- next
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.0.size_hint()
- }
-}
-
-impl<St: Stream + Unpin> ExactSizeIterator for IntoIter<St> {}
diff --git a/src/stream/select_with_strategy.rs b/src/stream/select_with_strategy.rs
deleted file mode 100644
index bd86990..0000000
--- a/src/stream/select_with_strategy.rs
+++ /dev/null
@@ -1,229 +0,0 @@
-use super::assert_stream;
-use crate::stream::{Fuse, StreamExt};
-use core::{fmt, pin::Pin};
-use futures_core::stream::{FusedStream, Stream};
-use futures_core::task::{Context, Poll};
-use pin_project_lite::pin_project;
-
-/// Type to tell [`SelectWithStrategy`] which stream to poll next.
-#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
-pub enum PollNext {
- /// Poll the first stream.
- Left,
- /// Poll the second stream.
- Right,
-}
-
-impl PollNext {
- /// Toggle the value and return the old one.
- pub fn toggle(&mut self) -> Self {
- let old = *self;
-
- match self {
- PollNext::Left => *self = PollNext::Right,
- PollNext::Right => *self = PollNext::Left,
- }
-
- old
- }
-}
-
-impl Default for PollNext {
- fn default() -> Self {
- PollNext::Left
- }
-}
-
-pin_project! {
- /// Stream for the [`select_with_strategy()`] function. See function docs for details.
- #[must_use = "streams do nothing unless polled"]
- pub struct SelectWithStrategy<St1, St2, Clos, State> {
- #[pin]
- stream1: Fuse<St1>,
- #[pin]
- stream2: Fuse<St2>,
- state: State,
- clos: Clos,
- }
-}
-
-/// This function will attempt to pull items from both streams. You provide a
-/// closure to tell [`SelectWithStrategy`] which stream to poll. The closure can
-/// store state on `SelectWithStrategy` to which it will receive a `&mut` on every
-/// invocation. This allows basing the strategy on prior choices.
-///
-/// After one of the two input streams completes, the remaining one will be
-/// polled exclusively. The returned stream completes when both input
-/// streams have completed.
-///
-/// Note that this function consumes both streams and returns a wrapped
-/// version of them.
-///
-/// ## Examples
-///
-/// ### Priority
-/// This example shows how to always prioritize the left stream.
-///
-/// ```rust
-/// # futures::executor::block_on(async {
-/// use futures::stream::{ repeat, select_with_strategy, PollNext, StreamExt };
-///
-/// let left = repeat(1);
-/// let right = repeat(2);
-///
-/// // We don't need any state, so let's make it an empty tuple.
-/// // We must provide some type here, as there is no way for the compiler
-/// // to infer it. As we don't need to capture variables, we can just
-/// // use a function pointer instead of a closure.
-/// fn prio_left(_: &mut ()) -> PollNext { PollNext::Left }
-///
-/// let mut out = select_with_strategy(left, right, prio_left);
-///
-/// for _ in 0..100 {
-/// // Whenever we poll out, we will alwas get `1`.
-/// assert_eq!(1, out.select_next_some().await);
-/// }
-/// # });
-/// ```
-///
-/// ### Round Robin
-/// This example shows how to select from both streams round robin.
-/// Note: this special case is provided by [`futures-util::stream::select`].
-///
-/// ```rust
-/// # futures::executor::block_on(async {
-/// use futures::stream::{ repeat, select_with_strategy, PollNext, StreamExt };
-///
-/// let left = repeat(1);
-/// let right = repeat(2);
-///
-/// let rrobin = |last: &mut PollNext| last.toggle();
-///
-/// let mut out = select_with_strategy(left, right, rrobin);
-///
-/// for _ in 0..100 {
-/// // We should be alternating now.
-/// assert_eq!(1, out.select_next_some().await);
-/// assert_eq!(2, out.select_next_some().await);
-/// }
-/// # });
-/// ```
-pub fn select_with_strategy<St1, St2, Clos, State>(
- stream1: St1,
- stream2: St2,
- which: Clos,
-) -> SelectWithStrategy<St1, St2, Clos, State>
-where
- St1: Stream,
- St2: Stream<Item = St1::Item>,
- Clos: FnMut(&mut State) -> PollNext,
- State: Default,
-{
- assert_stream::<St1::Item, _>(SelectWithStrategy {
- stream1: stream1.fuse(),
- stream2: stream2.fuse(),
- state: Default::default(),
- clos: which,
- })
-}
-
-impl<St1, St2, Clos, State> SelectWithStrategy<St1, St2, Clos, State> {
- /// Acquires a reference to the underlying streams that this combinator is
- /// pulling from.
- pub fn get_ref(&self) -> (&St1, &St2) {
- (self.stream1.get_ref(), self.stream2.get_ref())
- }
-
- /// Acquires a mutable reference to the underlying streams that this
- /// combinator is pulling from.
- ///
- /// Note that care must be taken to avoid tampering with the state of the
- /// stream which may otherwise confuse this combinator.
- pub fn get_mut(&mut self) -> (&mut St1, &mut St2) {
- (self.stream1.get_mut(), self.stream2.get_mut())
- }
-
- /// Acquires a pinned mutable reference to the underlying streams that this
- /// combinator is pulling from.
- ///
- /// Note that care must be taken to avoid tampering with the state of the
- /// stream which may otherwise confuse this combinator.
- pub fn get_pin_mut(self: Pin<&mut Self>) -> (Pin<&mut St1>, Pin<&mut St2>) {
- let this = self.project();
- (this.stream1.get_pin_mut(), this.stream2.get_pin_mut())
- }
-
- /// Consumes this combinator, returning the underlying streams.
- ///
- /// Note that this may discard intermediate state of this combinator, so
- /// care should be taken to avoid losing resources when this is called.
- pub fn into_inner(self) -> (St1, St2) {
- (self.stream1.into_inner(), self.stream2.into_inner())
- }
-}
-
-impl<St1, St2, Clos, State> FusedStream for SelectWithStrategy<St1, St2, Clos, State>
-where
- St1: Stream,
- St2: Stream<Item = St1::Item>,
- Clos: FnMut(&mut State) -> PollNext,
-{
- fn is_terminated(&self) -> bool {
- self.stream1.is_terminated() && self.stream2.is_terminated()
- }
-}
-
-impl<St1, St2, Clos, State> Stream for SelectWithStrategy<St1, St2, Clos, State>
-where
- St1: Stream,
- St2: Stream<Item = St1::Item>,
- Clos: FnMut(&mut State) -> PollNext,
-{
- type Item = St1::Item;
-
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<St1::Item>> {
- let this = self.project();
-
- match (this.clos)(this.state) {
- PollNext::Left => poll_inner(this.stream1, this.stream2, cx),
- PollNext::Right => poll_inner(this.stream2, this.stream1, cx),
- }
- }
-}
-
-fn poll_inner<St1, St2>(
- a: Pin<&mut St1>,
- b: Pin<&mut St2>,
- cx: &mut Context<'_>,
-) -> Poll<Option<St1::Item>>
-where
- St1: Stream,
- St2: Stream<Item = St1::Item>,
-{
- let a_done = match a.poll_next(cx) {
- Poll::Ready(Some(item)) => return Poll::Ready(Some(item)),
- Poll::Ready(None) => true,
- Poll::Pending => false,
- };
-
- match b.poll_next(cx) {
- Poll::Ready(Some(item)) => Poll::Ready(Some(item)),
- Poll::Ready(None) if a_done => Poll::Ready(None),
- Poll::Ready(None) | Poll::Pending => Poll::Pending,
- }
-}
-
-impl<St1, St2, Clos, State> fmt::Debug for SelectWithStrategy<St1, St2, Clos, State>
-where
- St1: fmt::Debug,
- St2: fmt::Debug,
- State: fmt::Debug,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("SelectWithStrategy")
- .field("stream1", &self.stream1)
- .field("stream2", &self.stream2)
- .field("state", &self.state)
- .finish()
- }
-}
diff --git a/src/stream/stream/all.rs b/src/stream/stream/all.rs
deleted file mode 100644
index ba2baa5..0000000
--- a/src/stream/stream/all.rs
+++ /dev/null
@@ -1,92 +0,0 @@
-use core::fmt;
-use core::pin::Pin;
-use futures_core::future::{FusedFuture, Future};
-use futures_core::ready;
-use futures_core::stream::Stream;
-use futures_core::task::{Context, Poll};
-use pin_project_lite::pin_project;
-
-pin_project! {
- /// Future for the [`all`](super::StreamExt::all) method.
- #[must_use = "futures do nothing unless you `.await` or poll them"]
- pub struct All<St, Fut, F> {
- #[pin]
- stream: St,
- f: F,
- accum: Option<bool>,
- #[pin]
- future: Option<Fut>,
- }
-}
-
-impl<St, Fut, F> fmt::Debug for All<St, Fut, F>
-where
- St: fmt::Debug,
- Fut: fmt::Debug,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("All")
- .field("stream", &self.stream)
- .field("accum", &self.accum)
- .field("future", &self.future)
- .finish()
- }
-}
-
-impl<St, Fut, F> All<St, Fut, F>
-where
- St: Stream,
- F: FnMut(St::Item) -> Fut,
- Fut: Future<Output = bool>,
-{
- pub(super) fn new(stream: St, f: F) -> Self {
- Self { stream, f, accum: Some(true), future: None }
- }
-}
-
-impl<St, Fut, F> FusedFuture for All<St, Fut, F>
-where
- St: Stream,
- F: FnMut(St::Item) -> Fut,
- Fut: Future<Output = bool>,
-{
- fn is_terminated(&self) -> bool {
- self.accum.is_none() && self.future.is_none()
- }
-}
-
-impl<St, Fut, F> Future for All<St, Fut, F>
-where
- St: Stream,
- F: FnMut(St::Item) -> Fut,
- Fut: Future<Output = bool>,
-{
- type Output = bool;
-
- fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<bool> {
- let mut this = self.project();
- Poll::Ready(loop {
- if let Some(fut) = this.future.as_mut().as_pin_mut() {
- // we're currently processing a future to produce a new accum value
- let acc = this.accum.unwrap() && ready!(fut.poll(cx));
- if !acc {
- break false;
- } // early exit
- *this.accum = Some(acc);
- this.future.set(None);
- } else if this.accum.is_some() {
- // we're waiting on a new item from the stream
- match ready!(this.stream.as_mut().poll_next(cx)) {
- Some(item) => {
- this.future.set(Some((this.f)(item)));
- }
- None => {
- break this.accum.take().unwrap();
- }
- }
- } else {
- panic!("All polled after completion")
- }
- })
- }
-}
diff --git a/src/stream/stream/any.rs b/src/stream/stream/any.rs
deleted file mode 100644
index f023125..0000000
--- a/src/stream/stream/any.rs
+++ /dev/null
@@ -1,92 +0,0 @@
-use core::fmt;
-use core::pin::Pin;
-use futures_core::future::{FusedFuture, Future};
-use futures_core::ready;
-use futures_core::stream::Stream;
-use futures_core::task::{Context, Poll};
-use pin_project_lite::pin_project;
-
-pin_project! {
- /// Future for the [`any`](super::StreamExt::any) method.
- #[must_use = "futures do nothing unless you `.await` or poll them"]
- pub struct Any<St, Fut, F> {
- #[pin]
- stream: St,
- f: F,
- accum: Option<bool>,
- #[pin]
- future: Option<Fut>,
- }
-}
-
-impl<St, Fut, F> fmt::Debug for Any<St, Fut, F>
-where
- St: fmt::Debug,
- Fut: fmt::Debug,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Any")
- .field("stream", &self.stream)
- .field("accum", &self.accum)
- .field("future", &self.future)
- .finish()
- }
-}
-
-impl<St, Fut, F> Any<St, Fut, F>
-where
- St: Stream,
- F: FnMut(St::Item) -> Fut,
- Fut: Future<Output = bool>,
-{
- pub(super) fn new(stream: St, f: F) -> Self {
- Self { stream, f, accum: Some(false), future: None }
- }
-}
-
-impl<St, Fut, F> FusedFuture for Any<St, Fut, F>
-where
- St: Stream,
- F: FnMut(St::Item) -> Fut,
- Fut: Future<Output = bool>,
-{
- fn is_terminated(&self) -> bool {
- self.accum.is_none() && self.future.is_none()
- }
-}
-
-impl<St, Fut, F> Future for Any<St, Fut, F>
-where
- St: Stream,
- F: FnMut(St::Item) -> Fut,
- Fut: Future<Output = bool>,
-{
- type Output = bool;
-
- fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<bool> {
- let mut this = self.project();
- Poll::Ready(loop {
- if let Some(fut) = this.future.as_mut().as_pin_mut() {
- // we're currently processing a future to produce a new accum value
- let acc = this.accum.unwrap() || ready!(fut.poll(cx));
- if acc {
- break true;
- } // early exit
- *this.accum = Some(acc);
- this.future.set(None);
- } else if this.accum.is_some() {
- // we're waiting on a new item from the stream
- match ready!(this.stream.as_mut().poll_next(cx)) {
- Some(item) => {
- this.future.set(Some((this.f)(item)));
- }
- None => {
- break this.accum.take().unwrap();
- }
- }
- } else {
- panic!("Any polled after completion")
- }
- })
- }
-}
diff --git a/src/stream/stream/buffer_unordered.rs b/src/stream/stream/buffer_unordered.rs
index d64c142..de42cfd 100644
--- a/src/stream/stream/buffer_unordered.rs
+++ b/src/stream/stream/buffer_unordered.rs
@@ -1,12 +1,12 @@
use crate::stream::{Fuse, FuturesUnordered, StreamExt};
-use core::fmt;
-use core::pin::Pin;
use futures_core::future::Future;
-use futures_core::stream::{FusedStream, Stream};
+use futures_core::stream::{Stream, FusedStream};
use futures_core::task::{Context, Poll};
#[cfg(feature = "sink")]
use futures_sink::Sink;
use pin_project_lite::pin_project;
+use core::fmt;
+use core::pin::Pin;
pin_project! {
/// Stream for the [`buffer_unordered`](super::StreamExt::buffer_unordered)
@@ -63,7 +63,10 @@ where
{
type Item = <St::Item as Future>::Output;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
let mut this = self.project();
// First up, try to spawn off as many futures as possible by filling up
diff --git a/src/stream/stream/buffered.rs b/src/stream/stream/buffered.rs
index 6052a73..1af9f49 100644
--- a/src/stream/stream/buffered.rs
+++ b/src/stream/stream/buffered.rs
@@ -1,6 +1,4 @@
use crate::stream::{Fuse, FuturesOrdered, StreamExt};
-use core::fmt;
-use core::pin::Pin;
use futures_core::future::Future;
use futures_core::ready;
use futures_core::stream::Stream;
@@ -8,6 +6,8 @@ use futures_core::task::{Context, Poll};
#[cfg(feature = "sink")]
use futures_sink::Sink;
use pin_project_lite::pin_project;
+use core::fmt;
+use core::pin::Pin;
pin_project! {
/// Stream for the [`buffered`](super::StreamExt::buffered) method.
@@ -44,7 +44,11 @@ where
St::Item: Future,
{
pub(super) fn new(stream: St, n: usize) -> Self {
- Self { stream: super::Fuse::new(stream), in_progress_queue: FuturesOrdered::new(), max: n }
+ Self {
+ stream: super::Fuse::new(stream),
+ in_progress_queue: FuturesOrdered::new(),
+ max: n,
+ }
}
delegate_access_inner!(stream, St, (.));
@@ -57,7 +61,10 @@ where
{
type Item = <St::Item as Future>::Output;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
let mut this = self.project();
// First up, try to spawn off as many futures as possible by filling up
@@ -72,7 +79,7 @@ where
// Attempt to pull the next value from the in_progress_queue
let res = this.in_progress_queue.poll_next_unpin(cx);
if let Some(val) = ready!(res) {
- return Poll::Ready(Some(val));
+ return Poll::Ready(Some(val))
}
// If more values are still coming from the stream, we're not done yet
diff --git a/src/stream/stream/catch_unwind.rs b/src/stream/stream/catch_unwind.rs
index 09a6dc1..d87a40a 100644
--- a/src/stream/stream/catch_unwind.rs
+++ b/src/stream/stream/catch_unwind.rs
@@ -1,9 +1,9 @@
-use futures_core::stream::{FusedStream, Stream};
+use futures_core::stream::{Stream, FusedStream};
use futures_core::task::{Context, Poll};
use pin_project_lite::pin_project;
use std::any::Any;
-use std::panic::{catch_unwind, AssertUnwindSafe, UnwindSafe};
use std::pin::Pin;
+use std::panic::{catch_unwind, UnwindSafe, AssertUnwindSafe};
pin_project! {
/// Stream for the [`catch_unwind`](super::StreamExt::catch_unwind) method.
@@ -27,20 +27,25 @@ impl<St: Stream + UnwindSafe> CatchUnwind<St> {
impl<St: Stream + UnwindSafe> Stream for CatchUnwind<St> {
type Item = Result<St::Item, Box<dyn Any + Send>>;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
let mut this = self.project();
if *this.caught_unwind {
Poll::Ready(None)
} else {
- let res = catch_unwind(AssertUnwindSafe(|| this.stream.as_mut().poll_next(cx)));
+ let res = catch_unwind(AssertUnwindSafe(|| {
+ this.stream.as_mut().poll_next(cx)
+ }));
match res {
Ok(poll) => poll.map(|opt| opt.map(Ok)),
Err(e) => {
*this.caught_unwind = true;
Poll::Ready(Some(Err(e)))
- }
+ },
}
}
}
diff --git a/src/stream/stream/chain.rs b/src/stream/stream/chain.rs
index c5da35e..2be7104 100644
--- a/src/stream/stream/chain.rs
+++ b/src/stream/stream/chain.rs
@@ -18,19 +18,20 @@ pin_project! {
// All interactions with `Pin<&mut Chain<..>>` happen through these methods
impl<St1, St2> Chain<St1, St2>
-where
- St1: Stream,
- St2: Stream<Item = St1::Item>,
+where St1: Stream,
+ St2: Stream<Item = St1::Item>,
{
pub(super) fn new(stream1: St1, stream2: St2) -> Self {
- Self { first: Some(stream1), second: stream2 }
+ Self {
+ first: Some(stream1),
+ second: stream2,
+ }
}
}
impl<St1, St2> FusedStream for Chain<St1, St2>
-where
- St1: Stream,
- St2: FusedStream<Item = St1::Item>,
+where St1: Stream,
+ St2: FusedStream<Item=St1::Item>,
{
fn is_terminated(&self) -> bool {
self.first.is_none() && self.second.is_terminated()
@@ -38,17 +39,19 @@ where
}
impl<St1, St2> Stream for Chain<St1, St2>
-where
- St1: Stream,
- St2: Stream<Item = St1::Item>,
+where St1: Stream,
+ St2: Stream<Item=St1::Item>,
{
type Item = St1::Item;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
let mut this = self.project();
if let Some(first) = this.first.as_mut().as_pin_mut() {
if let Some(item) = ready!(first.poll_next(cx)) {
- return Poll::Ready(Some(item));
+ return Poll::Ready(Some(item))
}
}
this.first.set(None);
@@ -64,7 +67,7 @@ where
let upper = match (first_upper, second_upper) {
(Some(x), Some(y)) => x.checked_add(y),
- _ => None,
+ _ => None
};
(lower, upper)
diff --git a/src/stream/stream/chunks.rs b/src/stream/stream/chunks.rs
index 8457869..45a3212 100644
--- a/src/stream/stream/chunks.rs
+++ b/src/stream/stream/chunks.rs
@@ -1,13 +1,13 @@
use crate::stream::Fuse;
-use alloc::vec::Vec;
-use core::mem;
-use core::pin::Pin;
use futures_core::ready;
-use futures_core::stream::{FusedStream, Stream};
+use futures_core::stream::{Stream, FusedStream};
use futures_core::task::{Context, Poll};
#[cfg(feature = "sink")]
use futures_sink::Sink;
use pin_project_lite::pin_project;
+use core::mem;
+use core::pin::Pin;
+use alloc::vec::Vec;
pin_project! {
/// Stream for the [`chunks`](super::StreamExt::chunks) method.
@@ -21,10 +21,7 @@ pin_project! {
}
}
-impl<St: Stream> Chunks<St>
-where
- St: Stream,
-{
+impl<St: Stream> Chunks<St> where St: Stream {
pub(super) fn new(stream: St, capacity: usize) -> Self {
assert!(capacity > 0);
@@ -46,7 +43,10 @@ where
impl<St: Stream> Stream for Chunks<St> {
type Item = Vec<St::Item>;
- fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
let mut this = self.as_mut().project();
loop {
match ready!(this.stream.as_mut().poll_next(cx)) {
@@ -56,7 +56,7 @@ impl<St: Stream> Stream for Chunks<St> {
Some(item) => {
this.items.push(item);
if this.items.len() >= *this.cap {
- return Poll::Ready(Some(self.take()));
+ return Poll::Ready(Some(self.take()))
}
}
diff --git a/src/stream/stream/collect.rs b/src/stream/stream/collect.rs
index b0e81b9..774b34b 100644
--- a/src/stream/stream/collect.rs
+++ b/src/stream/stream/collect.rs
@@ -23,14 +23,16 @@ impl<St: Stream, C: Default> Collect<St, C> {
}
pub(super) fn new(stream: St) -> Self {
- Self { stream, collection: Default::default() }
+ Self {
+ stream,
+ collection: Default::default(),
+ }
}
}
impl<St, C> FusedFuture for Collect<St, C>
-where
- St: FusedStream,
- C: Default + Extend<St::Item>,
+where St: FusedStream,
+ C: Default + Extend<St:: Item>
{
fn is_terminated(&self) -> bool {
self.stream.is_terminated()
@@ -38,9 +40,8 @@ where
}
impl<St, C> Future for Collect<St, C>
-where
- St: Stream,
- C: Default + Extend<St::Item>,
+where St: Stream,
+ C: Default + Extend<St:: Item>
{
type Output = C;
diff --git a/src/stream/stream/concat.rs b/src/stream/stream/concat.rs
index 7e058b2..ee1349f 100644
--- a/src/stream/stream/concat.rs
+++ b/src/stream/stream/concat.rs
@@ -1,7 +1,7 @@
use core::pin::Pin;
-use futures_core::future::{FusedFuture, Future};
+use futures_core::future::{Future, FusedFuture};
use futures_core::ready;
-use futures_core::stream::{FusedStream, Stream};
+use futures_core::stream::{Stream, FusedStream};
use futures_core::task::{Context, Poll};
use pin_project_lite::pin_project;
@@ -17,28 +17,35 @@ pin_project! {
}
impl<St> Concat<St>
-where
- St: Stream,
- St::Item: Extend<<St::Item as IntoIterator>::Item> + IntoIterator + Default,
+where St: Stream,
+ St::Item: Extend<<St::Item as IntoIterator>::Item> +
+ IntoIterator + Default,
{
pub(super) fn new(stream: St) -> Self {
- Self { stream, accum: None }
+ Self {
+ stream,
+ accum: None,
+ }
}
}
impl<St> Future for Concat<St>
-where
- St: Stream,
- St::Item: Extend<<St::Item as IntoIterator>::Item> + IntoIterator + Default,
+where St: Stream,
+ St::Item: Extend<<St::Item as IntoIterator>::Item> +
+ IntoIterator + Default,
{
type Output = St::Item;
- fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ fn poll(
+ self: Pin<&mut Self>, cx: &mut Context<'_>
+ ) -> Poll<Self::Output> {
let mut this = self.project();
loop {
match ready!(this.stream.as_mut().poll_next(cx)) {
- None => return Poll::Ready(this.accum.take().unwrap_or_default()),
+ None => {
+ return Poll::Ready(this.accum.take().unwrap_or_default())
+ }
Some(e) => {
if let Some(a) = this.accum {
a.extend(e)
@@ -52,9 +59,9 @@ where
}
impl<St> FusedFuture for Concat<St>
-where
- St: FusedStream,
- St::Item: Extend<<St::Item as IntoIterator>::Item> + IntoIterator + Default,
+where St: FusedStream,
+ St::Item: Extend<<St::Item as IntoIterator>::Item> +
+ IntoIterator + Default,
{
fn is_terminated(&self) -> bool {
self.accum.is_none() && self.stream.is_terminated()
diff --git a/src/stream/stream/count.rs b/src/stream/stream/count.rs
deleted file mode 100644
index 513cab7..0000000
--- a/src/stream/stream/count.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-use core::fmt;
-use core::pin::Pin;
-use futures_core::future::{FusedFuture, Future};
-use futures_core::ready;
-use futures_core::stream::{FusedStream, Stream};
-use futures_core::task::{Context, Poll};
-use pin_project_lite::pin_project;
-
-pin_project! {
- /// Future for the [`count`](super::StreamExt::count) method.
- #[must_use = "futures do nothing unless you `.await` or poll them"]
- pub struct Count<St> {
- #[pin]
- stream: St,
- count: usize
- }
-}
-
-impl<St> fmt::Debug for Count<St>
-where
- St: fmt::Debug,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Count").field("stream", &self.stream).field("count", &self.count).finish()
- }
-}
-
-impl<St: Stream> Count<St> {
- pub(super) fn new(stream: St) -> Self {
- Self { stream, count: 0 }
- }
-}
-
-impl<St: FusedStream> FusedFuture for Count<St> {
- fn is_terminated(&self) -> bool {
- self.stream.is_terminated()
- }
-}
-
-impl<St: Stream> Future for Count<St> {
- type Output = usize;
-
- fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- let mut this = self.project();
-
- Poll::Ready(loop {
- match ready!(this.stream.as_mut().poll_next(cx)) {
- Some(_) => *this.count += 1,
- None => break *this.count,
- }
- })
- }
-}
diff --git a/src/stream/stream/cycle.rs b/src/stream/stream/cycle.rs
index 507431d..a5b7dc0 100644
--- a/src/stream/stream/cycle.rs
+++ b/src/stream/stream/cycle.rs
@@ -21,7 +21,10 @@ where
St: Clone + Stream,
{
pub(super) fn new(stream: St) -> Self {
- Self { orig: stream.clone(), stream }
+ Self {
+ orig: stream.clone(),
+ stream,
+ }
}
}
diff --git a/src/stream/stream/enumerate.rs b/src/stream/stream/enumerate.rs
index 1cf9d49..7d4c9cb 100644
--- a/src/stream/stream/enumerate.rs
+++ b/src/stream/stream/enumerate.rs
@@ -19,7 +19,10 @@ pin_project! {
impl<St: Stream> Enumerate<St> {
pub(super) fn new(stream: St) -> Self {
- Self { stream, count: 0 }
+ Self {
+ stream,
+ count: 0,
+ }
}
delegate_access_inner!(stream, St, ());
@@ -34,7 +37,10 @@ impl<St: Stream + FusedStream> FusedStream for Enumerate<St> {
impl<St: Stream> Stream for Enumerate<St> {
type Item = (usize, St::Item);
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
let this = self.project();
match ready!(this.stream.poll_next(cx)) {
diff --git a/src/stream/stream/filter.rs b/src/stream/stream/filter.rs
index ccf1a51..57de025 100644
--- a/src/stream/stream/filter.rs
+++ b/src/stream/stream/filter.rs
@@ -1,4 +1,3 @@
-use crate::fns::FnMut1;
use core::fmt;
use core::pin::Pin;
use futures_core::future::Future;
@@ -8,6 +7,7 @@ use futures_core::task::{Context, Poll};
#[cfg(feature = "sink")]
use futures_sink::Sink;
use pin_project_lite::pin_project;
+use crate::fns::FnMut1;
pin_project! {
/// Stream for the [`filter`](super::StreamExt::filter) method.
@@ -41,23 +41,26 @@ where
#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
impl<St, Fut, F> Filter<St, Fut, F>
-where
- St: Stream,
- F: for<'a> FnMut1<&'a St::Item, Output = Fut>,
- Fut: Future<Output = bool>,
+where St: Stream,
+ F: for<'a> FnMut1<&'a St::Item, Output=Fut>,
+ Fut: Future<Output = bool>,
{
pub(super) fn new(stream: St, f: F) -> Self {
- Self { stream, f, pending_fut: None, pending_item: None }
+ Self {
+ stream,
+ f,
+ pending_fut: None,
+ pending_item: None,
+ }
}
delegate_access_inner!(stream, St, ());
}
impl<St, Fut, F> FusedStream for Filter<St, Fut, F>
-where
- St: Stream + FusedStream,
- F: FnMut(&St::Item) -> Fut,
- Fut: Future<Output = bool>,
+ where St: Stream + FusedStream,
+ F: FnMut(&St::Item) -> Fut,
+ Fut: Future<Output = bool>,
{
fn is_terminated(&self) -> bool {
self.pending_fut.is_none() && self.stream.is_terminated()
@@ -66,14 +69,16 @@ where
#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
impl<St, Fut, F> Stream for Filter<St, Fut, F>
-where
- St: Stream,
- F: for<'a> FnMut1<&'a St::Item, Output = Fut>,
- Fut: Future<Output = bool>,
+ where St: Stream,
+ F: for<'a> FnMut1<&'a St::Item, Output=Fut>,
+ Fut: Future<Output = bool>,
{
type Item = St::Item;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<St::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<St::Item>> {
let mut this = self.project();
Poll::Ready(loop {
if let Some(fut) = this.pending_fut.as_mut().as_pin_mut() {
@@ -106,10 +111,9 @@ where
// Forwarding impl of Sink from the underlying stream
#[cfg(feature = "sink")]
impl<S, Fut, F, Item> Sink<Item> for Filter<S, Fut, F>
-where
- S: Stream + Sink<Item>,
- F: FnMut(&S::Item) -> Fut,
- Fut: Future<Output = bool>,
+ where S: Stream + Sink<Item>,
+ F: FnMut(&S::Item) -> Fut,
+ Fut: Future<Output = bool>,
{
type Error = S::Error;
diff --git a/src/stream/stream/filter_map.rs b/src/stream/stream/filter_map.rs
index 02a0a43..b762fac 100644
--- a/src/stream/stream/filter_map.rs
+++ b/src/stream/stream/filter_map.rs
@@ -1,4 +1,3 @@
-use crate::fns::FnMut1;
use core::fmt;
use core::pin::Pin;
use futures_core::future::Future;
@@ -8,6 +7,7 @@ use futures_core::task::{Context, Poll};
#[cfg(feature = "sink")]
use futures_sink::Sink;
use pin_project_lite::pin_project;
+use crate::fns::FnMut1;
pin_project! {
/// Stream for the [`filter_map`](super::StreamExt::filter_map) method.
@@ -35,10 +35,9 @@ where
}
impl<St, Fut, F> FilterMap<St, Fut, F>
-where
- St: Stream,
- F: FnMut(St::Item) -> Fut,
- Fut: Future,
+ where St: Stream,
+ F: FnMut(St::Item) -> Fut,
+ Fut: Future,
{
pub(super) fn new(stream: St, f: F) -> Self {
Self { stream, f, pending: None }
@@ -48,10 +47,9 @@ where
}
impl<St, Fut, F, T> FusedStream for FilterMap<St, Fut, F>
-where
- St: Stream + FusedStream,
- F: FnMut1<St::Item, Output = Fut>,
- Fut: Future<Output = Option<T>>,
+ where St: Stream + FusedStream,
+ F: FnMut1<St::Item, Output=Fut>,
+ Fut: Future<Output = Option<T>>,
{
fn is_terminated(&self) -> bool {
self.pending.is_none() && self.stream.is_terminated()
@@ -59,14 +57,16 @@ where
}
impl<St, Fut, F, T> Stream for FilterMap<St, Fut, F>
-where
- St: Stream,
- F: FnMut1<St::Item, Output = Fut>,
- Fut: Future<Output = Option<T>>,
+ where St: Stream,
+ F: FnMut1<St::Item, Output=Fut>,
+ Fut: Future<Output = Option<T>>,
{
type Item = T;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<T>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<T>> {
let mut this = self.project();
Poll::Ready(loop {
if let Some(p) = this.pending.as_mut().as_pin_mut() {
@@ -100,10 +100,9 @@ where
// Forwarding impl of Sink from the underlying stream
#[cfg(feature = "sink")]
impl<S, Fut, F, Item> Sink<Item> for FilterMap<S, Fut, F>
-where
- S: Stream + Sink<Item>,
- F: FnMut1<S::Item, Output = Fut>,
- Fut: Future,
+ where S: Stream + Sink<Item>,
+ F: FnMut1<S::Item, Output=Fut>,
+ Fut: Future,
{
type Error = S::Error;
diff --git a/src/stream/stream/flatten_unordered.rs b/src/stream/stream/flatten_unordered.rs
deleted file mode 100644
index 07f971c..0000000
--- a/src/stream/stream/flatten_unordered.rs
+++ /dev/null
@@ -1,509 +0,0 @@
-use alloc::sync::Arc;
-use core::{
- cell::UnsafeCell,
- convert::identity,
- fmt,
- num::NonZeroUsize,
- pin::Pin,
- sync::atomic::{AtomicU8, Ordering},
-};
-
-use pin_project_lite::pin_project;
-
-use futures_core::{
- future::Future,
- ready,
- stream::{FusedStream, Stream},
- task::{Context, Poll, Waker},
-};
-#[cfg(feature = "sink")]
-use futures_sink::Sink;
-use futures_task::{waker, ArcWake};
-
-use crate::stream::FuturesUnordered;
-
-/// There is nothing to poll and stream isn't being
-/// polled or waking at the moment.
-const NONE: u8 = 0;
-
-/// Inner streams need to be polled.
-const NEED_TO_POLL_INNER_STREAMS: u8 = 1;
-
-/// The base stream needs to be polled.
-const NEED_TO_POLL_STREAM: u8 = 0b10;
-
-/// It needs to poll base stream and inner streams.
-const NEED_TO_POLL_ALL: u8 = NEED_TO_POLL_INNER_STREAMS | NEED_TO_POLL_STREAM;
-
-/// The current stream is being polled at the moment.
-const POLLING: u8 = 0b100;
-
-/// Inner streams are being woken at the moment.
-const WAKING_INNER_STREAMS: u8 = 0b1000;
-
-/// The base stream is being woken at the moment.
-const WAKING_STREAM: u8 = 0b10000;
-
-/// The base stream and inner streams are being woken at the moment.
-const WAKING_ALL: u8 = WAKING_STREAM | WAKING_INNER_STREAMS;
-
-/// The stream was waked and will be polled.
-const WOKEN: u8 = 0b100000;
-
-/// Determines what needs to be polled, and is stream being polled at the
-/// moment or not.
-#[derive(Clone, Debug)]
-struct SharedPollState {
- state: Arc<AtomicU8>,
-}
-
-impl SharedPollState {
- /// Constructs new `SharedPollState` with the given state.
- fn new(value: u8) -> SharedPollState {
- SharedPollState { state: Arc::new(AtomicU8::new(value)) }
- }
-
- /// Attempts to start polling, returning stored state in case of success.
- /// Returns `None` if some waker is waking at the moment.
- fn start_polling(
- &self,
- ) -> Option<(u8, PollStateBomb<'_, impl FnOnce(&SharedPollState) -> u8>)> {
- let value = self
- .state
- .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |value| {
- if value & WAKING_ALL == NONE {
- Some(POLLING)
- } else {
- None
- }
- })
- .ok()?;
- let bomb = PollStateBomb::new(self, SharedPollState::reset);
-
- Some((value, bomb))
- }
-
- /// Starts the waking process and performs bitwise or with the given value.
- fn start_waking(
- &self,
- to_poll: u8,
- waking: u8,
- ) -> Option<(u8, PollStateBomb<'_, impl FnOnce(&SharedPollState) -> u8>)> {
- let value = self
- .state
- .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |value| {
- // Waking process for this waker already started
- if value & waking != NONE {
- return None;
- }
- let mut next_value = value | to_poll;
- // Only start the waking process if we're not in the polling phase and the stream isn't woken already
- if value & (WOKEN | POLLING) == NONE {
- next_value |= waking;
- }
-
- if next_value != value {
- Some(next_value)
- } else {
- None
- }
- })
- .ok()?;
-
- if value & (WOKEN | POLLING) == NONE {
- let bomb = PollStateBomb::new(self, move |state| state.stop_waking(waking));
-
- Some((value, bomb))
- } else {
- None
- }
- }
-
- /// Sets current state to
- /// - `!POLLING` allowing to use wakers
- /// - `WOKEN` if the state was changed during `POLLING` phase as waker will be called,
- /// or `will_be_woken` flag supplied
- /// - `!WAKING_ALL` as
- /// * Wakers called during the `POLLING` phase won't propagate their calls
- /// * `POLLING` phase can't start if some of the wakers are active
- /// So no wrapped waker can touch the inner waker's cell, it's safe to poll again.
- fn stop_polling(&self, to_poll: u8, will_be_woken: bool) -> u8 {
- self.state
- .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |mut value| {
- let mut next_value = to_poll;
-
- value &= NEED_TO_POLL_ALL;
- if value != NONE || will_be_woken {
- next_value |= WOKEN;
- }
- next_value |= value;
-
- Some(next_value & !POLLING & !WAKING_ALL)
- })
- .unwrap()
- }
-
- /// Toggles state to non-waking, allowing to start polling.
- fn stop_waking(&self, waking: u8) -> u8 {
- self.state
- .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |value| {
- let mut next_value = value & !waking;
- // Waker will be called only if the current waking state is the same as the specified waker state
- if value & WAKING_ALL == waking {
- next_value |= WOKEN;
- }
-
- if next_value != value {
- Some(next_value)
- } else {
- None
- }
- })
- .unwrap_or_else(identity)
- }
-
- /// Resets current state allowing to poll the stream and wake up wakers.
- fn reset(&self) -> u8 {
- self.state.swap(NEED_TO_POLL_ALL, Ordering::AcqRel)
- }
-}
-
-/// Used to execute some function on the given state when dropped.
-struct PollStateBomb<'a, F: FnOnce(&SharedPollState) -> u8> {
- state: &'a SharedPollState,
- drop: Option<F>,
-}
-
-impl<'a, F: FnOnce(&SharedPollState) -> u8> PollStateBomb<'a, F> {
- /// Constructs new bomb with the given state.
- fn new(state: &'a SharedPollState, drop: F) -> Self {
- Self { state, drop: Some(drop) }
- }
-
- /// Deactivates bomb, forces it to not call provided function when dropped.
- fn deactivate(mut self) {
- self.drop.take();
- }
-
- /// Manually fires the bomb, returning supplied state.
- fn fire(mut self) -> Option<u8> {
- self.drop.take().map(|drop| (drop)(self.state))
- }
-}
-
-impl<F: FnOnce(&SharedPollState) -> u8> Drop for PollStateBomb<'_, F> {
- fn drop(&mut self) {
- if let Some(drop) = self.drop.take() {
- (drop)(self.state);
- }
- }
-}
-
-/// Will update state with the provided value on `wake_by_ref` call
-/// and then, if there is a need, call `inner_waker`.
-struct InnerWaker {
- inner_waker: UnsafeCell<Option<Waker>>,
- poll_state: SharedPollState,
- need_to_poll: u8,
-}
-
-unsafe impl Send for InnerWaker {}
-unsafe impl Sync for InnerWaker {}
-
-impl InnerWaker {
- /// Replaces given waker's inner_waker for polling stream/futures which will
- /// update poll state on `wake_by_ref` call. Use only if you need several
- /// contexts.
- ///
- /// ## Safety
- ///
- /// This function will modify waker's `inner_waker` via `UnsafeCell`, so
- /// it should be used only during `POLLING` phase.
- unsafe fn replace_waker(self_arc: &mut Arc<Self>, cx: &Context<'_>) -> Waker {
- *self_arc.inner_waker.get() = cx.waker().clone().into();
- waker(self_arc.clone())
- }
-
- /// Attempts to start the waking process for the waker with the given value.
- /// If succeeded, then the stream isn't yet woken and not being polled at the moment.
- fn start_waking(&self) -> Option<(u8, PollStateBomb<'_, impl FnOnce(&SharedPollState) -> u8>)> {
- self.poll_state.start_waking(self.need_to_poll, self.waking_state())
- }
-
- /// Returns the corresponding waking state toggled by this waker.
- fn waking_state(&self) -> u8 {
- self.need_to_poll << 3
- }
-}
-
-impl ArcWake for InnerWaker {
- fn wake_by_ref(self_arc: &Arc<Self>) {
- if let Some((_, state_bomb)) = self_arc.start_waking() {
- // Safety: now state is not `POLLING`
- let waker_opt = unsafe { self_arc.inner_waker.get().as_ref().unwrap() };
-
- if let Some(inner_waker) = waker_opt.clone() {
- // Stop waking to allow polling stream
- let poll_state_value = state_bomb.fire().unwrap();
-
- // Here we want to call waker only if stream isn't woken yet and
- // also to optimize the case when two wakers are called at the same time.
- //
- // In this case the best strategy will be to propagate only the latest waker's awake,
- // and then poll both entities in a single `poll_next` call
- if poll_state_value & (WOKEN | WAKING_ALL) == self_arc.waking_state() {
- // Wake up inner waker
- inner_waker.wake();
- }
- }
- }
- }
-}
-
-pin_project! {
- /// Future which contains optional stream.
- ///
- /// If it's `Some`, it will attempt to call `poll_next` on it,
- /// returning `Some((item, next_item_fut))` in case of `Poll::Ready(Some(...))`
- /// or `None` in case of `Poll::Ready(None)`.
- ///
- /// If `poll_next` will return `Poll::Pending`, it will be forwarded to
- /// the future and current task will be notified by waker.
- #[must_use = "futures do nothing unless you `.await` or poll them"]
- struct PollStreamFut<St> {
- #[pin]
- stream: Option<St>,
- }
-}
-
-impl<St> PollStreamFut<St> {
- /// Constructs new `PollStreamFut` using given `stream`.
- fn new(stream: impl Into<Option<St>>) -> Self {
- Self { stream: stream.into() }
- }
-}
-
-impl<St: Stream + Unpin> Future for PollStreamFut<St> {
- type Output = Option<(St::Item, PollStreamFut<St>)>;
-
- fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- let mut stream = self.project().stream;
-
- let item = if let Some(stream) = stream.as_mut().as_pin_mut() {
- ready!(stream.poll_next(cx))
- } else {
- None
- };
- let next_item_fut = PollStreamFut::new(stream.get_mut().take());
- let out = item.map(|item| (item, next_item_fut));
-
- Poll::Ready(out)
- }
-}
-
-pin_project! {
- /// Stream for the [`flatten_unordered`](super::StreamExt::flatten_unordered)
- /// method.
- #[project = FlattenUnorderedProj]
- #[must_use = "streams do nothing unless polled"]
- pub struct FlattenUnordered<St> where St: Stream {
- #[pin]
- inner_streams: FuturesUnordered<PollStreamFut<St::Item>>,
- #[pin]
- stream: St,
- poll_state: SharedPollState,
- limit: Option<NonZeroUsize>,
- is_stream_done: bool,
- inner_streams_waker: Arc<InnerWaker>,
- stream_waker: Arc<InnerWaker>,
- }
-}
-
-impl<St> fmt::Debug for FlattenUnordered<St>
-where
- St: Stream + fmt::Debug,
- St::Item: Stream + fmt::Debug,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("FlattenUnordered")
- .field("poll_state", &self.poll_state)
- .field("inner_streams", &self.inner_streams)
- .field("limit", &self.limit)
- .field("stream", &self.stream)
- .field("is_stream_done", &self.is_stream_done)
- .finish()
- }
-}
-
-impl<St> FlattenUnordered<St>
-where
- St: Stream,
- St::Item: Stream + Unpin,
-{
- pub(super) fn new(stream: St, limit: Option<usize>) -> FlattenUnordered<St> {
- let poll_state = SharedPollState::new(NEED_TO_POLL_STREAM);
-
- FlattenUnordered {
- inner_streams: FuturesUnordered::new(),
- stream,
- is_stream_done: false,
- limit: limit.and_then(NonZeroUsize::new),
- inner_streams_waker: Arc::new(InnerWaker {
- inner_waker: UnsafeCell::new(None),
- poll_state: poll_state.clone(),
- need_to_poll: NEED_TO_POLL_INNER_STREAMS,
- }),
- stream_waker: Arc::new(InnerWaker {
- inner_waker: UnsafeCell::new(None),
- poll_state: poll_state.clone(),
- need_to_poll: NEED_TO_POLL_STREAM,
- }),
- poll_state,
- }
- }
-
- delegate_access_inner!(stream, St, ());
-}
-
-impl<St> FlattenUnorderedProj<'_, St>
-where
- St: Stream,
-{
- /// Checks if current `inner_streams` size is less than optional limit.
- fn is_exceeded_limit(&self) -> bool {
- self.limit.map_or(false, |limit| self.inner_streams.len() >= limit.get())
- }
-}
-
-impl<St> FusedStream for FlattenUnordered<St>
-where
- St: FusedStream,
- St::Item: FusedStream + Unpin,
-{
- fn is_terminated(&self) -> bool {
- self.stream.is_terminated() && self.inner_streams.is_empty()
- }
-}
-
-impl<St> Stream for FlattenUnordered<St>
-where
- St: Stream,
- St::Item: Stream + Unpin,
-{
- type Item = <St::Item as Stream>::Item;
-
- fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
- let mut next_item = None;
- let mut need_to_poll_next = NONE;
-
- let mut this = self.as_mut().project();
-
- let (mut poll_state_value, state_bomb) = match this.poll_state.start_polling() {
- Some(value) => value,
- _ => {
- // Waker was called, just wait for the next poll
- return Poll::Pending;
- }
- };
-
- if poll_state_value & NEED_TO_POLL_STREAM != NONE {
- // Safety: now state is `POLLING`.
- let stream_waker = unsafe { InnerWaker::replace_waker(this.stream_waker, cx) };
-
- // Here we need to poll the base stream.
- //
- // To improve performance, we will attempt to place as many items as we can
- // to the `FuturesUnordered` bucket before polling inner streams
- loop {
- if this.is_exceeded_limit() || *this.is_stream_done {
- // We either exceeded the limit or the stream is exhausted
- if !*this.is_stream_done {
- // The stream needs to be polled in the next iteration
- need_to_poll_next |= NEED_TO_POLL_STREAM;
- }
-
- break;
- } else {
- match this.stream.as_mut().poll_next(&mut Context::from_waker(&stream_waker)) {
- Poll::Ready(Some(inner_stream)) => {
- // Add new stream to the inner streams bucket
- this.inner_streams.as_mut().push(PollStreamFut::new(inner_stream));
- // Inner streams must be polled afterward
- poll_state_value |= NEED_TO_POLL_INNER_STREAMS;
- }
- Poll::Ready(None) => {
- // Mark the stream as done
- *this.is_stream_done = true;
- }
- Poll::Pending => {
- break;
- }
- }
- }
- }
- }
-
- if poll_state_value & NEED_TO_POLL_INNER_STREAMS != NONE {
- // Safety: now state is `POLLING`.
- let inner_streams_waker =
- unsafe { InnerWaker::replace_waker(this.inner_streams_waker, cx) };
-
- match this
- .inner_streams
- .as_mut()
- .poll_next(&mut Context::from_waker(&inner_streams_waker))
- {
- Poll::Ready(Some(Some((item, next_item_fut)))) => {
- // Push next inner stream item future to the list of inner streams futures
- this.inner_streams.as_mut().push(next_item_fut);
- // Take the received item
- next_item = Some(item);
- // On the next iteration, inner streams must be polled again
- need_to_poll_next |= NEED_TO_POLL_INNER_STREAMS;
- }
- Poll::Ready(Some(None)) => {
- // On the next iteration, inner streams must be polled again
- need_to_poll_next |= NEED_TO_POLL_INNER_STREAMS;
- }
- _ => {}
- }
- }
-
- // We didn't have any `poll_next` panic, so it's time to deactivate the bomb
- state_bomb.deactivate();
-
- let mut force_wake =
- // we need to poll the stream and didn't reach the limit yet
- need_to_poll_next & NEED_TO_POLL_STREAM != NONE && !this.is_exceeded_limit()
- // or we need to poll inner streams again
- || need_to_poll_next & NEED_TO_POLL_INNER_STREAMS != NONE;
-
- // Stop polling and swap the latest state
- poll_state_value = this.poll_state.stop_polling(need_to_poll_next, force_wake);
- // If state was changed during `POLLING` phase, need to manually call a waker
- force_wake |= poll_state_value & NEED_TO_POLL_ALL != NONE;
-
- let is_done = *this.is_stream_done && this.inner_streams.is_empty();
-
- if next_item.is_some() || is_done {
- Poll::Ready(next_item)
- } else {
- if force_wake {
- cx.waker().wake_by_ref();
- }
-
- Poll::Pending
- }
- }
-}
-
-// Forwarding impl of Sink from the underlying stream
-#[cfg(feature = "sink")]
-impl<St, Item> Sink<Item> for FlattenUnordered<St>
-where
- St: Stream + Sink<Item>,
-{
- type Error = St::Error;
-
- delegate_sink!(stream, Item);
-}
diff --git a/src/stream/stream/fold.rs b/src/stream/stream/fold.rs
index b8b55ec..e109c3b 100644
--- a/src/stream/stream/fold.rs
+++ b/src/stream/stream/fold.rs
@@ -35,21 +35,24 @@ where
}
impl<St, Fut, T, F> Fold<St, Fut, T, F>
-where
- St: Stream,
- F: FnMut(T, St::Item) -> Fut,
- Fut: Future<Output = T>,
+where St: Stream,
+ F: FnMut(T, St::Item) -> Fut,
+ Fut: Future<Output = T>,
{
pub(super) fn new(stream: St, f: F, t: T) -> Self {
- Self { stream, f, accum: Some(t), future: None }
+ Self {
+ stream,
+ f,
+ accum: Some(t),
+ future: None,
+ }
}
}
impl<St, Fut, T, F> FusedFuture for Fold<St, Fut, T, F>
-where
- St: Stream,
- F: FnMut(T, St::Item) -> Fut,
- Fut: Future<Output = T>,
+ where St: Stream,
+ F: FnMut(T, St::Item) -> Fut,
+ Fut: Future<Output = T>,
{
fn is_terminated(&self) -> bool {
self.accum.is_none() && self.future.is_none()
@@ -57,10 +60,9 @@ where
}
impl<St, Fut, T, F> Future for Fold<St, Fut, T, F>
-where
- St: Stream,
- F: FnMut(T, St::Item) -> Fut,
- Fut: Future<Output = T>,
+ where St: Stream,
+ F: FnMut(T, St::Item) -> Fut,
+ Fut: Future<Output = T>,
{
type Output = T;
diff --git a/src/stream/stream/for_each.rs b/src/stream/stream/for_each.rs
index 5302b0e..ee90e66 100644
--- a/src/stream/stream/for_each.rs
+++ b/src/stream/stream/for_each.rs
@@ -32,21 +32,23 @@ where
}
impl<St, Fut, F> ForEach<St, Fut, F>
-where
- St: Stream,
- F: FnMut(St::Item) -> Fut,
- Fut: Future<Output = ()>,
+where St: Stream,
+ F: FnMut(St::Item) -> Fut,
+ Fut: Future<Output = ()>,
{
pub(super) fn new(stream: St, f: F) -> Self {
- Self { stream, f, future: None }
+ Self {
+ stream,
+ f,
+ future: None,
+ }
}
}
impl<St, Fut, F> FusedFuture for ForEach<St, Fut, F>
-where
- St: FusedStream,
- F: FnMut(St::Item) -> Fut,
- Fut: Future<Output = ()>,
+ where St: FusedStream,
+ F: FnMut(St::Item) -> Fut,
+ Fut: Future<Output = ()>,
{
fn is_terminated(&self) -> bool {
self.future.is_none() && self.stream.is_terminated()
@@ -54,10 +56,9 @@ where
}
impl<St, Fut, F> Future for ForEach<St, Fut, F>
-where
- St: Stream,
- F: FnMut(St::Item) -> Fut,
- Fut: Future<Output = ()>,
+ where St: Stream,
+ F: FnMut(St::Item) -> Fut,
+ Fut: Future<Output = ()>,
{
type Output = ();
diff --git a/src/stream/stream/for_each_concurrent.rs b/src/stream/stream/for_each_concurrent.rs
index 6c18753..cee0ba1 100644
--- a/src/stream/stream/for_each_concurrent.rs
+++ b/src/stream/stream/for_each_concurrent.rs
@@ -1,7 +1,7 @@
use crate::stream::{FuturesUnordered, StreamExt};
use core::fmt;
-use core::num::NonZeroUsize;
use core::pin::Pin;
+use core::num::NonZeroUsize;
use futures_core::future::{FusedFuture, Future};
use futures_core::stream::Stream;
use futures_core::task::{Context, Poll};
@@ -35,10 +35,9 @@ where
}
impl<St, Fut, F> ForEachConcurrent<St, Fut, F>
-where
- St: Stream,
- F: FnMut(St::Item) -> Fut,
- Fut: Future<Output = ()>,
+where St: Stream,
+ F: FnMut(St::Item) -> Fut,
+ Fut: Future<Output = ()>,
{
pub(super) fn new(stream: St, limit: Option<usize>, f: F) -> Self {
Self {
@@ -52,10 +51,9 @@ where
}
impl<St, Fut, F> FusedFuture for ForEachConcurrent<St, Fut, F>
-where
- St: Stream,
- F: FnMut(St::Item) -> Fut,
- Fut: Future<Output = ()>,
+ where St: Stream,
+ F: FnMut(St::Item) -> Fut,
+ Fut: Future<Output = ()>,
{
fn is_terminated(&self) -> bool {
self.stream.is_none() && self.futures.is_empty()
@@ -63,10 +61,9 @@ where
}
impl<St, Fut, F> Future for ForEachConcurrent<St, Fut, F>
-where
- St: Stream,
- F: FnMut(St::Item) -> Fut,
- Fut: Future<Output = ()>,
+ where St: Stream,
+ F: FnMut(St::Item) -> Fut,
+ Fut: Future<Output = ()>,
{
type Output = ();
@@ -83,7 +80,7 @@ where
Poll::Ready(Some(elem)) => {
made_progress_this_iter = true;
Some(elem)
- }
+ },
Poll::Ready(None) => {
stream_completed = true;
None
@@ -105,9 +102,9 @@ where
Poll::Ready(Some(())) => made_progress_this_iter = true,
Poll::Ready(None) => {
if this.stream.is_none() {
- return Poll::Ready(());
+ return Poll::Ready(())
}
- }
+ },
Poll::Pending => {}
}
diff --git a/src/stream/stream/forward.rs b/src/stream/stream/forward.rs
index 1fe2427..2247b21 100644
--- a/src/stream/stream/forward.rs
+++ b/src/stream/stream/forward.rs
@@ -23,7 +23,11 @@ pin_project! {
impl<St, Si, Item> Forward<St, Si, Item> {
pub(crate) fn new(stream: St, sink: Si) -> Self {
- Self { sink: Some(sink), stream: Fuse::new(stream), buffered_item: None }
+ Self {
+ sink: Some(sink),
+ stream: Fuse::new(stream),
+ buffered_item: None,
+ }
}
}
@@ -44,7 +48,10 @@ where
{
type Output = Result<(), E>;
- fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ fn poll(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Self::Output> {
let ForwardProj { mut sink, mut stream, buffered_item } = self.project();
let mut si = sink.as_mut().as_pin_mut().expect("polled `Forward` after completion");
@@ -63,11 +70,11 @@ where
Poll::Ready(None) => {
ready!(si.poll_close(cx))?;
sink.set(None);
- return Poll::Ready(Ok(()));
+ return Poll::Ready(Ok(()))
}
Poll::Pending => {
ready!(si.poll_flush(cx))?;
- return Poll::Pending;
+ return Poll::Pending
}
}
}
diff --git a/src/stream/stream/fuse.rs b/src/stream/stream/fuse.rs
index fe67813..e1d8c12 100644
--- a/src/stream/stream/fuse.rs
+++ b/src/stream/stream/fuse.rs
@@ -43,7 +43,10 @@ impl<S: Stream> FusedStream for Fuse<S> {
impl<S: Stream> Stream for Fuse<S> {
type Item = S::Item;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<S::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<S::Item>> {
let this = self.project();
if *this.done {
diff --git a/src/stream/stream/into_future.rs b/src/stream/stream/into_future.rs
index 8abfddc..a9a1e23 100644
--- a/src/stream/stream/into_future.rs
+++ b/src/stream/stream/into_future.rs
@@ -79,7 +79,10 @@ impl<St: Stream + Unpin> FusedFuture for StreamFuture<St> {
impl<St: Stream + Unpin> Future for StreamFuture<St> {
type Output = (Option<St::Item>, St);
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ fn poll(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Self::Output> {
let item = {
let s = self.stream.as_mut().expect("polling StreamFuture twice");
ready!(s.poll_next_unpin(cx))
diff --git a/src/stream/stream/map.rs b/src/stream/stream/map.rs
index 88bb612..1a269f0 100644
--- a/src/stream/stream/map.rs
+++ b/src/stream/stream/map.rs
@@ -24,7 +24,9 @@ where
St: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Map").field("stream", &self.stream).finish()
+ f.debug_struct("Map")
+ .field("stream", &self.stream)
+ .finish()
}
}
@@ -37,9 +39,8 @@ impl<St, F> Map<St, F> {
}
impl<St, F> FusedStream for Map<St, F>
-where
- St: FusedStream,
- F: FnMut1<St::Item>,
+ where St: FusedStream,
+ F: FnMut1<St::Item>,
{
fn is_terminated(&self) -> bool {
self.stream.is_terminated()
@@ -47,13 +48,15 @@ where
}
impl<St, F> Stream for Map<St, F>
-where
- St: Stream,
- F: FnMut1<St::Item>,
+ where St: Stream,
+ F: FnMut1<St::Item>,
{
type Item = F::Output;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
let mut this = self.project();
let res = ready!(this.stream.as_mut().poll_next(cx));
Poll::Ready(res.map(|x| this.f.call_mut(x)))
@@ -67,9 +70,8 @@ where
// Forwarding impl of Sink from the underlying stream
#[cfg(feature = "sink")]
impl<St, F, Item> Sink<Item> for Map<St, F>
-where
- St: Stream + Sink<Item>,
- F: FnMut1<St::Item>,
+ where St: Stream + Sink<Item>,
+ F: FnMut1<St::Item>,
{
type Error = St::Error;
diff --git a/src/stream/stream/mod.rs b/src/stream/stream/mod.rs
index 642b91e..c3340ec 100644
--- a/src/stream/stream/mod.rs
+++ b/src/stream/stream/mod.rs
@@ -40,10 +40,6 @@ mod concat;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::concat::Concat;
-mod count;
-#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
-pub use self::count::Count;
-
mod cycle;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::cycle::Cycle;
@@ -74,14 +70,6 @@ mod fold;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::fold::Fold;
-mod any;
-#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
-pub use self::any::Any;
-
-mod all;
-#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
-pub use self::all::All;
-
#[cfg(feature = "sink")]
mod forward;
@@ -135,7 +123,7 @@ pub use self::select_next_some::SelectNextSome;
mod peek;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
-pub use self::peek::{NextIf, NextIfEq, Peek, PeekMut, Peekable};
+pub use self::peek::{Peek, Peekable};
mod skip;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
@@ -181,60 +169,35 @@ mod scan;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::scan::Scan;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-mod buffer_unordered;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
-pub use self::buffer_unordered::BufferUnordered;
-
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-mod buffered;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
-pub use self::buffered::Buffered;
-
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-mod flatten_unordered;
-
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-#[allow(unreachable_pub)]
-pub use self::flatten_unordered::FlattenUnordered;
+cfg_target_has_atomic! {
+ #[cfg(feature = "alloc")]
+ mod buffer_unordered;
+ #[cfg(feature = "alloc")]
+ #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
+ pub use self::buffer_unordered::BufferUnordered;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-delegate_all!(
- /// Stream for the [`flat_map_unordered`](StreamExt::flat_map_unordered) method.
- FlatMapUnordered<St, U, F>(
- FlattenUnordered<Map<St, F>>
- ): Debug + Sink + Stream + FusedStream + AccessInner[St, (. .)] + New[|x: St, limit: Option<usize>, f: F| FlattenUnordered::new(Map::new(x, f), limit)]
- where St: Stream, U: Stream, U: Unpin, F: FnMut(St::Item) -> U
-);
+ #[cfg(feature = "alloc")]
+ mod buffered;
+ #[cfg(feature = "alloc")]
+ #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
+ pub use self::buffered::Buffered;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-mod for_each_concurrent;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
-pub use self::for_each_concurrent::ForEachConcurrent;
+ #[cfg(feature = "alloc")]
+ mod for_each_concurrent;
+ #[cfg(feature = "alloc")]
+ #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
+ pub use self::for_each_concurrent::ForEachConcurrent;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "sink")]
-#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
-#[cfg(feature = "alloc")]
-mod split;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "sink")]
-#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
-#[cfg(feature = "alloc")]
-#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
-pub use self::split::{ReuniteError, SplitSink, SplitStream};
+ #[cfg(feature = "sink")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
+ #[cfg(feature = "alloc")]
+ mod split;
+ #[cfg(feature = "sink")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
+ #[cfg(feature = "alloc")]
+ #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
+ pub use self::split::{SplitStream, SplitSink, ReuniteError};
+}
#[cfg(feature = "std")]
mod catch_unwind;
@@ -409,9 +372,9 @@ pub trait StreamExt: Stream {
/// use futures::stream::{self, StreamExt};
///
/// let stream = stream::iter(1..=10);
- /// let events = stream.filter(|x| future::ready(x % 2 == 0));
+ /// let evens = stream.filter(|x| future::ready(x % 2 == 0));
///
- /// assert_eq!(vec![2, 4, 6, 8, 10], events.collect::<Vec<_>>().await);
+ /// assert_eq!(vec![2, 4, 6, 8, 10], evens.collect::<Vec<_>>().await);
/// # });
/// ```
fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
@@ -441,11 +404,11 @@ pub trait StreamExt: Stream {
/// use futures::stream::{self, StreamExt};
///
/// let stream = stream::iter(1..=10);
- /// let events = stream.filter_map(|x| async move {
+ /// let evens = stream.filter_map(|x| async move {
/// if x % 2 == 0 { Some(x + 1) } else { None }
/// });
///
- /// assert_eq!(vec![3, 5, 7, 9, 11], events.collect::<Vec<_>>().await);
+ /// assert_eq!(vec![3, 5, 7, 9, 11], evens.collect::<Vec<_>>().await);
/// # });
/// ```
fn filter_map<Fut, T, F>(self, f: F) -> FilterMap<Self, Fut, F>
@@ -599,38 +562,6 @@ pub trait StreamExt: Stream {
assert_future::<Self::Item, _>(Concat::new(self))
}
- /// Drives the stream to completion, counting the number of items.
- ///
- /// # Overflow Behavior
- ///
- /// The method does no guarding against overflows, so counting elements of a
- /// stream with more than [`usize::MAX`] elements either produces the wrong
- /// result or panics. If debug assertions are enabled, a panic is guaranteed.
- ///
- /// # Panics
- ///
- /// This function might panic if the iterator has more than [`usize::MAX`]
- /// elements.
- ///
- /// # Examples
- ///
- /// ```
- /// # futures::executor::block_on(async {
- /// use futures::stream::{self, StreamExt};
- ///
- /// let stream = stream::iter(1..=10);
- /// let count = stream.count().await;
- ///
- /// assert_eq!(count, 10);
- /// # });
- /// ```
- fn count(self) -> Count<Self>
- where
- Self: Sized,
- {
- assert_future::<usize, _>(Count::new(self))
- }
-
/// Repeats a stream endlessly.
///
/// The stream never terminates. Note that you likely want to avoid
@@ -690,50 +621,6 @@ pub trait StreamExt: Stream {
assert_future::<T, _>(Fold::new(self, f, init))
}
- /// Execute predicate over asynchronous stream, and return `true` if any element in stream satisfied a predicate.
- ///
- /// # Examples
- ///
- /// ```
- /// # futures::executor::block_on(async {
- /// use futures::stream::{self, StreamExt};
- ///
- /// let number_stream = stream::iter(0..10);
- /// let contain_three = number_stream.any(|i| async move { i == 3 });
- /// assert_eq!(contain_three.await, true);
- /// # });
- /// ```
- fn any<Fut, F>(self, f: F) -> Any<Self, Fut, F>
- where
- F: FnMut(Self::Item) -> Fut,
- Fut: Future<Output = bool>,
- Self: Sized,
- {
- assert_future::<bool, _>(Any::new(self, f))
- }
-
- /// Execute predicate over asynchronous stream, and return `true` if all element in stream satisfied a predicate.
- ///
- /// # Examples
- ///
- /// ```
- /// # futures::executor::block_on(async {
- /// use futures::stream::{self, StreamExt};
- ///
- /// let number_stream = stream::iter(0..10);
- /// let less_then_twenty = number_stream.all(|i| async move { i < 20 });
- /// assert_eq!(less_then_twenty.await, true);
- /// # });
- /// ```
- fn all<Fut, F>(self, f: F) -> All<Self, Fut, F>
- where
- F: FnMut(Self::Item) -> Fut,
- Fut: Future<Output = bool>,
- Self: Sized,
- {
- assert_future::<bool, _>(All::new(self, f))
- }
-
/// Flattens a stream of streams into just one continuous stream.
///
/// # Examples
@@ -773,57 +660,13 @@ pub trait StreamExt: Stream {
assert_stream::<<Self::Item as Stream>::Item, _>(Flatten::new(self))
}
- /// Flattens a stream of streams into just one continuous stream. Polls
- /// inner streams concurrently.
- ///
- /// # Examples
- ///
- /// ```
- /// # futures::executor::block_on(async {
- /// use futures::channel::mpsc;
- /// use futures::stream::StreamExt;
- /// use std::thread;
- ///
- /// let (tx1, rx1) = mpsc::unbounded();
- /// let (tx2, rx2) = mpsc::unbounded();
- /// let (tx3, rx3) = mpsc::unbounded();
- ///
- /// thread::spawn(move || {
- /// tx1.unbounded_send(1).unwrap();
- /// tx1.unbounded_send(2).unwrap();
- /// });
- /// thread::spawn(move || {
- /// tx2.unbounded_send(3).unwrap();
- /// tx2.unbounded_send(4).unwrap();
- /// });
- /// thread::spawn(move || {
- /// tx3.unbounded_send(rx1).unwrap();
- /// tx3.unbounded_send(rx2).unwrap();
- /// });
- ///
- /// let mut output = rx3.flatten_unordered(None).collect::<Vec<i32>>().await;
- /// output.sort();
- ///
- /// assert_eq!(output, vec![1, 2, 3, 4]);
- /// # });
- /// ```
- #[cfg(not(futures_no_atomic_cas))]
- #[cfg(feature = "alloc")]
- fn flatten_unordered(self, limit: impl Into<Option<usize>>) -> FlattenUnordered<Self>
- where
- Self::Item: Stream + Unpin,
- Self: Sized,
- {
- FlattenUnordered::new(self, limit.into())
- }
-
/// Maps a stream like [`StreamExt::map`] but flattens nested `Stream`s.
///
/// [`StreamExt::map`] is very useful, but if it produces a `Stream` instead,
/// you would have to chain combinators like `.map(f).flatten()` while this
/// combinator provides ability to write `.flat_map(f)` instead of chaining.
///
- /// The provided closure which produces inner streams is executed over all elements
+ /// The provided closure which produce inner streams is executed over all elements
/// of stream as last inner stream is terminated and next stream item is available.
///
/// Note that this function consumes the stream passed into it and returns a
@@ -851,59 +694,6 @@ pub trait StreamExt: Stream {
assert_stream::<U::Item, _>(FlatMap::new(self, f))
}
- /// Maps a stream like [`StreamExt::map`] but flattens nested `Stream`s
- /// and polls them concurrently, yielding items in any order, as they made
- /// available.
- ///
- /// [`StreamExt::map`] is very useful, but if it produces `Stream`s
- /// instead, and you need to poll all of them concurrently, you would
- /// have to use something like `for_each_concurrent` and merge values
- /// by hand. This combinator provides ability to collect all values
- /// from concurrently polled streams into one stream.
- ///
- /// The first argument is an optional limit on the number of concurrently
- /// polled streams. If this limit is not `None`, no more than `limit` streams
- /// will be polled concurrently. The `limit` argument is of type
- /// `Into<Option<usize>>`, and so can be provided as either `None`,
- /// `Some(10)`, or just `10`. Note: a limit of zero is interpreted as
- /// no limit at all, and will have the same result as passing in `None`.
- ///
- /// The provided closure which produces inner streams is executed over
- /// all elements of stream as next stream item is available and limit
- /// of concurrently processed streams isn't exceeded.
- ///
- /// Note that this function consumes the stream passed into it and
- /// returns a wrapped version of it.
- ///
- /// # Examples
- ///
- /// ```
- /// # futures::executor::block_on(async {
- /// use futures::stream::{self, StreamExt};
- ///
- /// let stream = stream::iter(1..5);
- /// let stream = stream.flat_map_unordered(1, |x| stream::iter(vec![x; x]));
- /// let mut values = stream.collect::<Vec<_>>().await;
- /// values.sort();
- ///
- /// assert_eq!(vec![1usize, 2, 2, 3, 3, 3, 4, 4, 4, 4], values);
- /// # });
- /// ```
- #[cfg(not(futures_no_atomic_cas))]
- #[cfg(feature = "alloc")]
- fn flat_map_unordered<U, F>(
- self,
- limit: impl Into<Option<usize>>,
- f: F,
- ) -> FlatMapUnordered<Self, U, F>
- where
- U: Stream + Unpin,
- F: FnMut(Self::Item) -> U,
- Self: Sized,
- {
- FlatMapUnordered::new(self, limit.into(), f)
- }
-
/// Combinator similar to [`StreamExt::fold`] that holds internal state
/// and produces a new stream.
///
@@ -1129,7 +919,7 @@ pub trait StreamExt: Stream {
/// fut.await;
/// # })
/// ```
- #[cfg(not(futures_no_atomic_cas))]
+ #[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
#[cfg(feature = "alloc")]
fn for_each_concurrent<Fut, F>(
self,
@@ -1352,7 +1142,7 @@ pub trait StreamExt: Stream {
///
/// This method is only available when the `std` or `alloc` feature of this
/// library is activated, and it is activated by default.
- #[cfg(not(futures_no_atomic_cas))]
+ #[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
#[cfg(feature = "alloc")]
fn buffered(self, n: usize) -> Buffered<Self>
where
@@ -1397,7 +1187,7 @@ pub trait StreamExt: Stream {
/// assert_eq!(buffered.next().await, None);
/// # Ok::<(), i32>(()) }).unwrap();
/// ```
- #[cfg(not(futures_no_atomic_cas))]
+ #[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
#[cfg(feature = "alloc")]
fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
where
@@ -1539,8 +1329,7 @@ pub trait StreamExt: Stream {
/// the sink is closed. Note that neither the original stream nor provided
/// sink will be output by this future. Pass the sink by `Pin<&mut S>`
/// (for example, via `forward(&mut sink)` inside an `async` fn/block) in
- /// order to preserve access to the `Sink`. If the stream produces an error,
- /// that error will be returned by this future without flushing/closing the sink.
+ /// order to preserve access to the `Sink`.
#[cfg(feature = "sink")]
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
fn forward<S>(self, sink: S) -> Forward<Self, S>
@@ -1565,7 +1354,7 @@ pub trait StreamExt: Stream {
/// library is activated, and it is activated by default.
#[cfg(feature = "sink")]
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
- #[cfg(not(futures_no_atomic_cas))]
+ #[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
#[cfg(feature = "alloc")]
fn split<Item>(self) -> (SplitSink<Self, Item>, SplitStream<Self>)
where
diff --git a/src/stream/stream/next.rs b/src/stream/stream/next.rs
index 8d8347a..6949878 100644
--- a/src/stream/stream/next.rs
+++ b/src/stream/stream/next.rs
@@ -28,7 +28,10 @@ impl<St: ?Sized + FusedStream + Unpin> FusedFuture for Next<'_, St> {
impl<St: ?Sized + Stream + Unpin> Future for Next<'_, St> {
type Output = Option<St::Item>;
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ fn poll(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Self::Output> {
self.stream.poll_next_unpin(cx)
}
}
diff --git a/src/stream/stream/peek.rs b/src/stream/stream/peek.rs
index c72dfc3..a403110 100644
--- a/src/stream/stream/peek.rs
+++ b/src/stream/stream/peek.rs
@@ -1,7 +1,5 @@
-use crate::fns::FnOnce1;
use crate::stream::{Fuse, StreamExt};
use core::fmt;
-use core::marker::PhantomData;
use core::pin::Pin;
use futures_core::future::{FusedFuture, Future};
use futures_core::ready;
@@ -28,12 +26,15 @@ pin_project! {
impl<St: Stream> Peekable<St> {
pub(super) fn new(stream: St) -> Self {
- Self { stream: stream.fuse(), peeked: None }
+ Self {
+ stream: stream.fuse(),
+ peeked: None,
+ }
}
delegate_access_inner!(stream, St, (.));
- /// Produces a future which retrieves a reference to the next item
+ /// Produces a `Peek` future which retrieves a reference to the next item
/// in the stream, or `None` if the underlying stream terminates.
pub fn peek(self: Pin<&mut Self>) -> Peek<'_, St> {
Peek { inner: Some(self) }
@@ -43,60 +44,15 @@ impl<St: Stream> Peekable<St> {
///
/// This method polls the underlying stream and return either a reference
/// to the next item if the stream is ready or passes through any errors.
- pub fn poll_peek(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<&St::Item>> {
- let mut this = self.project();
-
- Poll::Ready(loop {
- if this.peeked.is_some() {
- break this.peeked.as_ref();
- } else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) {
- *this.peeked = Some(item);
- } else {
- break None;
- }
- })
- }
-
- /// Produces a future which retrieves a mutable reference to the next item
- /// in the stream, or `None` if the underlying stream terminates.
- ///
- /// # Examples
- ///
- /// ```
- /// # futures::executor::block_on(async {
- /// use futures::stream::{self, StreamExt};
- /// use futures::pin_mut;
- ///
- /// let stream = stream::iter(vec![1, 2, 3]).peekable();
- /// pin_mut!(stream);
- ///
- /// assert_eq!(stream.as_mut().peek_mut().await, Some(&mut 1));
- /// assert_eq!(stream.as_mut().next().await, Some(1));
- ///
- /// // Peek into the stream and modify the value which will be returned next
- /// if let Some(p) = stream.as_mut().peek_mut().await {
- /// if *p == 2 {
- /// *p = 5;
- /// }
- /// }
- ///
- /// assert_eq!(stream.collect::<Vec<_>>().await, vec![5, 3]);
- /// # });
- /// ```
- pub fn peek_mut(self: Pin<&mut Self>) -> PeekMut<'_, St> {
- PeekMut { inner: Some(self) }
- }
-
- /// Peek retrieves a mutable reference to the next item in the stream.
- pub fn poll_peek_mut(
+ pub fn poll_peek(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
- ) -> Poll<Option<&mut St::Item>> {
+ ) -> Poll<Option<&St::Item>> {
let mut this = self.project();
Poll::Ready(loop {
if this.peeked.is_some() {
- break this.peeked.as_mut();
+ break this.peeked.as_ref();
} else if let Some(item) = ready!(this.stream.as_mut().poll_next(cx)) {
*this.peeked = Some(item);
} else {
@@ -104,86 +60,6 @@ impl<St: Stream> Peekable<St> {
}
})
}
-
- /// Creates a future which will consume and return the next value of this
- /// stream if a condition is true.
- ///
- /// If `func` returns `true` for the next value of this stream, consume and
- /// return it. Otherwise, return `None`.
- ///
- /// # Examples
- ///
- /// Consume a number if it's equal to 0.
- ///
- /// ```
- /// # futures::executor::block_on(async {
- /// use futures::stream::{self, StreamExt};
- /// use futures::pin_mut;
- ///
- /// let stream = stream::iter(0..5).peekable();
- /// pin_mut!(stream);
- /// // The first item of the stream is 0; consume it.
- /// assert_eq!(stream.as_mut().next_if(|&x| x == 0).await, Some(0));
- /// // The next item returned is now 1, so `consume` will return `false`.
- /// assert_eq!(stream.as_mut().next_if(|&x| x == 0).await, None);
- /// // `next_if` saves the value of the next item if it was not equal to `expected`.
- /// assert_eq!(stream.next().await, Some(1));
- /// # });
- /// ```
- ///
- /// Consume any number less than 10.
- ///
- /// ```
- /// # futures::executor::block_on(async {
- /// use futures::stream::{self, StreamExt};
- /// use futures::pin_mut;
- ///
- /// let stream = stream::iter(1..20).peekable();
- /// pin_mut!(stream);
- /// // Consume all numbers less than 10
- /// while stream.as_mut().next_if(|&x| x < 10).await.is_some() {}
- /// // The next value returned will be 10
- /// assert_eq!(stream.next().await, Some(10));
- /// # });
- /// ```
- pub fn next_if<F>(self: Pin<&mut Self>, func: F) -> NextIf<'_, St, F>
- where
- F: FnOnce(&St::Item) -> bool,
- {
- NextIf { inner: Some((self, func)) }
- }
-
- /// Creates a future which will consume and return the next item if it is
- /// equal to `expected`.
- ///
- /// # Example
- ///
- /// Consume a number if it's equal to 0.
- ///
- /// ```
- /// # futures::executor::block_on(async {
- /// use futures::stream::{self, StreamExt};
- /// use futures::pin_mut;
- ///
- /// let stream = stream::iter(0..5).peekable();
- /// pin_mut!(stream);
- /// // The first item of the stream is 0; consume it.
- /// assert_eq!(stream.as_mut().next_if_eq(&0).await, Some(0));
- /// // The next item returned is now 1, so `consume` will return `false`.
- /// assert_eq!(stream.as_mut().next_if_eq(&0).await, None);
- /// // `next_if_eq` saves the value of the next item if it was not equal to `expected`.
- /// assert_eq!(stream.next().await, Some(1));
- /// # });
- /// ```
- pub fn next_if_eq<'a, T>(self: Pin<&'a mut Self>, expected: &'a T) -> NextIfEq<'a, St, T>
- where
- T: ?Sized,
- St::Item: PartialEq<T>,
- {
- NextIfEq {
- inner: NextIf { inner: Some((self, NextIfEqFn { expected, _next: PhantomData })) },
- }
- }
}
impl<St: Stream> FusedStream for Peekable<St> {
@@ -227,7 +103,7 @@ where
}
pin_project! {
- /// Future for the [`Peekable::peek`](self::Peekable::peek) method.
+ /// Future for the [`Peekable::peek()`](self::Peekable::peek) function from [`Peekable`]
#[must_use = "futures do nothing unless polled"]
pub struct Peek<'a, St: Stream> {
inner: Option<Pin<&'a mut Peekable<St>>>,
@@ -240,7 +116,9 @@ where
St::Item: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Peek").field("inner", &self.inner).finish()
+ f.debug_struct("Peek")
+ .field("inner", &self.inner)
+ .finish()
}
}
@@ -255,7 +133,6 @@ where
St: Stream,
{
type Output = Option<&'a St::Item>;
-
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let inner = self.project().inner;
if let Some(peekable) = inner {
@@ -267,167 +144,3 @@ where
}
}
}
-
-pin_project! {
- /// Future for the [`Peekable::peek_mut`](self::Peekable::peek_mut) method.
- #[must_use = "futures do nothing unless polled"]
- pub struct PeekMut<'a, St: Stream> {
- inner: Option<Pin<&'a mut Peekable<St>>>,
- }
-}
-
-impl<St> fmt::Debug for PeekMut<'_, St>
-where
- St: Stream + fmt::Debug,
- St::Item: fmt::Debug,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("PeekMut").field("inner", &self.inner).finish()
- }
-}
-
-impl<St: Stream> FusedFuture for PeekMut<'_, St> {
- fn is_terminated(&self) -> bool {
- self.inner.is_none()
- }
-}
-
-impl<'a, St> Future for PeekMut<'a, St>
-where
- St: Stream,
-{
- type Output = Option<&'a mut St::Item>;
-
- fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- let inner = self.project().inner;
- if let Some(peekable) = inner {
- ready!(peekable.as_mut().poll_peek_mut(cx));
-
- inner.take().unwrap().poll_peek_mut(cx)
- } else {
- panic!("PeekMut polled after completion")
- }
- }
-}
-
-pin_project! {
- /// Future for the [`Peekable::next_if`](self::Peekable::next_if) method.
- #[must_use = "futures do nothing unless polled"]
- pub struct NextIf<'a, St: Stream, F> {
- inner: Option<(Pin<&'a mut Peekable<St>>, F)>,
- }
-}
-
-impl<St, F> fmt::Debug for NextIf<'_, St, F>
-where
- St: Stream + fmt::Debug,
- St::Item: fmt::Debug,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("NextIf").field("inner", &self.inner.as_ref().map(|(s, _f)| s)).finish()
- }
-}
-
-#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
-impl<St, F> FusedFuture for NextIf<'_, St, F>
-where
- St: Stream,
- F: for<'a> FnOnce1<&'a St::Item, Output = bool>,
-{
- fn is_terminated(&self) -> bool {
- self.inner.is_none()
- }
-}
-
-#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
-impl<St, F> Future for NextIf<'_, St, F>
-where
- St: Stream,
- F: for<'a> FnOnce1<&'a St::Item, Output = bool>,
-{
- type Output = Option<St::Item>;
-
- fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- let inner = self.project().inner;
- if let Some((peekable, _)) = inner {
- let res = ready!(peekable.as_mut().poll_next(cx));
-
- let (peekable, func) = inner.take().unwrap();
- match res {
- Some(ref matched) if func.call_once(matched) => Poll::Ready(res),
- other => {
- let peekable = peekable.project();
- // Since we called `self.next()`, we consumed `self.peeked`.
- assert!(peekable.peeked.is_none());
- *peekable.peeked = other;
- Poll::Ready(None)
- }
- }
- } else {
- panic!("NextIf polled after completion")
- }
- }
-}
-
-pin_project! {
- /// Future for the [`Peekable::next_if_eq`](self::Peekable::next_if_eq) method.
- #[must_use = "futures do nothing unless polled"]
- pub struct NextIfEq<'a, St: Stream, T: ?Sized> {
- #[pin]
- inner: NextIf<'a, St, NextIfEqFn<'a, T, St::Item>>,
- }
-}
-
-impl<St, T> fmt::Debug for NextIfEq<'_, St, T>
-where
- St: Stream + fmt::Debug,
- St::Item: fmt::Debug,
- T: ?Sized,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("NextIfEq")
- .field("inner", &self.inner.inner.as_ref().map(|(s, _f)| s))
- .finish()
- }
-}
-
-impl<St, T> FusedFuture for NextIfEq<'_, St, T>
-where
- St: Stream,
- T: ?Sized,
- St::Item: PartialEq<T>,
-{
- fn is_terminated(&self) -> bool {
- self.inner.is_terminated()
- }
-}
-
-impl<St, T> Future for NextIfEq<'_, St, T>
-where
- St: Stream,
- T: ?Sized,
- St::Item: PartialEq<T>,
-{
- type Output = Option<St::Item>;
-
- fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- self.project().inner.poll(cx)
- }
-}
-
-struct NextIfEqFn<'a, T: ?Sized, Item> {
- expected: &'a T,
- _next: PhantomData<Item>,
-}
-
-impl<T, Item> FnOnce1<&Item> for NextIfEqFn<'_, T, Item>
-where
- T: ?Sized,
- Item: PartialEq<T>,
-{
- type Output = bool;
-
- fn call_once(self, next: &Item) -> Self::Output {
- next == self.expected
- }
-}
diff --git a/src/stream/stream/ready_chunks.rs b/src/stream/stream/ready_chunks.rs
index 5ebc958..b6e3e5c 100644
--- a/src/stream/stream/ready_chunks.rs
+++ b/src/stream/stream/ready_chunks.rs
@@ -1,12 +1,12 @@
use crate::stream::Fuse;
-use alloc::vec::Vec;
-use core::mem;
-use core::pin::Pin;
-use futures_core::stream::{FusedStream, Stream};
+use futures_core::stream::{Stream, FusedStream};
use futures_core::task::{Context, Poll};
#[cfg(feature = "sink")]
use futures_sink::Sink;
use pin_project_lite::pin_project;
+use core::mem;
+use core::pin::Pin;
+use alloc::vec::Vec;
pin_project! {
/// Stream for the [`ready_chunks`](super::StreamExt::ready_chunks) method.
@@ -20,10 +20,7 @@ pin_project! {
}
}
-impl<St: Stream> ReadyChunks<St>
-where
- St: Stream,
-{
+impl<St: Stream> ReadyChunks<St> where St: Stream {
pub(super) fn new(stream: St, capacity: usize) -> Self {
assert!(capacity > 0);
@@ -40,7 +37,10 @@ where
impl<St: Stream> Stream for ReadyChunks<St> {
type Item = Vec<St::Item>;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
let mut this = self.project();
loop {
@@ -61,10 +61,7 @@ impl<St: Stream> Stream for ReadyChunks<St> {
Poll::Ready(Some(item)) => {
this.items.push(item);
if this.items.len() >= *this.cap {
- return Poll::Ready(Some(mem::replace(
- this.items,
- Vec::with_capacity(*this.cap),
- )));
+ return Poll::Ready(Some(mem::replace(this.items, Vec::with_capacity(*this.cap))))
}
}
diff --git a/src/stream/stream/scan.rs b/src/stream/stream/scan.rs
index f5cfde9..2097280 100644
--- a/src/stream/stream/scan.rs
+++ b/src/stream/stream/scan.rs
@@ -56,7 +56,14 @@ where
Fut: Future<Output = Option<B>>,
{
pub(super) fn new(stream: St, initial_state: S, f: F) -> Self {
- Self { stream, state_f: Some(StateFn { state: initial_state, f }), future: None }
+ Self {
+ stream,
+ state_f: Some(StateFn {
+ state: initial_state,
+ f,
+ }),
+ future: None,
+ }
}
delegate_access_inner!(stream, St, ());
@@ -118,11 +125,11 @@ where
// Forwarding impl of Sink from the underlying stream
#[cfg(feature = "sink")]
-impl<St, S, Fut, F, Item> Sink<Item> for Scan<St, S, Fut, F>
+impl<S, Fut, F, Item> Sink<Item> for Scan<S, S, Fut, F>
where
- St: Stream + Sink<Item>,
+ S: Stream + Sink<Item>,
{
- type Error = St::Error;
+ type Error = S::Error;
delegate_sink!(stream, Item);
}
diff --git a/src/stream/stream/select_next_some.rs b/src/stream/stream/select_next_some.rs
index 3115e14..fe7a089 100644
--- a/src/stream/stream/select_next_some.rs
+++ b/src/stream/stream/select_next_some.rs
@@ -1,9 +1,9 @@
-use crate::stream::StreamExt;
use core::pin::Pin;
-use futures_core::future::{FusedFuture, Future};
use futures_core::ready;
use futures_core::stream::FusedStream;
+use futures_core::future::{Future, FusedFuture};
use futures_core::task::{Context, Poll};
+use crate::stream::StreamExt;
/// Future for the [`select_next_some`](super::StreamExt::select_next_some)
/// method.
diff --git a/src/stream/stream/skip.rs b/src/stream/stream/skip.rs
index f495779..6ffcf57 100644
--- a/src/stream/stream/skip.rs
+++ b/src/stream/stream/skip.rs
@@ -19,7 +19,10 @@ pin_project! {
impl<St: Stream> Skip<St> {
pub(super) fn new(stream: St, n: usize) -> Self {
- Self { stream, remaining: n }
+ Self {
+ stream,
+ remaining: n,
+ }
}
delegate_access_inner!(stream, St, ());
@@ -34,7 +37,10 @@ impl<St: FusedStream> FusedStream for Skip<St> {
impl<St: Stream> Stream for Skip<St> {
type Item = St::Item;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<St::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<St::Item>> {
let mut this = self.project();
while *this.remaining > 0 {
@@ -51,8 +57,11 @@ impl<St: Stream> Stream for Skip<St> {
fn size_hint(&self) -> (usize, Option<usize>) {
let (lower, upper) = self.stream.size_hint();
- let lower = lower.saturating_sub(self.remaining);
- let upper = upper.map(|x| x.saturating_sub(self.remaining));
+ let lower = lower.saturating_sub(self.remaining as usize);
+ let upper = match upper {
+ Some(x) => Some(x.saturating_sub(self.remaining as usize)),
+ None => None,
+ };
(lower, upper)
}
diff --git a/src/stream/stream/skip_while.rs b/src/stream/stream/skip_while.rs
index 50a21a2..e1aa3f9 100644
--- a/src/stream/stream/skip_while.rs
+++ b/src/stream/stream/skip_while.rs
@@ -39,23 +39,27 @@ where
}
impl<St, Fut, F> SkipWhile<St, Fut, F>
-where
- St: Stream,
- F: FnMut(&St::Item) -> Fut,
- Fut: Future<Output = bool>,
+ where St: Stream,
+ F: FnMut(&St::Item) -> Fut,
+ Fut: Future<Output = bool>,
{
pub(super) fn new(stream: St, f: F) -> Self {
- Self { stream, f, pending_fut: None, pending_item: None, done_skipping: false }
+ Self {
+ stream,
+ f,
+ pending_fut: None,
+ pending_item: None,
+ done_skipping: false,
+ }
}
delegate_access_inner!(stream, St, ());
}
impl<St, Fut, F> FusedStream for SkipWhile<St, Fut, F>
-where
- St: FusedStream,
- F: FnMut(&St::Item) -> Fut,
- Fut: Future<Output = bool>,
+ where St: FusedStream,
+ F: FnMut(&St::Item) -> Fut,
+ Fut: Future<Output = bool>,
{
fn is_terminated(&self) -> bool {
self.pending_item.is_none() && self.stream.is_terminated()
@@ -63,14 +67,16 @@ where
}
impl<St, Fut, F> Stream for SkipWhile<St, Fut, F>
-where
- St: Stream,
- F: FnMut(&St::Item) -> Fut,
- Fut: Future<Output = bool>,
+ where St: Stream,
+ F: FnMut(&St::Item) -> Fut,
+ Fut: Future<Output = bool>,
{
type Item = St::Item;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<St::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<St::Item>> {
let mut this = self.project();
if *this.done_skipping {
@@ -113,10 +119,9 @@ where
// Forwarding impl of Sink from the underlying stream
#[cfg(feature = "sink")]
impl<S, Fut, F, Item> Sink<Item> for SkipWhile<S, Fut, F>
-where
- S: Stream + Sink<Item>,
- F: FnMut(&S::Item) -> Fut,
- Fut: Future<Output = bool>,
+ where S: Stream + Sink<Item>,
+ F: FnMut(&S::Item) -> Fut,
+ Fut: Future<Output = bool>,
{
type Error = S::Error;
diff --git a/src/stream/stream/split.rs b/src/stream/stream/split.rs
index 3a72fee..997b974 100644
--- a/src/stream/stream/split.rs
+++ b/src/stream/stream/split.rs
@@ -1,9 +1,9 @@
-use core::fmt;
-use core::pin::Pin;
use futures_core::ready;
use futures_core::stream::Stream;
use futures_core::task::{Context, Poll};
use futures_sink::Sink;
+use core::fmt;
+use core::pin::Pin;
use crate::lock::BiLock;
@@ -20,8 +20,7 @@ impl<S: Unpin> SplitStream<S> {
/// together. Succeeds only if the `SplitStream<S>` and `SplitSink<S>` are
/// a matching pair originating from the same call to `StreamExt::split`.
pub fn reunite<Item>(self, other: SplitSink<S, Item>) -> Result<S, ReuniteError<S, Item>>
- where
- S: Sink<Item>,
+ where S: Sink<Item>,
{
other.reunite(self)
}
@@ -37,7 +36,10 @@ impl<S: Stream> Stream for SplitStream<S> {
#[allow(bad_style)]
fn SplitSink<S: Sink<Item>, Item>(lock: BiLock<S>) -> SplitSink<S, Item> {
- SplitSink { lock, slot: None }
+ SplitSink {
+ lock,
+ slot: None,
+ }
}
/// A `Sink` part of the split pair
@@ -56,16 +58,14 @@ impl<S: Sink<Item> + Unpin, Item> SplitSink<S, Item> {
/// together. Succeeds only if the `SplitStream<S>` and `SplitSink<S>` are
/// a matching pair originating from the same call to `StreamExt::split`.
pub fn reunite(self, other: SplitStream<S>) -> Result<S, ReuniteError<S, Item>> {
- self.lock.reunite(other.0).map_err(|err| ReuniteError(SplitSink(err.0), SplitStream(err.1)))
+ self.lock.reunite(other.0).map_err(|err| {
+ ReuniteError(SplitSink(err.0), SplitStream(err.1))
+ })
}
}
impl<S: Sink<Item>, Item> SplitSink<S, Item> {
- fn poll_flush_slot(
- mut inner: Pin<&mut S>,
- slot: &mut Option<Item>,
- cx: &mut Context<'_>,
- ) -> Poll<Result<(), S::Error>> {
+ fn poll_flush_slot(mut inner: Pin<&mut S>, slot: &mut Option<Item>, cx: &mut Context<'_>) -> Poll<Result<(), S::Error>> {
if slot.is_some() {
ready!(inner.as_mut().poll_ready(cx))?;
Poll::Ready(inner.start_send(slot.take().unwrap()))
@@ -74,10 +74,7 @@ impl<S: Sink<Item>, Item> SplitSink<S, Item> {
}
}
- fn poll_lock_and_flush_slot(
- mut self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- ) -> Poll<Result<(), S::Error>> {
+ fn poll_lock_and_flush_slot(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), S::Error>> {
let this = &mut *self;
let mut inner = ready!(this.lock.poll_lock(cx));
Self::poll_flush_slot(inner.as_pin_mut(), &mut this.slot, cx)
@@ -130,7 +127,9 @@ pub struct ReuniteError<T, Item>(pub SplitSink<T, Item>, pub SplitStream<T>);
impl<T, Item> fmt::Debug for ReuniteError<T, Item> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_tuple("ReuniteError").field(&"...").finish()
+ f.debug_tuple("ReuniteError")
+ .field(&"...")
+ .finish()
}
}
diff --git a/src/stream/stream/take.rs b/src/stream/stream/take.rs
index b1c728e..124d397 100644
--- a/src/stream/stream/take.rs
+++ b/src/stream/stream/take.rs
@@ -1,7 +1,7 @@
use core::cmp;
use core::pin::Pin;
use futures_core::ready;
-use futures_core::stream::{FusedStream, Stream};
+use futures_core::stream::{Stream, FusedStream};
use futures_core::task::{Context, Poll};
#[cfg(feature = "sink")]
use futures_sink::Sink;
@@ -20,19 +20,24 @@ pin_project! {
impl<St: Stream> Take<St> {
pub(super) fn new(stream: St, n: usize) -> Self {
- Self { stream, remaining: n }
+ Self {
+ stream,
+ remaining: n,
+ }
}
delegate_access_inner!(stream, St, ());
}
impl<St> Stream for Take<St>
-where
- St: Stream,
+ where St: Stream,
{
type Item = St::Item;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<St::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<St::Item>> {
if self.remaining == 0 {
Poll::Ready(None)
} else {
@@ -58,7 +63,7 @@ where
let upper = match upper {
Some(x) if x < self.remaining as usize => Some(x),
- _ => Some(self.remaining as usize),
+ _ => Some(self.remaining as usize)
};
(lower, upper)
@@ -66,8 +71,7 @@ where
}
impl<St> FusedStream for Take<St>
-where
- St: FusedStream,
+ where St: FusedStream,
{
fn is_terminated(&self) -> bool {
self.remaining == 0 || self.stream.is_terminated()
@@ -77,8 +81,7 @@ where
// Forwarding impl of Sink from the underlying stream
#[cfg(feature = "sink")]
impl<S, Item> Sink<Item> for Take<S>
-where
- S: Stream + Sink<Item>,
+ where S: Stream + Sink<Item>,
{
type Error = S::Error;
diff --git a/src/stream/stream/take_until.rs b/src/stream/stream/take_until.rs
index d14f9ce..4dea01a 100644
--- a/src/stream/stream/take_until.rs
+++ b/src/stream/stream/take_until.rs
@@ -34,7 +34,10 @@ where
Fut: Future + fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("TakeUntil").field("stream", &self.stream).field("fut", &self.fut).finish()
+ f.debug_struct("TakeUntil")
+ .field("stream", &self.stream)
+ .field("fut", &self.fut)
+ .finish()
}
}
@@ -44,7 +47,12 @@ where
Fut: Future,
{
pub(super) fn new(stream: St, fut: Fut) -> Self {
- Self { stream, fut: Some(fut), fut_result: None, free: false }
+ Self {
+ stream,
+ fut: Some(fut),
+ fut_result: None,
+ free: false,
+ }
}
delegate_access_inner!(stream, St, ());
diff --git a/src/stream/stream/take_while.rs b/src/stream/stream/take_while.rs
index 01b2765..4cdba83 100644
--- a/src/stream/stream/take_while.rs
+++ b/src/stream/stream/take_while.rs
@@ -2,7 +2,7 @@ use core::fmt;
use core::pin::Pin;
use futures_core::future::Future;
use futures_core::ready;
-use futures_core::stream::{FusedStream, Stream};
+use futures_core::stream::{Stream, FusedStream};
use futures_core::task::{Context, Poll};
#[cfg(feature = "sink")]
use futures_sink::Sink;
@@ -39,27 +39,34 @@ where
}
impl<St, Fut, F> TakeWhile<St, Fut, F>
-where
- St: Stream,
- F: FnMut(&St::Item) -> Fut,
- Fut: Future<Output = bool>,
+ where St: Stream,
+ F: FnMut(&St::Item) -> Fut,
+ Fut: Future<Output = bool>,
{
pub(super) fn new(stream: St, f: F) -> Self {
- Self { stream, f, pending_fut: None, pending_item: None, done_taking: false }
+ Self {
+ stream,
+ f,
+ pending_fut: None,
+ pending_item: None,
+ done_taking: false,
+ }
}
delegate_access_inner!(stream, St, ());
}
impl<St, Fut, F> Stream for TakeWhile<St, Fut, F>
-where
- St: Stream,
- F: FnMut(&St::Item) -> Fut,
- Fut: Future<Output = bool>,
+ where St: Stream,
+ F: FnMut(&St::Item) -> Fut,
+ Fut: Future<Output = bool>,
{
type Item = St::Item;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<St::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<St::Item>> {
if self.done_taking {
return Poll::Ready(None);
}
@@ -102,10 +109,9 @@ where
}
impl<St, Fut, F> FusedStream for TakeWhile<St, Fut, F>
-where
- St: FusedStream,
- F: FnMut(&St::Item) -> Fut,
- Fut: Future<Output = bool>,
+ where St: FusedStream,
+ F: FnMut(&St::Item) -> Fut,
+ Fut: Future<Output = bool>,
{
fn is_terminated(&self) -> bool {
self.done_taking || self.pending_item.is_none() && self.stream.is_terminated()
@@ -115,8 +121,7 @@ where
// Forwarding impl of Sink from the underlying stream
#[cfg(feature = "sink")]
impl<S, Fut, F, Item> Sink<Item> for TakeWhile<S, Fut, F>
-where
- S: Stream + Sink<Item>,
+ where S: Stream + Sink<Item>,
{
type Error = S::Error;
diff --git a/src/stream/stream/then.rs b/src/stream/stream/then.rs
index d4531d4..3d42bdd 100644
--- a/src/stream/stream/then.rs
+++ b/src/stream/stream/then.rs
@@ -26,27 +26,32 @@ where
Fut: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Then").field("stream", &self.stream).field("future", &self.future).finish()
+ f.debug_struct("Then")
+ .field("stream", &self.stream)
+ .field("future", &self.future)
+ .finish()
}
}
impl<St, Fut, F> Then<St, Fut, F>
-where
- St: Stream,
- F: FnMut(St::Item) -> Fut,
+ where St: Stream,
+ F: FnMut(St::Item) -> Fut,
{
pub(super) fn new(stream: St, f: F) -> Self {
- Self { stream, future: None, f }
+ Self {
+ stream,
+ future: None,
+ f,
+ }
}
delegate_access_inner!(stream, St, ());
}
impl<St, Fut, F> FusedStream for Then<St, Fut, F>
-where
- St: FusedStream,
- F: FnMut(St::Item) -> Fut,
- Fut: Future,
+ where St: FusedStream,
+ F: FnMut(St::Item) -> Fut,
+ Fut: Future,
{
fn is_terminated(&self) -> bool {
self.future.is_none() && self.stream.is_terminated()
@@ -54,14 +59,16 @@ where
}
impl<St, Fut, F> Stream for Then<St, Fut, F>
-where
- St: Stream,
- F: FnMut(St::Item) -> Fut,
- Fut: Future,
+ where St: Stream,
+ F: FnMut(St::Item) -> Fut,
+ Fut: Future,
{
type Item = Fut::Output;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
let mut this = self.project();
Poll::Ready(loop {
@@ -92,8 +99,7 @@ where
// Forwarding impl of Sink from the underlying stream
#[cfg(feature = "sink")]
impl<S, Fut, F, Item> Sink<Item> for Then<S, Fut, F>
-where
- S: Sink<Item>,
+ where S: Sink<Item>,
{
type Error = S::Error;
diff --git a/src/stream/stream/unzip.rs b/src/stream/stream/unzip.rs
index 15f22e8..5024770 100644
--- a/src/stream/stream/unzip.rs
+++ b/src/stream/stream/unzip.rs
@@ -21,19 +21,25 @@ pin_project! {
impl<St: Stream, FromA: Default, FromB: Default> Unzip<St, FromA, FromB> {
fn finish(self: Pin<&mut Self>) -> (FromA, FromB) {
let this = self.project();
- (mem::replace(this.left, Default::default()), mem::replace(this.right, Default::default()))
+ (
+ mem::replace(this.left, Default::default()),
+ mem::replace(this.right, Default::default()),
+ )
}
pub(super) fn new(stream: St) -> Self {
- Self { stream, left: Default::default(), right: Default::default() }
+ Self {
+ stream,
+ left: Default::default(),
+ right: Default::default(),
+ }
}
}
impl<St, A, B, FromA, FromB> FusedFuture for Unzip<St, FromA, FromB>
-where
- St: FusedStream<Item = (A, B)>,
- FromA: Default + Extend<A>,
- FromB: Default + Extend<B>,
+where St: FusedStream<Item = (A, B)>,
+ FromA: Default + Extend<A>,
+ FromB: Default + Extend<B>,
{
fn is_terminated(&self) -> bool {
self.stream.is_terminated()
@@ -41,10 +47,9 @@ where
}
impl<St, A, B, FromA, FromB> Future for Unzip<St, FromA, FromB>
-where
- St: Stream<Item = (A, B)>,
- FromA: Default + Extend<A>,
- FromB: Default + Extend<B>,
+where St: Stream<Item = (A, B)>,
+ FromA: Default + Extend<A>,
+ FromB: Default + Extend<B>,
{
type Output = (FromA, FromB);
@@ -55,7 +60,7 @@ where
Some(e) => {
this.left.extend(Some(e.0));
this.right.extend(Some(e.1));
- }
+ },
None => return Poll::Ready(self.finish()),
}
}
diff --git a/src/stream/stream/zip.rs b/src/stream/stream/zip.rs
index 360a8b6..588531a 100644
--- a/src/stream/stream/zip.rs
+++ b/src/stream/stream/zip.rs
@@ -1,4 +1,4 @@
-use crate::stream::{Fuse, StreamExt};
+use crate::stream::{StreamExt, Fuse};
use core::cmp;
use core::pin::Pin;
use futures_core::stream::{FusedStream, Stream};
@@ -21,7 +21,12 @@ pin_project! {
impl<St1: Stream, St2: Stream> Zip<St1, St2> {
pub(super) fn new(stream1: St1, stream2: St2) -> Self {
- Self { stream1: stream1.fuse(), stream2: stream2.fuse(), queued1: None, queued2: None }
+ Self {
+ stream1: stream1.fuse(),
+ stream2: stream2.fuse(),
+ queued1: None,
+ queued2: None,
+ }
}
/// Acquires a reference to the underlying streams that this combinator is
@@ -59,9 +64,7 @@ impl<St1: Stream, St2: Stream> Zip<St1, St2> {
}
impl<St1, St2> FusedStream for Zip<St1, St2>
-where
- St1: Stream,
- St2: Stream,
+ where St1: Stream, St2: Stream,
{
fn is_terminated(&self) -> bool {
self.stream1.is_terminated() && self.stream2.is_terminated()
@@ -69,13 +72,14 @@ where
}
impl<St1, St2> Stream for Zip<St1, St2>
-where
- St1: Stream,
- St2: Stream,
+ where St1: Stream, St2: Stream
{
type Item = (St1::Item, St2::Item);
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
let mut this = self.project();
if this.queued1.is_none() {
@@ -120,7 +124,7 @@ where
}
(Some(x), None) => x.checked_add(queued1_len),
(None, Some(y)) => y.checked_add(queued2_len),
- (None, None) => None,
+ (None, None) => None
};
(lower, upper)
diff --git a/src/stream/try_stream/and_then.rs b/src/stream/try_stream/and_then.rs
index a7b50db..b185646 100644
--- a/src/stream/try_stream/and_then.rs
+++ b/src/stream/try_stream/and_then.rs
@@ -2,7 +2,7 @@ use core::fmt;
use core::pin::Pin;
use futures_core::future::TryFuture;
use futures_core::ready;
-use futures_core::stream::{FusedStream, Stream, TryStream};
+use futures_core::stream::{Stream, TryStream, FusedStream};
use futures_core::task::{Context, Poll};
#[cfg(feature = "sink")]
use futures_sink::Sink;
@@ -34,10 +34,9 @@ where
}
impl<St, Fut, F> AndThen<St, Fut, F>
-where
- St: TryStream,
- F: FnMut(St::Ok) -> Fut,
- Fut: TryFuture<Error = St::Error>,
+ where St: TryStream,
+ F: FnMut(St::Ok) -> Fut,
+ Fut: TryFuture<Error = St::Error>,
{
pub(super) fn new(stream: St, f: F) -> Self {
Self { stream, future: None, f }
@@ -47,14 +46,16 @@ where
}
impl<St, Fut, F> Stream for AndThen<St, Fut, F>
-where
- St: TryStream,
- F: FnMut(St::Ok) -> Fut,
- Fut: TryFuture<Error = St::Error>,
+ where St: TryStream,
+ F: FnMut(St::Ok) -> Fut,
+ Fut: TryFuture<Error = St::Error>,
{
type Item = Result<Fut::Ok, St::Error>;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
let mut this = self.project();
Poll::Ready(loop {
@@ -83,10 +84,9 @@ where
}
impl<St, Fut, F> FusedStream for AndThen<St, Fut, F>
-where
- St: TryStream + FusedStream,
- F: FnMut(St::Ok) -> Fut,
- Fut: TryFuture<Error = St::Error>,
+ where St: TryStream + FusedStream,
+ F: FnMut(St::Ok) -> Fut,
+ Fut: TryFuture<Error = St::Error>,
{
fn is_terminated(&self) -> bool {
self.future.is_none() && self.stream.is_terminated()
@@ -96,8 +96,7 @@ where
// Forwarding impl of Sink from the underlying stream
#[cfg(feature = "sink")]
impl<S, Fut, F, Item> Sink<Item> for AndThen<S, Fut, F>
-where
- S: Sink<Item>,
+ where S: Sink<Item>,
{
type Error = S::Error;
diff --git a/src/stream/try_stream/into_async_read.rs b/src/stream/try_stream/into_async_read.rs
index 914b277..197c105 100644
--- a/src/stream/try_stream/into_async_read.rs
+++ b/src/stream/try_stream/into_async_read.rs
@@ -3,7 +3,7 @@ use core::pin::Pin;
use futures_core::ready;
use futures_core::stream::TryStream;
use futures_core::task::{Context, Poll};
-use futures_io::{AsyncBufRead, AsyncRead, AsyncWrite};
+use futures_io::{AsyncRead, AsyncWrite, AsyncBufRead};
use std::cmp;
use std::io::{Error, Result};
@@ -40,7 +40,10 @@ where
St::Ok: AsRef<[u8]>,
{
pub(super) fn new(stream: St) -> Self {
- Self { stream, state: ReadState::PendingChunk }
+ Self {
+ stream,
+ state: ReadState::PendingChunk,
+ }
}
}
@@ -60,7 +63,9 @@ where
let chunk = chunk.as_ref();
let len = cmp::min(buf.len(), chunk.len() - *chunk_start);
- buf[..len].copy_from_slice(&chunk[*chunk_start..*chunk_start + len]);
+ buf[..len].copy_from_slice(
+ &chunk[*chunk_start..*chunk_start + len],
+ );
*chunk_start += len;
if chunk.len() == *chunk_start {
@@ -69,21 +74,26 @@ where
return Poll::Ready(Ok(len));
}
- ReadState::PendingChunk => match ready!(self.stream.try_poll_next_unpin(cx)) {
- Some(Ok(chunk)) => {
- if !chunk.as_ref().is_empty() {
- self.state = ReadState::Ready { chunk, chunk_start: 0 };
+ ReadState::PendingChunk => {
+ match ready!(self.stream.try_poll_next_unpin(cx)) {
+ Some(Ok(chunk)) => {
+ if !chunk.as_ref().is_empty() {
+ self.state = ReadState::Ready {
+ chunk,
+ chunk_start: 0,
+ };
+ }
+ }
+ Some(Err(err)) => {
+ self.state = ReadState::Eof;
+ return Poll::Ready(Err(err));
+ }
+ None => {
+ self.state = ReadState::Eof;
+ return Poll::Ready(Ok(0));
}
}
- Some(Err(err)) => {
- self.state = ReadState::Eof;
- return Poll::Ready(Err(err));
- }
- None => {
- self.state = ReadState::Eof;
- return Poll::Ready(Ok(0));
- }
- },
+ }
ReadState::Eof => {
return Poll::Ready(Ok(0));
}
@@ -100,17 +110,23 @@ where
fn poll_write(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
- buf: &[u8],
+ buf: &[u8]
) -> Poll<Result<usize>> {
- Pin::new(&mut self.stream).poll_write(cx, buf)
+ Pin::new( &mut self.stream ).poll_write( cx, buf )
}
- fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
- Pin::new(&mut self.stream).poll_flush(cx)
+ fn poll_flush(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>
+ ) -> Poll<Result<()>> {
+ Pin::new( &mut self.stream ).poll_flush( cx )
}
- fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
- Pin::new(&mut self.stream).poll_close(cx)
+ fn poll_close(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>
+ ) -> Poll<Result<()>> {
+ Pin::new( &mut self.stream ).poll_close( cx )
}
}
@@ -119,12 +135,18 @@ where
St: TryStream<Error = Error> + Unpin,
St::Ok: AsRef<[u8]>,
{
- fn poll_fill_buf(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> {
+ fn poll_fill_buf(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<&[u8]>> {
while let ReadState::PendingChunk = self.state {
match ready!(self.stream.try_poll_next_unpin(cx)) {
Some(Ok(chunk)) => {
if !chunk.as_ref().is_empty() {
- self.state = ReadState::Ready { chunk, chunk_start: 0 };
+ self.state = ReadState::Ready {
+ chunk,
+ chunk_start: 0,
+ };
}
}
Some(Err(err)) => {
@@ -147,11 +169,12 @@ where
Poll::Ready(Ok(&[]))
}
- fn consume(mut self: Pin<&mut Self>, amount: usize) {
- // https://github.com/rust-lang/futures-rs/pull/1556#discussion_r281644295
- if amount == 0 {
- return;
- }
+ fn consume(
+ mut self: Pin<&mut Self>,
+ amount: usize,
+ ) {
+ // https://github.com/rust-lang/futures-rs/pull/1556#discussion_r281644295
+ if amount == 0 { return }
if let ReadState::Ready { chunk, chunk_start } = &mut self.state {
*chunk_start += amount;
debug_assert!(*chunk_start <= chunk.as_ref().len());
diff --git a/src/stream/try_stream/into_stream.rs b/src/stream/try_stream/into_stream.rs
index 2126258..89bc3ef 100644
--- a/src/stream/try_stream/into_stream.rs
+++ b/src/stream/try_stream/into_stream.rs
@@ -34,7 +34,10 @@ impl<St: TryStream> Stream for IntoStream<St> {
type Item = Result<St::Ok, St::Error>;
#[inline]
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
self.project().stream.try_poll_next(cx)
}
diff --git a/src/stream/try_stream/mod.rs b/src/stream/try_stream/mod.rs
index 6bf2cb7..b7353d9 100644
--- a/src/stream/try_stream/mod.rs
+++ b/src/stream/try_stream/mod.rs
@@ -5,21 +5,18 @@
#[cfg(feature = "compat")]
use crate::compat::Compat;
-use crate::fns::{
- inspect_err_fn, inspect_ok_fn, into_fn, map_err_fn, map_ok_fn, InspectErrFn, InspectOkFn,
- IntoFn, MapErrFn, MapOkFn,
-};
-use crate::future::assert_future;
-use crate::stream::assert_stream;
-use crate::stream::{Inspect, Map};
-#[cfg(feature = "alloc")]
-use alloc::vec::Vec;
use core::pin::Pin;
use futures_core::{
future::{Future, TryFuture},
stream::TryStream,
task::{Context, Poll},
};
+use crate::fns::{
+ InspectOkFn, inspect_ok_fn, InspectErrFn, inspect_err_fn, MapErrFn, map_err_fn, IntoFn, into_fn, MapOkFn, map_ok_fn,
+};
+use crate::future::assert_future;
+use crate::stream::{Map, Inspect};
+use crate::stream::assert_stream;
mod and_then;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
@@ -96,12 +93,6 @@ mod try_concat;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::try_concat::TryConcat;
-#[cfg(feature = "alloc")]
-mod try_chunks;
-#[cfg(feature = "alloc")]
-#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
-pub use self::try_chunks::{TryChunks, TryChunksError};
-
mod try_fold;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::try_fold::TryFold;
@@ -118,29 +109,25 @@ mod try_take_while;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::try_take_while::TryTakeWhile;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-mod try_buffer_unordered;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
-pub use self::try_buffer_unordered::TryBufferUnordered;
+cfg_target_has_atomic! {
+ #[cfg(feature = "alloc")]
+ mod try_buffer_unordered;
+ #[cfg(feature = "alloc")]
+ #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
+ pub use self::try_buffer_unordered::TryBufferUnordered;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-mod try_buffered;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
-pub use self::try_buffered::TryBuffered;
+ #[cfg(feature = "alloc")]
+ mod try_buffered;
+ #[cfg(feature = "alloc")]
+ #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
+ pub use self::try_buffered::TryBuffered;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-mod try_for_each_concurrent;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
-pub use self::try_for_each_concurrent::TryForEachConcurrent;
+ #[cfg(feature = "alloc")]
+ mod try_for_each_concurrent;
+ #[cfg(feature = "alloc")]
+ #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
+ pub use self::try_for_each_concurrent::TryForEachConcurrent;
+}
#[cfg(feature = "io")]
#[cfg(feature = "std")]
@@ -528,7 +515,7 @@ pub trait TryStreamExt: TryStream {
/// assert_eq!(Err(oneshot::Canceled), fut.await);
/// # })
/// ```
- #[cfg(not(futures_no_atomic_cas))]
+ #[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
#[cfg(feature = "alloc")]
fn try_for_each_concurrent<Fut, F>(
self,
@@ -584,53 +571,6 @@ pub trait TryStreamExt: TryStream {
assert_future::<Result<C, Self::Error>, _>(TryCollect::new(self))
}
- /// An adaptor for chunking up successful items of the stream inside a vector.
- ///
- /// This combinator will attempt to pull successful items from this stream and buffer
- /// them into a local vector. At most `capacity` items will get buffered
- /// before they're yielded from the returned stream.
- ///
- /// Note that the vectors returned from this iterator may not always have
- /// `capacity` elements. If the underlying stream ended and only a partial
- /// vector was created, it'll be returned. Additionally if an error happens
- /// from the underlying stream then the currently buffered items will be
- /// yielded.
- ///
- /// This method is only available when the `std` or `alloc` feature of this
- /// library is activated, and it is activated by default.
- ///
- /// This function is similar to
- /// [`StreamExt::chunks`](crate::stream::StreamExt::chunks) but exits
- /// early if an error occurs.
- ///
- /// # Examples
- ///
- /// ```
- /// # futures::executor::block_on(async {
- /// use futures::stream::{self, TryChunksError, TryStreamExt};
- ///
- /// let stream = stream::iter(vec![Ok::<i32, i32>(1), Ok(2), Ok(3), Err(4), Ok(5), Ok(6)]);
- /// let mut stream = stream.try_chunks(2);
- ///
- /// assert_eq!(stream.try_next().await, Ok(Some(vec![1, 2])));
- /// assert_eq!(stream.try_next().await, Err(TryChunksError(vec![3], 4)));
- /// assert_eq!(stream.try_next().await, Ok(Some(vec![5, 6])));
- /// # })
- /// ```
- ///
- /// # Panics
- ///
- /// This method will panic if `capacity` is zero.
- #[cfg(feature = "alloc")]
- fn try_chunks(self, capacity: usize) -> TryChunks<Self>
- where
- Self: Sized,
- {
- assert_stream::<Result<Vec<Self::Ok>, TryChunksError<Self::Ok, Self::Error>>, _>(
- TryChunks::new(self, capacity),
- )
- }
-
/// Attempt to filter the values produced by this stream according to the
/// provided asynchronous closure.
///
@@ -736,21 +676,17 @@ pub trait TryStreamExt: TryStream {
/// thread::spawn(move || {
/// tx2.unbounded_send(Ok(2)).unwrap();
/// tx2.unbounded_send(Err(3)).unwrap();
- /// tx2.unbounded_send(Ok(4)).unwrap();
/// });
/// thread::spawn(move || {
/// tx3.unbounded_send(Ok(rx1)).unwrap();
/// tx3.unbounded_send(Ok(rx2)).unwrap();
- /// tx3.unbounded_send(Err(5)).unwrap();
+ /// tx3.unbounded_send(Err(4)).unwrap();
/// });
///
/// let mut stream = rx3.try_flatten();
/// assert_eq!(stream.next().await, Some(Ok(1)));
/// assert_eq!(stream.next().await, Some(Ok(2)));
/// assert_eq!(stream.next().await, Some(Err(3)));
- /// assert_eq!(stream.next().await, Some(Ok(4)));
- /// assert_eq!(stream.next().await, Some(Err(5)));
- /// assert_eq!(stream.next().await, None);
/// # });
/// ```
fn try_flatten(self) -> TryFlatten<Self>
@@ -900,7 +836,7 @@ pub trait TryStreamExt: TryStream {
/// assert_eq!(buffered.next().await, Some(Err("error in the stream")));
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
- #[cfg(not(futures_no_atomic_cas))]
+ #[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
#[cfg(feature = "alloc")]
fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
where
@@ -976,16 +912,14 @@ pub trait TryStreamExt: TryStream {
/// assert_eq!(buffered.next().await, Some(Err("error in the stream")));
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
- #[cfg(not(futures_no_atomic_cas))]
+ #[cfg_attr(feature = "cfg-target-has-atomic", cfg(target_has_atomic = "ptr"))]
#[cfg(feature = "alloc")]
fn try_buffered(self, n: usize) -> TryBuffered<Self>
where
Self::Ok: TryFuture<Error = Self::Error>,
Self: Sized,
{
- assert_stream::<Result<<Self::Ok as TryFuture>::Ok, Self::Error>, _>(TryBuffered::new(
- self, n,
- ))
+ assert_stream::<Result<<Self::Ok as TryFuture>::Ok, Self::Error>, _>(TryBuffered::new(self, n))
}
// TODO: false positive warning from rustdoc. Verify once #43466 settles
@@ -1005,7 +939,6 @@ pub trait TryStreamExt: TryStream {
/// Wraps a [`TryStream`] into a stream compatible with libraries using
/// futures 0.1 `Stream`. Requires the `compat` feature to be enabled.
/// ```
- /// # if cfg!(miri) { return; } // Miri does not support epoll
/// use futures::future::{FutureExt, TryFutureExt};
/// # let (tx, rx) = futures::channel::oneshot::channel();
///
diff --git a/src/stream/try_stream/or_else.rs b/src/stream/try_stream/or_else.rs
index cb69e81..999123a 100644
--- a/src/stream/try_stream/or_else.rs
+++ b/src/stream/try_stream/or_else.rs
@@ -2,7 +2,7 @@ use core::fmt;
use core::pin::Pin;
use futures_core::future::TryFuture;
use futures_core::ready;
-use futures_core::stream::{FusedStream, Stream, TryStream};
+use futures_core::stream::{Stream, TryStream, FusedStream};
use futures_core::task::{Context, Poll};
#[cfg(feature = "sink")]
use futures_sink::Sink;
@@ -34,10 +34,9 @@ where
}
impl<St, Fut, F> OrElse<St, Fut, F>
-where
- St: TryStream,
- F: FnMut(St::Error) -> Fut,
- Fut: TryFuture<Ok = St::Ok>,
+ where St: TryStream,
+ F: FnMut(St::Error) -> Fut,
+ Fut: TryFuture<Ok = St::Ok>,
{
pub(super) fn new(stream: St, f: F) -> Self {
Self { stream, future: None, f }
@@ -47,14 +46,16 @@ where
}
impl<St, Fut, F> Stream for OrElse<St, Fut, F>
-where
- St: TryStream,
- F: FnMut(St::Error) -> Fut,
- Fut: TryFuture<Ok = St::Ok>,
+ where St: TryStream,
+ F: FnMut(St::Error) -> Fut,
+ Fut: TryFuture<Ok = St::Ok>,
{
type Item = Result<St::Ok, Fut::Error>;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
let mut this = self.project();
Poll::Ready(loop {
@@ -67,7 +68,7 @@ where
Some(Ok(item)) => break Some(Ok(item)),
Some(Err(e)) => {
this.future.set(Some((this.f)(e)));
- }
+ },
None => break None,
}
}
@@ -87,10 +88,9 @@ where
}
impl<St, Fut, F> FusedStream for OrElse<St, Fut, F>
-where
- St: TryStream + FusedStream,
- F: FnMut(St::Error) -> Fut,
- Fut: TryFuture<Ok = St::Ok>,
+ where St: TryStream + FusedStream,
+ F: FnMut(St::Error) -> Fut,
+ Fut: TryFuture<Ok = St::Ok>,
{
fn is_terminated(&self) -> bool {
self.future.is_none() && self.stream.is_terminated()
@@ -100,8 +100,7 @@ where
// Forwarding impl of Sink from the underlying stream
#[cfg(feature = "sink")]
impl<S, Fut, F, Item> Sink<Item> for OrElse<S, Fut, F>
-where
- S: Sink<Item>,
+ where S: Sink<Item>,
{
type Error = S::Error;
diff --git a/src/stream/try_stream/try_buffer_unordered.rs b/src/stream/try_stream/try_buffer_unordered.rs
index 9a899d4..71c6fc7 100644
--- a/src/stream/try_stream/try_buffer_unordered.rs
+++ b/src/stream/try_stream/try_buffer_unordered.rs
@@ -1,12 +1,12 @@
+use crate::stream::{Fuse, FuturesUnordered, StreamExt, IntoStream};
use crate::future::{IntoFuture, TryFutureExt};
-use crate::stream::{Fuse, FuturesUnordered, IntoStream, StreamExt};
-use core::pin::Pin;
use futures_core::future::TryFuture;
use futures_core::stream::{Stream, TryStream};
use futures_core::task::{Context, Poll};
#[cfg(feature = "sink")]
use futures_sink::Sink;
use pin_project_lite::pin_project;
+use core::pin::Pin;
pin_project! {
/// Stream for the
@@ -24,9 +24,8 @@ pin_project! {
}
impl<St> TryBufferUnordered<St>
-where
- St: TryStream,
- St::Ok: TryFuture,
+ where St: TryStream,
+ St::Ok: TryFuture,
{
pub(super) fn new(stream: St, n: usize) -> Self {
Self {
@@ -40,13 +39,15 @@ where
}
impl<St> Stream for TryBufferUnordered<St>
-where
- St: TryStream,
- St::Ok: TryFuture<Error = St::Error>,
+ where St: TryStream,
+ St::Ok: TryFuture<Error = St::Error>,
{
type Item = Result<<St::Ok as TryFuture>::Ok, St::Error>;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
let mut this = self.project();
// First up, try to spawn off as many futures as possible by filling up
@@ -76,9 +77,8 @@ where
// Forwarding impl of Sink from the underlying stream
#[cfg(feature = "sink")]
impl<S, Item, E> Sink<Item> for TryBufferUnordered<S>
-where
- S: TryStream + Sink<Item, Error = E>,
- S::Ok: TryFuture<Error = E>,
+ where S: TryStream + Sink<Item, Error = E>,
+ S::Ok: TryFuture<Error = E>,
{
type Error = E;
diff --git a/src/stream/try_stream/try_buffered.rs b/src/stream/try_stream/try_buffered.rs
index 45bd3f8..ff7e844 100644
--- a/src/stream/try_stream/try_buffered.rs
+++ b/src/stream/try_stream/try_buffered.rs
@@ -1,12 +1,12 @@
+use crate::stream::{Fuse, FuturesOrdered, StreamExt, IntoStream};
use crate::future::{IntoFuture, TryFutureExt};
-use crate::stream::{Fuse, FuturesOrdered, IntoStream, StreamExt};
-use core::pin::Pin;
use futures_core::future::TryFuture;
use futures_core::stream::{Stream, TryStream};
use futures_core::task::{Context, Poll};
#[cfg(feature = "sink")]
use futures_sink::Sink;
use pin_project_lite::pin_project;
+use core::pin::Pin;
pin_project! {
/// Stream for the [`try_buffered`](super::TryStreamExt::try_buffered) method.
@@ -47,7 +47,10 @@ where
{
type Item = Result<<St::Ok as TryFuture>::Ok, St::Error>;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
let mut this = self.project();
// First up, try to spawn off as many futures as possible by filling up
diff --git a/src/stream/try_stream/try_chunks.rs b/src/stream/try_stream/try_chunks.rs
deleted file mode 100644
index 07d4425..0000000
--- a/src/stream/try_stream/try_chunks.rs
+++ /dev/null
@@ -1,131 +0,0 @@
-use crate::stream::{Fuse, IntoStream, StreamExt};
-
-use alloc::vec::Vec;
-use core::pin::Pin;
-use core::{fmt, mem};
-use futures_core::ready;
-use futures_core::stream::{FusedStream, Stream, TryStream};
-use futures_core::task::{Context, Poll};
-#[cfg(feature = "sink")]
-use futures_sink::Sink;
-use pin_project_lite::pin_project;
-
-pin_project! {
- /// Stream for the [`try_chunks`](super::TryStreamExt::try_chunks) method.
- #[derive(Debug)]
- #[must_use = "streams do nothing unless polled"]
- pub struct TryChunks<St: TryStream> {
- #[pin]
- stream: Fuse<IntoStream<St>>,
- items: Vec<St::Ok>,
- cap: usize, // https://github.com/rust-lang/futures-rs/issues/1475
- }
-}
-
-impl<St: TryStream> TryChunks<St> {
- pub(super) fn new(stream: St, capacity: usize) -> Self {
- assert!(capacity > 0);
-
- Self {
- stream: IntoStream::new(stream).fuse(),
- items: Vec::with_capacity(capacity),
- cap: capacity,
- }
- }
-
- fn take(self: Pin<&mut Self>) -> Vec<St::Ok> {
- let cap = self.cap;
- mem::replace(self.project().items, Vec::with_capacity(cap))
- }
-
- delegate_access_inner!(stream, St, (. .));
-}
-
-impl<St: TryStream> Stream for TryChunks<St> {
- #[allow(clippy::type_complexity)]
- type Item = Result<Vec<St::Ok>, TryChunksError<St::Ok, St::Error>>;
-
- fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
- let mut this = self.as_mut().project();
- loop {
- match ready!(this.stream.as_mut().try_poll_next(cx)) {
- // Push the item into the buffer and check whether it is full.
- // If so, replace our buffer with a new and empty one and return
- // the full one.
- Some(item) => match item {
- Ok(item) => {
- this.items.push(item);
- if this.items.len() >= *this.cap {
- return Poll::Ready(Some(Ok(self.take())));
- }
- }
- Err(e) => {
- return Poll::Ready(Some(Err(TryChunksError(self.take(), e))));
- }
- },
-
- // Since the underlying stream ran out of values, return what we
- // have buffered, if we have anything.
- None => {
- let last = if this.items.is_empty() {
- None
- } else {
- let full_buf = mem::replace(this.items, Vec::new());
- Some(full_buf)
- };
-
- return Poll::Ready(last.map(Ok));
- }
- }
- }
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- let chunk_len = if self.items.is_empty() { 0 } else { 1 };
- let (lower, upper) = self.stream.size_hint();
- let lower = lower.saturating_add(chunk_len);
- let upper = match upper {
- Some(x) => x.checked_add(chunk_len),
- None => None,
- };
- (lower, upper)
- }
-}
-
-impl<St: TryStream + FusedStream> FusedStream for TryChunks<St> {
- fn is_terminated(&self) -> bool {
- self.stream.is_terminated() && self.items.is_empty()
- }
-}
-
-// Forwarding impl of Sink from the underlying stream
-#[cfg(feature = "sink")]
-impl<S, Item> Sink<Item> for TryChunks<S>
-where
- S: TryStream + Sink<Item>,
-{
- type Error = <S as Sink<Item>>::Error;
-
- delegate_sink!(stream, Item);
-}
-
-/// Error indicating, that while chunk was collected inner stream produced an error.
-///
-/// Contains all items that were collected before an error occurred, and the stream error itself.
-#[derive(PartialEq, Eq)]
-pub struct TryChunksError<T, E>(pub Vec<T>, pub E);
-
-impl<T, E: fmt::Debug> fmt::Debug for TryChunksError<T, E> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.1.fmt(f)
- }
-}
-
-impl<T, E: fmt::Display> fmt::Display for TryChunksError<T, E> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.1.fmt(f)
- }
-}
-
-#[cfg(feature = "std")]
-impl<T, E: fmt::Debug + fmt::Display> std::error::Error for TryChunksError<T, E> {}
diff --git a/src/stream/try_stream/try_collect.rs b/src/stream/try_stream/try_collect.rs
index 5d3b3d7..387de97 100644
--- a/src/stream/try_stream/try_collect.rs
+++ b/src/stream/try_stream/try_collect.rs
@@ -19,7 +19,10 @@ pin_project! {
impl<St: TryStream, C: Default> TryCollect<St, C> {
pub(super) fn new(s: St) -> Self {
- Self { stream: s, items: Default::default() }
+ Self {
+ stream: s,
+ items: Default::default(),
+ }
}
}
@@ -40,7 +43,10 @@ where
{
type Output = Result<C, St::Error>;
- fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ fn poll(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Self::Output> {
let mut this = self.project();
Poll::Ready(Ok(loop {
match ready!(this.stream.as_mut().try_poll_next(cx)?) {
diff --git a/src/stream/try_stream/try_concat.rs b/src/stream/try_stream/try_concat.rs
index 58fb6a5..2451332 100644
--- a/src/stream/try_stream/try_concat.rs
+++ b/src/stream/try_stream/try_concat.rs
@@ -22,7 +22,10 @@ where
St::Ok: Extend<<St::Ok as IntoIterator>::Item> + IntoIterator + Default,
{
pub(super) fn new(stream: St) -> Self {
- Self { stream, accum: None }
+ Self {
+ stream,
+ accum: None,
+ }
}
}
diff --git a/src/stream/try_stream/try_filter.rs b/src/stream/try_stream/try_filter.rs
index 61e6105..eacefd2 100644
--- a/src/stream/try_stream/try_filter.rs
+++ b/src/stream/try_stream/try_filter.rs
@@ -2,7 +2,7 @@ use core::fmt;
use core::pin::Pin;
use futures_core::future::Future;
use futures_core::ready;
-use futures_core::stream::{FusedStream, Stream, TryStream};
+use futures_core::stream::{Stream, TryStream, FusedStream};
use futures_core::task::{Context, Poll};
#[cfg(feature = "sink")]
use futures_sink::Sink;
@@ -40,21 +40,24 @@ where
}
impl<St, Fut, F> TryFilter<St, Fut, F>
-where
- St: TryStream,
+ where St: TryStream
{
pub(super) fn new(stream: St, f: F) -> Self {
- Self { stream, f, pending_fut: None, pending_item: None }
+ Self {
+ stream,
+ f,
+ pending_fut: None,
+ pending_item: None,
+ }
}
delegate_access_inner!(stream, St, ());
}
impl<St, Fut, F> FusedStream for TryFilter<St, Fut, F>
-where
- St: TryStream + FusedStream,
- F: FnMut(&St::Ok) -> Fut,
- Fut: Future<Output = bool>,
+ where St: TryStream + FusedStream,
+ F: FnMut(&St::Ok) -> Fut,
+ Fut: Future<Output = bool>,
{
fn is_terminated(&self) -> bool {
self.pending_fut.is_none() && self.stream.is_terminated()
@@ -62,14 +65,16 @@ where
}
impl<St, Fut, F> Stream for TryFilter<St, Fut, F>
-where
- St: TryStream,
- Fut: Future<Output = bool>,
- F: FnMut(&St::Ok) -> Fut,
+ where St: TryStream,
+ Fut: Future<Output = bool>,
+ F: FnMut(&St::Ok) -> Fut,
{
type Item = Result<St::Ok, St::Error>;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
let mut this = self.project();
Poll::Ready(loop {
@@ -103,8 +108,7 @@ where
// Forwarding impl of Sink from the underlying stream
#[cfg(feature = "sink")]
impl<S, Fut, F, Item, E> Sink<Item> for TryFilter<S, Fut, F>
-where
- S: TryStream + Sink<Item, Error = E>,
+ where S: TryStream + Sink<Item, Error = E>,
{
type Error = E;
diff --git a/src/stream/try_stream/try_filter_map.rs b/src/stream/try_stream/try_filter_map.rs
index bb1b5b9..335649b 100644
--- a/src/stream/try_stream/try_filter_map.rs
+++ b/src/stream/try_stream/try_filter_map.rs
@@ -1,8 +1,8 @@
use core::fmt;
use core::pin::Pin;
-use futures_core::future::TryFuture;
+use futures_core::future::{TryFuture};
use futures_core::ready;
-use futures_core::stream::{FusedStream, Stream, TryStream};
+use futures_core::stream::{Stream, TryStream, FusedStream};
use futures_core::task::{Context, Poll};
#[cfg(feature = "sink")]
use futures_sink::Sink;
@@ -43,10 +43,9 @@ impl<St, Fut, F> TryFilterMap<St, Fut, F> {
}
impl<St, Fut, F, T> FusedStream for TryFilterMap<St, Fut, F>
-where
- St: TryStream + FusedStream,
- Fut: TryFuture<Ok = Option<T>, Error = St::Error>,
- F: FnMut(St::Ok) -> Fut,
+ where St: TryStream + FusedStream,
+ Fut: TryFuture<Ok = Option<T>, Error = St::Error>,
+ F: FnMut(St::Ok) -> Fut,
{
fn is_terminated(&self) -> bool {
self.pending.is_none() && self.stream.is_terminated()
@@ -54,14 +53,16 @@ where
}
impl<St, Fut, F, T> Stream for TryFilterMap<St, Fut, F>
-where
- St: TryStream,
- Fut: TryFuture<Ok = Option<T>, Error = St::Error>,
- F: FnMut(St::Ok) -> Fut,
+ where St: TryStream,
+ Fut: TryFuture<Ok = Option<T>, Error = St::Error>,
+ F: FnMut(St::Ok) -> Fut,
{
type Item = Result<T, St::Error>;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
let mut this = self.project();
Poll::Ready(loop {
@@ -97,8 +98,7 @@ where
// Forwarding impl of Sink from the underlying stream
#[cfg(feature = "sink")]
impl<S, Fut, F, Item> Sink<Item> for TryFilterMap<S, Fut, F>
-where
- S: Sink<Item>,
+ where S: Sink<Item>,
{
type Error = S::Error;
diff --git a/src/stream/try_stream/try_fold.rs b/src/stream/try_stream/try_fold.rs
index d344d96..1d41e4b 100644
--- a/src/stream/try_stream/try_fold.rs
+++ b/src/stream/try_stream/try_fold.rs
@@ -35,21 +35,24 @@ where
}
impl<St, Fut, T, F> TryFold<St, Fut, T, F>
-where
- St: TryStream,
- F: FnMut(T, St::Ok) -> Fut,
- Fut: TryFuture<Ok = T, Error = St::Error>,
+where St: TryStream,
+ F: FnMut(T, St::Ok) -> Fut,
+ Fut: TryFuture<Ok = T, Error = St::Error>,
{
pub(super) fn new(stream: St, f: F, t: T) -> Self {
- Self { stream, f, accum: Some(t), future: None }
+ Self {
+ stream,
+ f,
+ accum: Some(t),
+ future: None,
+ }
}
}
impl<St, Fut, T, F> FusedFuture for TryFold<St, Fut, T, F>
-where
- St: TryStream,
- F: FnMut(T, St::Ok) -> Fut,
- Fut: TryFuture<Ok = T, Error = St::Error>,
+ where St: TryStream,
+ F: FnMut(T, St::Ok) -> Fut,
+ Fut: TryFuture<Ok = T, Error = St::Error>,
{
fn is_terminated(&self) -> bool {
self.accum.is_none() && self.future.is_none()
@@ -57,10 +60,9 @@ where
}
impl<St, Fut, T, F> Future for TryFold<St, Fut, T, F>
-where
- St: TryStream,
- F: FnMut(T, St::Ok) -> Fut,
- Fut: TryFuture<Ok = T, Error = St::Error>,
+ where St: TryStream,
+ F: FnMut(T, St::Ok) -> Fut,
+ Fut: TryFuture<Ok = T, Error = St::Error>,
{
type Output = Result<T, St::Error>;
diff --git a/src/stream/try_stream/try_for_each.rs b/src/stream/try_stream/try_for_each.rs
index 6a081d8..0a814ae 100644
--- a/src/stream/try_stream/try_for_each.rs
+++ b/src/stream/try_stream/try_for_each.rs
@@ -32,21 +32,23 @@ where
}
impl<St, Fut, F> TryForEach<St, Fut, F>
-where
- St: TryStream,
- F: FnMut(St::Ok) -> Fut,
- Fut: TryFuture<Ok = (), Error = St::Error>,
+where St: TryStream,
+ F: FnMut(St::Ok) -> Fut,
+ Fut: TryFuture<Ok = (), Error = St::Error>,
{
pub(super) fn new(stream: St, f: F) -> Self {
- Self { stream, f, future: None }
+ Self {
+ stream,
+ f,
+ future: None,
+ }
}
}
impl<St, Fut, F> Future for TryForEach<St, Fut, F>
-where
- St: TryStream,
- F: FnMut(St::Ok) -> Fut,
- Fut: TryFuture<Ok = (), Error = St::Error>,
+ where St: TryStream,
+ F: FnMut(St::Ok) -> Fut,
+ Fut: TryFuture<Ok = (), Error = St::Error>,
{
type Output = Result<(), St::Error>;
diff --git a/src/stream/try_stream/try_for_each_concurrent.rs b/src/stream/try_stream/try_for_each_concurrent.rs
index 62734c7..d2f4b0f 100644
--- a/src/stream/try_stream/try_for_each_concurrent.rs
+++ b/src/stream/try_stream/try_for_each_concurrent.rs
@@ -1,8 +1,8 @@
use crate::stream::{FuturesUnordered, StreamExt};
use core::fmt;
use core::mem;
-use core::num::NonZeroUsize;
use core::pin::Pin;
+use core::num::NonZeroUsize;
use futures_core::future::{FusedFuture, Future};
use futures_core::stream::TryStream;
use futures_core::task::{Context, Poll};
@@ -37,10 +37,9 @@ where
}
impl<St, Fut, F> FusedFuture for TryForEachConcurrent<St, Fut, F>
-where
- St: TryStream,
- F: FnMut(St::Ok) -> Fut,
- Fut: Future<Output = Result<(), St::Error>>,
+ where St: TryStream,
+ F: FnMut(St::Ok) -> Fut,
+ Fut: Future<Output = Result<(), St::Error>>,
{
fn is_terminated(&self) -> bool {
self.stream.is_none() && self.futures.is_empty()
@@ -48,10 +47,9 @@ where
}
impl<St, Fut, F> TryForEachConcurrent<St, Fut, F>
-where
- St: TryStream,
- F: FnMut(St::Ok) -> Fut,
- Fut: Future<Output = Result<(), St::Error>>,
+where St: TryStream,
+ F: FnMut(St::Ok) -> Fut,
+ Fut: Future<Output = Result<(), St::Error>>,
{
pub(super) fn new(stream: St, limit: Option<usize>, f: F) -> Self {
Self {
@@ -65,10 +63,9 @@ where
}
impl<St, Fut, F> Future for TryForEachConcurrent<St, Fut, F>
-where
- St: TryStream,
- F: FnMut(St::Ok) -> Fut,
- Fut: Future<Output = Result<(), St::Error>>,
+ where St: TryStream,
+ F: FnMut(St::Ok) -> Fut,
+ Fut: Future<Output = Result<(), St::Error>>,
{
type Output = Result<(), St::Error>;
@@ -88,7 +85,7 @@ where
Poll::Ready(Some(Ok(elem))) => {
made_progress_this_iter = true;
Some(elem)
- }
+ },
Poll::Ready(None) => {
this.stream.set(None);
None
@@ -112,9 +109,9 @@ where
Poll::Ready(Some(Ok(()))) => made_progress_this_iter = true,
Poll::Ready(None) => {
if this.stream.is_none() {
- return Poll::Ready(Ok(()));
+ return Poll::Ready(Ok(()))
}
- }
+ },
Poll::Pending => {}
Poll::Ready(Some(Err(e))) => {
// Empty the stream and futures so that we know
diff --git a/src/stream/try_stream/try_next.rs b/src/stream/try_stream/try_next.rs
index 13fcf80..1bc00fb 100644
--- a/src/stream/try_stream/try_next.rs
+++ b/src/stream/try_stream/try_next.rs
@@ -28,7 +28,10 @@ impl<St: ?Sized + TryStream + Unpin + FusedStream> FusedFuture for TryNext<'_, S
impl<St: ?Sized + TryStream + Unpin> Future for TryNext<'_, St> {
type Output = Result<Option<St::Ok>, St::Error>;
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ fn poll(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Self::Output> {
self.stream.try_poll_next_unpin(cx)?.map(Ok)
}
}
diff --git a/src/stream/try_stream/try_skip_while.rs b/src/stream/try_stream/try_skip_while.rs
index a424b6c..0603b10 100644
--- a/src/stream/try_stream/try_skip_while.rs
+++ b/src/stream/try_stream/try_skip_while.rs
@@ -2,7 +2,7 @@ use core::fmt;
use core::pin::Pin;
use futures_core::future::TryFuture;
use futures_core::ready;
-use futures_core::stream::{FusedStream, Stream, TryStream};
+use futures_core::stream::{Stream, TryStream, FusedStream};
use futures_core::task::{Context, Poll};
#[cfg(feature = "sink")]
use futures_sink::Sink;
@@ -40,27 +40,34 @@ where
}
impl<St, Fut, F> TrySkipWhile<St, Fut, F>
-where
- St: TryStream,
- F: FnMut(&St::Ok) -> Fut,
- Fut: TryFuture<Ok = bool, Error = St::Error>,
+ where St: TryStream,
+ F: FnMut(&St::Ok) -> Fut,
+ Fut: TryFuture<Ok = bool, Error = St::Error>,
{
pub(super) fn new(stream: St, f: F) -> Self {
- Self { stream, f, pending_fut: None, pending_item: None, done_skipping: false }
+ Self {
+ stream,
+ f,
+ pending_fut: None,
+ pending_item: None,
+ done_skipping: false,
+ }
}
delegate_access_inner!(stream, St, ());
}
impl<St, Fut, F> Stream for TrySkipWhile<St, Fut, F>
-where
- St: TryStream,
- F: FnMut(&St::Ok) -> Fut,
- Fut: TryFuture<Ok = bool, Error = St::Error>,
+ where St: TryStream,
+ F: FnMut(&St::Ok) -> Fut,
+ Fut: TryFuture<Ok = bool, Error = St::Error>,
{
type Item = Result<St::Ok, St::Error>;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
let mut this = self.project();
if *this.done_skipping {
@@ -98,10 +105,9 @@ where
}
impl<St, Fut, F> FusedStream for TrySkipWhile<St, Fut, F>
-where
- St: TryStream + FusedStream,
- F: FnMut(&St::Ok) -> Fut,
- Fut: TryFuture<Ok = bool, Error = St::Error>,
+ where St: TryStream + FusedStream,
+ F: FnMut(&St::Ok) -> Fut,
+ Fut: TryFuture<Ok = bool, Error = St::Error>,
{
fn is_terminated(&self) -> bool {
self.pending_item.is_none() && self.stream.is_terminated()
@@ -111,8 +117,7 @@ where
// Forwarding impl of Sink from the underlying stream
#[cfg(feature = "sink")]
impl<S, Fut, F, Item, E> Sink<Item> for TrySkipWhile<S, Fut, F>
-where
- S: TryStream + Sink<Item, Error = E>,
+ where S: TryStream + Sink<Item, Error = E>,
{
type Error = E;
diff --git a/src/stream/try_stream/try_take_while.rs b/src/stream/try_stream/try_take_while.rs
index 3375960..6241572 100644
--- a/src/stream/try_stream/try_take_while.rs
+++ b/src/stream/try_stream/try_take_while.rs
@@ -49,7 +49,13 @@ where
Fut: TryFuture<Ok = bool, Error = St::Error>,
{
pub(super) fn new(stream: St, f: F) -> Self {
- Self { stream, f, pending_fut: None, pending_item: None, done_taking: false }
+ Self {
+ stream,
+ f,
+ pending_fut: None,
+ pending_item: None,
+ done_taking: false,
+ }
}
delegate_access_inner!(stream, St, ());
diff --git a/src/stream/try_stream/try_unfold.rs b/src/stream/try_stream/try_unfold.rs
index fd9cdf1..258c18e 100644
--- a/src/stream/try_stream/try_unfold.rs
+++ b/src/stream/try_stream/try_unfold.rs
@@ -61,7 +61,11 @@ where
F: FnMut(T) -> Fut,
Fut: TryFuture<Ok = Option<(Item, T)>>,
{
- assert_stream::<Result<Item, Fut::Error>, _>(TryUnfold { f, state: Some(init), fut: None })
+ assert_stream::<Result<Item, Fut::Error>, _>(TryUnfold {
+ f,
+ state: Some(init),
+ fut: None,
+ })
}
pin_project! {
@@ -81,7 +85,10 @@ where
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()
+ f.debug_struct("TryUnfold")
+ .field("state", &self.state)
+ .field("fut", &self.fut)
+ .finish()
}
}
@@ -92,7 +99,10 @@ where
{
type Item = Result<Item, Fut::Error>;
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ fn poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Self::Item>> {
let mut this = self.project();
if let Some(state) = this.state.take() {
diff --git a/src/stream/unfold.rs b/src/stream/unfold.rs
index 7d8ef6b..e17d465 100644
--- a/src/stream/unfold.rs
+++ b/src/stream/unfold.rs
@@ -52,7 +52,10 @@ where
F: FnMut(T) -> Fut,
Fut: Future<Output = Option<(Item, T)>>,
{
- assert_stream::<Item, _>(Unfold { f, state: UnfoldState::Value { value: init } })
+ assert_stream::<Item, _>(Unfold {
+ f,
+ state: UnfoldState::Value { value: init },
+ })
}
pin_project! {
@@ -71,7 +74,9 @@ where
Fut: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Unfold").field("state", &self.state).finish()
+ f.debug_struct("Unfold")
+ .field("state", &self.state)
+ .finish()
}
}
@@ -100,7 +105,9 @@ where
let mut this = self.project();
if let Some(state) = this.state.as_mut().take_value() {
- this.state.set(UnfoldState::Future { future: (this.f)(state) });
+ this.state.set(UnfoldState::Future {
+ future: (this.f)(state),
+ });
}
let step = match this.state.as_mut().project_future() {
diff --git a/src/task/mod.rs b/src/task/mod.rs
index 0a31eea..dd1515c 100644
--- a/src/task/mod.rs
+++ b/src/task/mod.rs
@@ -11,27 +11,29 @@
//! executors or dealing with synchronization issues around task wakeup.
#[doc(no_inline)]
-pub use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
+pub use core::task::{Context, Poll, Waker, RawWaker, RawWakerVTable};
-pub use futures_task::{FutureObj, LocalFutureObj, LocalSpawn, Spawn, SpawnError, UnsafeFutureObj};
+pub use futures_task::{
+ Spawn, LocalSpawn, SpawnError,
+ FutureObj, LocalFutureObj, UnsafeFutureObj,
+};
pub use futures_task::noop_waker;
+#[cfg(feature = "std")]
pub use futures_task::noop_waker_ref;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-pub use futures_task::ArcWake;
+cfg_target_has_atomic! {
+ #[cfg(feature = "alloc")]
+ pub use futures_task::ArcWake;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-pub use futures_task::waker;
+ #[cfg(feature = "alloc")]
+ pub use futures_task::waker;
-#[cfg(not(futures_no_atomic_cas))]
-#[cfg(feature = "alloc")]
-pub use futures_task::{waker_ref, WakerRef};
+ #[cfg(feature = "alloc")]
+ pub use futures_task::{waker_ref, WakerRef};
-#[cfg(not(futures_no_atomic_cas))]
-pub use futures_core::task::__internal::AtomicWaker;
+ pub use futures_core::task::__internal::AtomicWaker;
+}
mod spawn;
-pub use self::spawn::{LocalSpawnExt, SpawnExt};
+pub use self::spawn::{SpawnExt, LocalSpawnExt};
diff --git a/src/task/spawn.rs b/src/task/spawn.rs
index 87ca360..f877923 100644
--- a/src/task/spawn.rs
+++ b/src/task/spawn.rs
@@ -34,7 +34,6 @@ pub trait SpawnExt: Spawn {
/// today. Feel free to use this method in the meantime.
///
/// ```
- /// # if cfg!(miri) { return; } // https://github.com/rust-lang/miri/issues/1038
/// use futures::executor::ThreadPool;
/// use futures::task::SpawnExt;
///
@@ -59,7 +58,6 @@ pub trait SpawnExt: Spawn {
/// resolves to the output of the spawned future.
///
/// ```
- /// # if cfg!(miri) { return; } // https://github.com/rust-lang/miri/issues/1038
/// use futures::executor::{block_on, ThreadPool};
/// use futures::future;
/// use futures::task::SpawnExt;
@@ -138,7 +136,6 @@ pub trait LocalSpawnExt: LocalSpawn {
/// resolves to the output of the spawned future.
///
/// ```
- /// # if cfg!(miri) { return; } // https://github.com/rust-lang/miri/issues/1038
/// use futures::executor::LocalPool;
/// use futures::task::LocalSpawnExt;
///