chore: checkpoint before Python removal

This commit is contained in:
2026-03-26 22:33:59 +00:00
parent 683cec9307
commit e568ddf82a
29972 changed files with 11269302 additions and 2 deletions

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
{
"git": {
"sha1": "d9bba94c239daa1175a5bb2958f37a5c72db3f6a"
},
"path_in_vcs": "futures-util"
}

693
vendor/futures-util/Cargo.lock generated vendored Normal file
View File

@@ -0,0 +1,693 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "autocfg"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bytes"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cloudabi"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-deque"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-epoch"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-queue"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-utils"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fuchsia-zircon-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures"
version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures-channel"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures-core 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "futures-core"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"portable-atomic 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "futures-io"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures-macro"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 2.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "futures-sink"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures-task"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures-util"
version = "0.3.32"
dependencies = [
"futures 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-channel 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-core 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-io 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-macro 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-sink 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-task 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.175 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project-lite 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"spin 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hermit-abi"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "iovec"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.175 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "kernel32-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.175"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lock_api"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"scopeguard 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lock_api"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"scopeguard 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "log"
version = "0.4.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "maybe-uninit"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memchr"
version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memoffset"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mio"
version = "0.6.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.175 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mio-uds"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.175 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "miow"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "net2"
version = "0.2.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.175 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num_cpus"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hermit-abi 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.175 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parking_lot"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lock_api 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot_core 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parking_lot_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.175 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pin-project-lite"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "portable-atomic"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro2"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-ident 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "slab"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "smallvec"
version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "spin"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lock_api 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "2.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-ident 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-current-thread 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-fs 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-sync 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-tcp 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-threadpool 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-timer 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-udp 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-uds 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-codec"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-current-thread"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-executor"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-fs"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-threadpool 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-io"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-reactor"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-sync 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-sync"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-tcp"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-threadpool"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-deque 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-queue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-timer"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-udp"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-uds"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.175 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-uds 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ws2_32-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum autocfg 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
"checksum bitflags 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
"checksum byteorder 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum crossbeam-deque 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c20ff29ded3204c5106278a81a38f4b482636ed4fa1e6cfbeef193291beb29ed"
"checksum crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
"checksum crossbeam-queue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570"
"checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
"checksum fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum futures 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678"
"checksum futures-channel 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
"checksum futures-core 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
"checksum futures-io 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
"checksum futures-macro 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
"checksum futures-sink 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
"checksum futures-task 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
"checksum hermit-abi 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
"checksum libc 0.2.175 (registry+https://github.com/rust-lang/crates.io-index)" = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
"checksum lock_api 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75"
"checksum lock_api 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
"checksum log 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)" = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
"checksum memchr 2.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
"checksum memoffset 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa"
"checksum mio 0.6.23 (registry+https://github.com/rust-lang/crates.io-index)" = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4"
"checksum mio-uds 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0"
"checksum miow 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d"
"checksum net2 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)" = "b13b648036a2339d06de780866fbdfda0dde886de7b3af2ddeba8b14f4ee34ac"
"checksum num_cpus 1.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b"
"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252"
"checksum parking_lot_core 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bda66b810a62be75176a80873726630147a5ca780cd33921e0b5709033e66b0a"
"checksum pin-project-lite 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
"checksum portable-atomic 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
"checksum proc-macro2 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
"checksum quote 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
"checksum redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)" = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum scopeguard 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum slab 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
"checksum smallvec 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0"
"checksum spin 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591"
"checksum syn 2.0.106 (registry+https://github.com/rust-lang/crates.io-index)" = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
"checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6"
"checksum tokio-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "25b2998660ba0e70d18684de5d06b70b70a3a747469af9dea7618cc59e75976b"
"checksum tokio-current-thread 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e"
"checksum tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671"
"checksum tokio-fs 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "297a1206e0ca6302a0eed35b700d292b275256f596e2f3fea7729d5e629b6ff4"
"checksum tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674"
"checksum tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351"
"checksum tokio-sync 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee"
"checksum tokio-tcp 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72"
"checksum tokio-threadpool 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "df720b6581784c118f0eb4310796b12b1d242a7eb95f716a8367855325c25f89"
"checksum tokio-timer 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296"
"checksum tokio-udp 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a0b10e610b39c38b031a2fcab08e4b82f16ece36504988dcbd81dbba650d82"
"checksum tokio-uds 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ab57a4ac4111c8c9dbcf70779f6fc8bc35ae4b2454809febac840ad19bd7e4e0"
"checksum unicode-ident 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"

181
vendor/futures-util/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,181 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
rust-version = "1.71"
name = "futures-util"
version = "0.3.32"
build = false
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = """
Common utilities and extension traits for the futures-rs library.
"""
homepage = "https://rust-lang.github.io/futures-rs"
readme = "README.md"
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-lang/futures-rs"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = [
"--cfg",
"docsrs",
]
[features]
alloc = [
"futures-core/alloc",
"futures-task/alloc",
"slab",
]
async-await = []
async-await-macro = [
"async-await",
"futures-macro",
]
bilock = []
cfg-target-has-atomic = []
channel = [
"std",
"futures-channel",
]
compat = [
"std",
"futures_01",
"libc",
]
default = [
"std",
"async-await",
"async-await-macro",
]
io = [
"std",
"futures-io",
"memchr",
]
io-compat = [
"io",
"compat",
"tokio-io",
"libc",
]
portable-atomic = ["futures-core/portable-atomic"]
sink = ["futures-sink"]
std = [
"alloc",
"futures-core/std",
"futures-task/std",
"slab/std",
]
unstable = [
"futures-core/unstable",
"futures-task/unstable",
]
write-all-vectored = ["io"]
[lib]
name = "futures_util"
path = "src/lib.rs"
[[bench]]
name = "bilock"
path = "benches/bilock.rs"
[[bench]]
name = "flatten_unordered"
path = "benches/flatten_unordered.rs"
[[bench]]
name = "futures_unordered"
path = "benches/futures_unordered.rs"
[[bench]]
name = "select"
path = "benches/select.rs"
[dependencies.futures-channel]
version = "0.3.32"
features = ["std"]
optional = true
default-features = false
[dependencies.futures-core]
version = "0.3.32"
default-features = false
[dependencies.futures-io]
version = "0.3.32"
features = ["std"]
optional = true
default-features = false
[dependencies.futures-macro]
version = "=0.3.32"
optional = true
default-features = false
[dependencies.futures-sink]
version = "0.3.32"
optional = true
default-features = false
[dependencies.futures-task]
version = "0.3.32"
default-features = false
[dependencies.futures_01]
version = "0.1.25"
optional = true
package = "futures"
[dependencies.libc]
version = "0.2.26"
optional = true
[dependencies.memchr]
version = "2.2"
optional = true
[dependencies.pin-project-lite]
version = "0.2.6"
[dependencies.slab]
version = "0.4.7"
optional = true
default-features = false
[dependencies.spin]
version = "0.10.0"
optional = true
[dependencies.tokio-io]
version = "0.1.9"
optional = true
[dev-dependencies.tokio]
version = "0.1.11"
[lints.rust]
missing_debug_implementations = "warn"
rust_2018_idioms = "warn"
single_use_lifetimes = "warn"
unreachable_pub = "warn"
[lints.rust.unexpected_cfgs]
level = "warn"
priority = 0
check-cfg = ["cfg(futures_sanitizer)"]

202
vendor/futures-util/LICENSE-APACHE vendored Normal file
View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright (c) 2016 Alex Crichton
Copyright (c) 2017 The Tokio Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

26
vendor/futures-util/LICENSE-MIT vendored Normal file
View File

@@ -0,0 +1,26 @@
Copyright (c) 2016 Alex Crichton
Copyright (c) 2017 The Tokio Authors
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

23
vendor/futures-util/README.md vendored Normal file
View File

@@ -0,0 +1,23 @@
# 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.71 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.

68
vendor/futures-util/benches/bilock.rs vendored Normal file
View File

@@ -0,0 +1,68 @@
#![feature(test)]
#![cfg(feature = "bilock")]
extern crate test;
use futures::task::Poll;
use futures_test::task::noop_context;
use futures_util::lock::BiLock;
use crate::test::Bencher;
#[bench]
fn contended(b: &mut Bencher) {
let mut context = noop_context();
b.iter(|| {
let (x, y) = BiLock::new(1);
for _ in 0..1000 {
let x_guard = match x.poll_lock(&mut context) {
Poll::Ready(guard) => guard,
_ => panic!(),
};
// Try poll second lock while first lock still holds the lock
match y.poll_lock(&mut context) {
Poll::Pending => (),
_ => panic!(),
};
drop(x_guard);
let y_guard = match y.poll_lock(&mut context) {
Poll::Ready(guard) => guard,
_ => panic!(),
};
drop(y_guard);
}
(x, y)
});
}
#[bench]
fn lock_unlock(b: &mut Bencher) {
let mut context = noop_context();
b.iter(|| {
let (x, y) = BiLock::new(1);
for _ in 0..1000 {
let x_guard = match x.poll_lock(&mut context) {
Poll::Ready(guard) => guard,
_ => panic!(),
};
drop(x_guard);
let y_guard = match y.poll_lock(&mut context) {
Poll::Ready(guard) => guard,
_ => panic!(),
};
drop(y_guard);
}
(x, y)
})
}

View File

@@ -0,0 +1,58 @@
#![feature(test)]
extern crate test;
use crate::test::Bencher;
use futures::channel::oneshot;
use futures::executor::block_on;
use futures::future;
use futures::stream::{self, StreamExt};
use futures::task::Poll;
use futures_util::FutureExt;
use std::collections::VecDeque;
use std::thread;
#[bench]
fn oneshot_streams(b: &mut Bencher) {
const STREAM_COUNT: usize = 10_000;
const STREAM_ITEM_COUNT: usize = 1;
b.iter(|| {
let mut txs = VecDeque::with_capacity(STREAM_COUNT);
let mut rxs = Vec::new();
for _ in 0..STREAM_COUNT {
let (tx, rx) = oneshot::channel();
txs.push_back(tx);
rxs.push(rx);
}
thread::spawn(move || {
let mut last = 1;
while let Some(tx) = txs.pop_front() {
let _ = tx.send(stream::iter(last..last + STREAM_ITEM_COUNT));
last += STREAM_ITEM_COUNT;
}
});
let mut flatten = stream::iter(rxs)
.map(|recv| recv.into_stream().map(|val| val.unwrap()).flatten())
.flatten_unordered(None);
block_on(future::poll_fn(move |cx| {
let mut count = 0;
loop {
match flatten.poll_next_unpin(cx) {
Poll::Ready(None) => break,
Poll::Ready(Some(_)) => {
count += 1;
}
_ => {}
}
}
assert_eq!(count, STREAM_COUNT * STREAM_ITEM_COUNT);
Poll::Ready(())
}))
});
}

View File

@@ -0,0 +1,43 @@
#![feature(test)]
extern crate test;
use crate::test::Bencher;
use futures::channel::oneshot;
use futures::executor::block_on;
use futures::future;
use futures::stream::{FuturesUnordered, StreamExt};
use futures::task::Poll;
use std::collections::VecDeque;
use std::thread;
#[bench]
fn oneshots(b: &mut Bencher) {
const NUM: usize = 10_000;
b.iter(|| {
let mut txs = VecDeque::with_capacity(NUM);
let mut rxs = FuturesUnordered::new();
for _ in 0..NUM {
let (tx, rx) = oneshot::channel();
txs.push_back(tx);
rxs.push(rx);
}
thread::spawn(move || {
while let Some(tx) = txs.pop_front() {
let _ = tx.send("hello");
}
});
block_on(future::poll_fn(move |cx| {
loop {
if let Poll::Ready(None) = rxs.poll_next_unpin(cx) {
break;
}
}
Poll::Ready(())
}))
});
}

35
vendor/futures-util/benches/select.rs vendored Normal file
View File

@@ -0,0 +1,35 @@
#![feature(test)]
extern crate test;
use crate::test::Bencher;
use futures::executor::block_on;
use futures::stream::{repeat, select, StreamExt};
#[bench]
fn select_streams(b: &mut Bencher) {
const STREAM_COUNT: usize = 10_000;
b.iter(|| {
let stream1 = repeat(1).take(STREAM_COUNT);
let stream2 = repeat(2).take(STREAM_COUNT);
let stream3 = repeat(3).take(STREAM_COUNT);
let stream4 = repeat(4).take(STREAM_COUNT);
let stream5 = repeat(5).take(STREAM_COUNT);
let stream6 = repeat(6).take(STREAM_COUNT);
let stream7 = repeat(7).take(STREAM_COUNT);
let count = block_on(async {
let count = select(
stream1,
select(
stream2,
select(stream3, select(stream4, select(stream5, select(stream6, stream7)))),
),
)
.count()
.await;
count
});
assert_eq!(count, STREAM_COUNT * 7);
});
}

209
vendor/futures-util/src/abortable.rs vendored Normal file
View File

@@ -0,0 +1,209 @@
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 {
pub(crate) inner: Arc<AbortInner>,
}
impl AbortRegistration {
/// Create an [`AbortHandle`] from the given [`AbortRegistration`].
///
/// The created [`AbortHandle`] is functionally the same as any other
/// [`AbortHandle`]s that are associated with the same [`AbortRegistration`],
/// such as the one created by [`AbortHandle::new_pair`].
pub fn handle(&self) -> AbortHandle {
AbortHandle { inner: self.inner.clone() }
}
}
/// A handle to an `Abortable` task.
#[derive(Debug, Clone)]
pub struct AbortHandle {
inner: Arc<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)]
pub(crate) struct AbortInner {
pub(crate) waker: AtomicWaker,
pub(crate) aborted: AtomicBool,
}
/// Indicator that the `Abortable` task was aborted.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct Aborted;
impl fmt::Display for Aborted {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "`Abortable` future has been aborted")
}
}
#[cfg(feature = "std")]
impl std::error::Error for Aborted {}
impl<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();
}
/// Checks whether [`AbortHandle::abort`] was *called* on any associated
/// [`AbortHandle`]s, which includes all the [`AbortHandle`]s linked with
/// the same [`AbortRegistration`]. This means that it will return `true`
/// even if:
/// * `abort` was called after the task had completed.
/// * `abort` was called while the task was being polled - the task may still be running and
/// will not be stopped until `poll` returns.
///
/// This operation has a Relaxed ordering.
pub fn is_aborted(&self) -> bool {
self.inner.aborted.load(Ordering::Relaxed)
}
}

View File

@@ -0,0 +1,110 @@
//! The `join` macro.
macro_rules! document_join_macro {
($join:item $try_join:item) => {
/// Polls multiple futures simultaneously, returning a tuple
/// of all results once complete.
///
/// While `join!(a, b)` is similar to `(a.await, b.await)`,
/// `join!` polls both futures concurrently and therefore is more efficient.
///
/// This macro is only usable inside of async functions, closures, and blocks.
/// It is also gated behind the `async-await` feature of this library, which is
/// activated by default.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::join;
///
/// let a = async { 1 };
/// let b = async { 2 };
/// assert_eq!(join!(a, b), (1, 2));
///
/// // `join!` is variadic, so you can pass any number of futures
/// let c = async { 3 };
/// let d = async { 4 };
/// let e = async { 5 };
/// assert_eq!(join!(c, d, e), (3, 4, 5));
/// # });
/// ```
$join
/// Polls multiple futures simultaneously, resolving to a [`Result`] containing
/// either a tuple of the successful outputs or an error.
///
/// `try_join!` is similar to [`join!`], but completes immediately if any of
/// the futures return an error.
///
/// This macro is only usable inside of async functions, closures, and blocks.
/// It is also gated behind the `async-await` feature of this library, which is
/// activated by default.
///
/// # Examples
///
/// When used on multiple futures that return `Ok`, `try_join!` will return
/// `Ok` of a tuple of the values:
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::try_join;
///
/// let a = async { Ok::<i32, i32>(1) };
/// let b = async { Ok::<i32, i32>(2) };
/// assert_eq!(try_join!(a, b), Ok((1, 2)));
///
/// // `try_join!` is variadic, so you can pass any number of futures
/// let c = async { Ok::<i32, i32>(3) };
/// let d = async { Ok::<i32, i32>(4) };
/// let e = async { Ok::<i32, i32>(5) };
/// assert_eq!(try_join!(c, d, e), Ok((3, 4, 5)));
/// # });
/// ```
///
/// If one of the futures resolves to an error, `try_join!` will return
/// that error:
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::try_join;
///
/// let a = async { Ok::<i32, i32>(1) };
/// let b = async { Err::<u64, i32>(2) };
///
/// assert_eq!(try_join!(a, b), Err(2));
/// # });
/// ```
$try_join
}
}
#[allow(unreachable_pub)]
#[doc(hidden)]
pub use futures_macro::join_internal;
#[allow(unreachable_pub)]
#[doc(hidden)]
pub use futures_macro::try_join_internal;
document_join_macro! {
#[macro_export]
macro_rules! join {
($($tokens:tt)*) => {{
use $crate::__private as __futures_crate;
$crate::join_internal! {
$( $tokens )*
}
}}
}
#[macro_export]
macro_rules! try_join {
($($tokens:tt)*) => {{
use $crate::__private as __futures_crate;
$crate::try_join_internal! {
$( $tokens )*
}
}}
}
}

View File

@@ -0,0 +1,60 @@
//! Await
//!
//! This module contains a number of functions and combinators for working
//! with `async`/`await` code.
use futures_core::future::{FusedFuture, Future};
use futures_core::stream::{FusedStream, Stream};
#[macro_use]
mod poll;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762
pub use self::poll::*;
#[macro_use]
mod pending;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762
pub use self::pending::*;
// Primary export is a macro
#[cfg(feature = "async-await-macro")]
mod join_mod;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762
#[cfg(feature = "async-await-macro")]
pub use self::join_mod::*;
// Primary export is a macro
#[cfg(feature = "async-await-macro")]
mod select_mod;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762
#[cfg(feature = "async-await-macro")]
pub use self::select_mod::*;
// Primary export is a macro
#[cfg(feature = "std")]
#[cfg(feature = "async-await-macro")]
mod stream_select_mod;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762
#[cfg(feature = "std")]
#[cfg(feature = "async-await-macro")]
pub use self::stream_select_mod::*;
#[cfg(feature = "std")]
#[cfg(feature = "async-await-macro")]
mod random;
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/64762
#[cfg(feature = "std")]
#[cfg(feature = "async-await-macro")]
pub use self::random::*;
#[doc(hidden)]
#[inline(always)]
pub fn assert_unpin<T: Unpin>(_: &T) {}
#[doc(hidden)]
#[inline(always)]
pub fn assert_fused_future<T: Future + FusedFuture>(_: &T) {}
#[doc(hidden)]
#[inline(always)]
pub fn assert_fused_stream<T: Stream + FusedStream>(_: &T) {}

View File

@@ -0,0 +1,43 @@
use core::pin::Pin;
use futures_core::future::Future;
use futures_core::task::{Context, Poll};
/// A macro which yields to the event loop once.
///
/// This is equivalent to returning [`Poll::Pending`](futures_core::task::Poll)
/// from a [`Future::poll`](futures_core::future::Future::poll) implementation.
/// Similarly, when using this macro, it must be ensured that [`wake`](std::task::Waker::wake)
/// is called somewhere when further progress can be made.
///
/// This macro is only usable inside of async functions, closures, and blocks.
/// It is also gated behind the `async-await` feature of this library, which is
/// activated by default.
#[macro_export]
macro_rules! pending {
() => {
$crate::__private::async_await::pending_once().await
};
}
#[doc(hidden)]
pub fn pending_once() -> PendingOnce {
PendingOnce { is_ready: false }
}
#[allow(missing_debug_implementations)]
#[doc(hidden)]
pub struct PendingOnce {
is_ready: bool,
}
impl Future for PendingOnce {
type Output = ();
fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
if self.is_ready {
Poll::Ready(())
} else {
self.is_ready = true;
Poll::Pending
}
}
}

View File

@@ -0,0 +1,39 @@
use crate::future::FutureExt;
use core::pin::Pin;
use futures_core::future::Future;
use futures_core::task::{Context, Poll};
/// A macro which returns the result of polling a future once within the
/// current `async` context.
///
/// This macro is only usable inside of `async` functions, closures, and blocks.
/// It is also gated behind the `async-await` feature of this library, which is
/// activated by default.
///
/// If you need the result of polling a [`Stream`](crate::stream::Stream),
/// you can use this macro with the [`next`](crate::stream::StreamExt::next) method:
/// `poll!(stream.next())`.
#[macro_export]
macro_rules! poll {
($x:expr $(,)?) => {
$crate::__private::async_await::poll($x).await
};
}
#[doc(hidden)]
pub fn poll<F: Future + Unpin>(future: F) -> PollOnce<F> {
PollOnce { future }
}
#[allow(missing_debug_implementations)]
#[doc(hidden)]
pub struct PollOnce<F: Future + Unpin> {
future: F,
}
impl<F: Future + Unpin> Future for PollOnce<F> {
type Output = Poll<F::Output>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Poll::Ready(self.future.poll_unpin(cx))
}
}

View File

@@ -0,0 +1,54 @@
use std::{
cell::Cell,
collections::hash_map::DefaultHasher,
hash::Hasher,
num::Wrapping,
sync::atomic::{AtomicUsize, Ordering},
};
// Based on [FisherYates shuffle].
//
// [FisherYates shuffle]: https://en.wikipedia.org/wiki/FisherYates_shuffle
#[doc(hidden)]
pub fn shuffle<T>(slice: &mut [T]) {
for i in (1..slice.len()).rev() {
slice.swap(i, gen_index(i + 1));
}
}
/// Return a value from `0..n`.
fn gen_index(n: usize) -> usize {
(random() % n as u64) as usize
}
/// Pseudorandom number generator based on [xorshift*].
///
/// [xorshift*]: https://en.wikipedia.org/wiki/Xorshift#xorshift*
fn random() -> u64 {
std::thread_local! {
static RNG: Cell<Wrapping<u64>> = Cell::new(Wrapping(prng_seed()));
}
fn prng_seed() -> u64 {
static COUNTER: AtomicUsize = AtomicUsize::new(0);
// Any non-zero seed will do
let mut seed = 0;
while seed == 0 {
let mut hasher = DefaultHasher::new();
hasher.write_usize(COUNTER.fetch_add(1, Ordering::Relaxed));
seed = hasher.finish();
}
seed
}
RNG.with(|rng| {
let mut x = rng.get();
debug_assert_ne!(x.0, 0);
x ^= x >> 12;
x ^= x << 25;
x ^= x >> 27;
rng.set(x);
x.0.wrapping_mul(0x2545_f491_4f6c_dd1d)
})
}

View File

@@ -0,0 +1,340 @@
//! The `select` macro.
macro_rules! document_select_macro {
// This branch is required for `futures 0.3.1`, from before select_biased was introduced
($select:item) => {
#[allow(clippy::too_long_first_doc_paragraph)]
/// Polls multiple futures and streams simultaneously, executing the branch
/// for the future that finishes first. If multiple futures are ready,
/// one will be pseudo-randomly selected at runtime. Futures directly
/// passed to `select!` must be `Unpin` and implement `FusedFuture`.
///
/// If an expression which yields a `Future` is passed to `select!`
/// (e.g. an `async fn` call) instead of a `Future` by name the `Unpin`
/// requirement is relaxed, since the macro will pin the resulting `Future`
/// on the stack. However the `Future` returned by the expression must
/// still implement `FusedFuture`.
///
/// Futures and streams which are not already fused can be fused using the
/// `.fuse()` method. Note, though, that fusing a future or stream directly
/// in the call to `select!` will not be enough to prevent it from being
/// polled after completion if the `select!` call is in a loop, so when
/// `select!`ing in a loop, users should take care to `fuse()` outside of
/// the loop.
///
/// `select!` can be used as an expression and will return the return
/// value of the selected branch. For this reason the return type of every
/// branch in a `select!` must be the same.
///
/// This macro is only usable inside of async functions, closures, and blocks.
/// It is also gated behind the `async-await` feature of this library, which is
/// activated by default.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
/// use futures::select;
/// let mut a = future::ready(4);
/// let mut b = future::pending::<()>();
///
/// let res = select! {
/// a_res = a => a_res + 1,
/// _ = b => 0,
/// };
/// assert_eq!(res, 5);
/// # });
/// ```
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
/// use futures::stream::{self, StreamExt};
/// use futures::select;
/// let mut st = stream::iter(vec![2]).fuse();
/// let mut fut = future::pending::<()>();
///
/// select! {
/// x = st.next() => assert_eq!(Some(2), x),
/// _ = fut => panic!(),
/// }
/// # });
/// ```
///
/// As described earlier, `select` can directly select on expressions
/// which return `Future`s - even if those do not implement `Unpin`:
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::FutureExt;
/// use futures::select;
///
/// // Calling the following async fn returns a Future which does not
/// // implement Unpin
/// async fn async_identity_fn(arg: usize) -> usize {
/// arg
/// }
///
/// let res = select! {
/// a_res = async_identity_fn(62).fuse() => a_res + 1,
/// b_res = async_identity_fn(13).fuse() => b_res,
/// };
/// assert!(res == 63 || res == 13);
/// # });
/// ```
///
/// If a similar async function is called outside of `select` to produce
/// a `Future`, the `Future` must be pinned in order to be able to pass
/// it to `select`. This can be achieved via `Box::pin` for pinning a
/// `Future` on the heap or the `pin!` macro for pinning a `Future`
/// on the stack.
///
/// ```
/// # futures::executor::block_on(async {
/// use core::pin::pin;
///
/// use futures::future::FutureExt;
/// use futures::select;
///
/// // Calling the following async fn returns a Future which does not
/// // implement Unpin
/// async fn async_identity_fn(arg: usize) -> usize {
/// arg
/// }
///
/// let fut_1 = async_identity_fn(1).fuse();
/// let fut_2 = async_identity_fn(2).fuse();
/// let mut fut_1 = Box::pin(fut_1); // Pins the Future on the heap
/// let mut fut_2 = pin!(fut_2); // Pins the Future on the stack
///
/// let res = select! {
/// a_res = fut_1 => a_res,
/// b_res = fut_2 => b_res,
/// };
/// assert!(res == 1 || res == 2);
/// # });
/// ```
///
/// `select` also accepts a `complete` branch and a `default` branch.
/// `complete` will run if all futures and streams have already been
/// exhausted. `default` will run if no futures or streams are
/// immediately ready. `complete` takes priority over `default` in
/// the case where all futures have completed.
/// A motivating use-case for passing `Future`s by name as well as for
/// `complete` blocks is to call `select!` in a loop, which is
/// demonstrated in the following example:
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
/// use futures::select;
/// let mut a_fut = future::ready(4);
/// let mut b_fut = future::ready(6);
/// let mut total = 0;
///
/// loop {
/// select! {
/// a = a_fut => total += a,
/// b = b_fut => total += b,
/// complete => break,
/// default => panic!(), // never runs (futures run first, then complete)
/// }
/// }
/// assert_eq!(total, 10);
/// # });
/// ```
///
/// Note that the futures that have been matched over can still be mutated
/// from inside the `select!` block's branches. This can be used to implement
/// more complex behavior such as timer resets or writing into the head of
/// a stream.
$select
};
($select:item $select_biased:item) => {
document_select_macro!($select);
#[allow(clippy::too_long_first_doc_paragraph)]
/// Polls multiple futures and streams simultaneously, executing the branch
/// for the future that finishes first. Unlike [`select!`], if multiple futures are ready,
/// one will be selected in order of declaration. Futures directly
/// passed to `select_biased!` must be `Unpin` and implement `FusedFuture`.
///
/// If an expression which yields a `Future` is passed to `select_biased!`
/// (e.g. an `async fn` call) instead of a `Future` by name the `Unpin`
/// requirement is relaxed, since the macro will pin the resulting `Future`
/// on the stack. However the `Future` returned by the expression must
/// still implement `FusedFuture`.
///
/// Futures and streams which are not already fused can be fused using the
/// `.fuse()` method. Note, though, that fusing a future or stream directly
/// in the call to `select_biased!` will not be enough to prevent it from being
/// polled after completion if the `select_biased!` call is in a loop, so when
/// `select_biased!`ing in a loop, users should take care to `fuse()` outside of
/// the loop.
///
/// `select_biased!` can be used as an expression and will return the return
/// value of the selected branch. For this reason the return type of every
/// branch in a `select_biased!` must be the same.
///
/// This macro is only usable inside of async functions, closures, and blocks.
/// It is also gated behind the `async-await` feature of this library, which is
/// activated by default.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
/// use futures::select_biased;
/// let mut a = future::ready(4);
/// let mut b = future::pending::<()>();
///
/// let res = select_biased! {
/// a_res = a => a_res + 1,
/// _ = b => 0,
/// };
/// assert_eq!(res, 5);
/// # });
/// ```
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
/// use futures::stream::{self, StreamExt};
/// use futures::select_biased;
/// let mut st = stream::iter(vec![2]).fuse();
/// let mut fut = future::pending::<()>();
///
/// select_biased! {
/// x = st.next() => assert_eq!(Some(2), x),
/// _ = fut => panic!(),
/// }
/// # });
/// ```
///
/// As described earlier, `select_biased` can directly select on expressions
/// which return `Future`s - even if those do not implement `Unpin`:
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::FutureExt;
/// use futures::select_biased;
///
/// // Calling the following async fn returns a Future which does not
/// // implement Unpin
/// async fn async_identity_fn(arg: usize) -> usize {
/// arg
/// }
///
/// let res = select_biased! {
/// a_res = async_identity_fn(62).fuse() => a_res + 1,
/// b_res = async_identity_fn(13).fuse() => b_res,
/// };
/// assert_eq!(res, 63);
/// # });
/// ```
///
/// If a similar async function is called outside of `select_biased` to produce
/// a `Future`, the `Future` must be pinned in order to be able to pass
/// it to `select_biased`. This can be achieved via `Box::pin` for pinning a
/// `Future` on the heap or the `pin!` macro for pinning a `Future`
/// on the stack.
///
/// ```
/// # futures::executor::block_on(async {
/// use core::pin::pin;
///
/// use futures::future::FutureExt;
/// use futures::select_biased;
///
/// // Calling the following async fn returns a Future which does not
/// // implement Unpin
/// async fn async_identity_fn(arg: usize) -> usize {
/// arg
/// }
///
/// let fut_1 = async_identity_fn(1).fuse();
/// let fut_2 = async_identity_fn(2).fuse();
/// let mut fut_1 = Box::pin(fut_1); // Pins the Future on the heap
/// let mut fut_2 = pin!(fut_2); // Pins the Future on the stack
///
/// let res = select_biased! {
/// a_res = fut_1 => a_res,
/// b_res = fut_2 => b_res,
/// };
/// assert!(res == 1 || res == 2);
/// # });
/// ```
///
/// `select_biased` also accepts a `complete` branch and a `default` branch.
/// `complete` will run if all futures and streams have already been
/// exhausted. `default` will run if no futures or streams are
/// immediately ready. `complete` takes priority over `default` in
/// the case where all futures have completed.
/// A motivating use-case for passing `Future`s by name as well as for
/// `complete` blocks is to call `select_biased!` in a loop, which is
/// demonstrated in the following example:
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
/// use futures::select_biased;
/// let mut a_fut = future::ready(4);
/// let mut b_fut = future::ready(6);
/// let mut total = 0;
///
/// loop {
/// select_biased! {
/// a = a_fut => total += a,
/// b = b_fut => total += b,
/// complete => break,
/// default => panic!(), // never runs (futures run first, then complete)
/// }
/// }
/// assert_eq!(total, 10);
/// # });
/// ```
///
/// Note that the futures that have been matched over can still be mutated
/// from inside the `select_biased!` block's branches. This can be used to implement
/// more complex behavior such as timer resets or writing into the head of
/// a stream.
///
/// [`select!`]: macro.select.html
$select_biased
};
}
#[cfg(feature = "std")]
#[allow(unreachable_pub)]
#[doc(hidden)]
pub use futures_macro::select_internal;
#[allow(unreachable_pub)]
#[doc(hidden)]
pub use futures_macro::select_biased_internal;
document_select_macro! {
#[cfg(feature = "std")]
#[macro_export]
macro_rules! select {
($($tokens:tt)*) => {{
use $crate::__private as __futures_crate;
$crate::select_internal! {
$( $tokens )*
}
}}
}
#[macro_export]
macro_rules! select_biased {
($($tokens:tt)*) => {{
use $crate::__private as __futures_crate;
$crate::select_biased_internal! {
$( $tokens )*
}
}}
}
}

View File

@@ -0,0 +1,39 @@
//! The `stream_select` macro.
#[allow(unreachable_pub)]
#[doc(hidden)]
pub use futures_macro::stream_select_internal;
#[allow(clippy::too_long_first_doc_paragraph)]
/// 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!(),
/// }
/// # });
/// ```
#[macro_export]
macro_rules! stream_select {
($($tokens:tt)*) => {{
use $crate::__private as __futures_crate;
$crate::stream_select_internal! {
$( $tokens )*
}
}}
}

View File

@@ -0,0 +1,455 @@
use futures_01::executor::{
spawn as spawn01, Notify as Notify01, NotifyHandle as NotifyHandle01, Spawn as Spawn01,
UnsafeNotify as UnsafeNotify01,
};
use futures_01::{Async as Async01, Future as Future01, Stream as Stream01};
#[cfg(feature = "sink")]
use futures_01::{AsyncSink as AsyncSink01, Sink as Sink01};
use futures_core::{future::Future as Future03, stream::Stream as Stream03, task as task03};
#[cfg(feature = "sink")]
use futures_sink::Sink as Sink03;
use std::boxed::Box;
use std::pin::Pin;
use std::task::Context;
#[cfg(feature = "io-compat")]
#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use io::{AsyncRead01CompatExt, AsyncWrite01CompatExt};
/// Converts a futures 0.1 Future, Stream, AsyncRead, or AsyncWrite
/// object to a futures 0.3-compatible version,
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Compat01As03<T> {
pub(crate) inner: Spawn01<T>,
}
impl<T> Unpin for Compat01As03<T> {}
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) }
}
fn in_notify<R>(&mut self, cx: &mut Context<'_>, f: impl FnOnce(&mut T) -> R) -> R {
let notify = &WakerToHandle(cx.waker());
self.inner.poll_fn_notify(notify, 0, f)
}
/// Get a reference to 0.1 Future, Stream, AsyncRead, or AsyncWrite object contained within.
pub fn get_ref(&self) -> &T {
self.inner.get_ref()
}
/// Get a mutable reference to 0.1 Future, Stream, AsyncRead or AsyncWrite object contained
/// within.
pub fn get_mut(&mut self) -> &mut T {
self.inner.get_mut()
}
/// Consume this wrapper to return the underlying 0.1 Future, Stream, AsyncRead, or
/// AsyncWrite object.
pub fn into_inner(self) -> T {
self.inner.into_inner()
}
}
/// Extension trait for futures 0.1 [`Future`](futures_01::future::Future)
pub trait Future01CompatExt: Future01 {
/// Converts a futures 0.1
/// [`Future<Item = T, Error = E>`](futures_01::future::Future)
/// into a futures 0.3
/// [`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
/// use futures_util::compat::Future01CompatExt;
///
/// let future = futures_01::future::ok::<u32, ()>(1);
/// assert_eq!(future.compat().await, Ok(1));
/// # });
/// ```
fn compat(self) -> Compat01As03<Self>
where
Self: Sized,
{
Compat01As03::new(self)
}
}
impl<Fut: Future01> Future01CompatExt for Fut {}
/// Extension trait for futures 0.1 [`Stream`](futures_01::stream::Stream)
pub trait Stream01CompatExt: Stream01 {
/// Converts a futures 0.1
/// [`Stream<Item = T, Error = E>`](futures_01::stream::Stream)
/// into a futures 0.3
/// [`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;
///
/// let stream = futures_01::stream::once::<u32, ()>(Ok(1));
/// let mut stream = stream.compat();
/// assert_eq!(stream.next().await, Some(Ok(1)));
/// assert_eq!(stream.next().await, None);
/// # });
/// ```
fn compat(self) -> Compat01As03<Self>
where
Self: Sized,
{
Compat01As03::new(self)
}
}
impl<St: Stream01> Stream01CompatExt for St {}
/// Extension trait for futures 0.1 [`Sink`](futures_01::sink::Sink)
#[cfg(feature = "sink")]
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
pub trait Sink01CompatExt: Sink01 {
/// Converts a futures 0.1
/// [`Sink<SinkItem = T, SinkError = E>`](futures_01::sink::Sink)
/// into a futures 0.3
/// [`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};
///
/// let (tx, rx) = futures_01::unsync::mpsc::channel(1);
/// let (mut tx, mut rx) = (tx.sink_compat(), rx.compat());
///
/// tx.send(1).await.unwrap();
/// drop(tx);
/// assert_eq!(rx.next().await, Some(Ok(1)));
/// assert_eq!(rx.next().await, None);
/// # });
/// ```
fn sink_compat(self) -> Compat01As03Sink<Self, Self::SinkItem>
where
Self: Sized,
{
Compat01As03Sink::new(self)
}
}
#[cfg(feature = "sink")]
impl<Si: Sink01> Sink01CompatExt for Si {}
fn poll_01_to_03<T, E>(x: Result<Async01<T>, E>) -> task03::Poll<Result<T, E>> {
match x? {
Async01::Ready(t) => task03::Poll::Ready(Ok(t)),
Async01::NotReady => task03::Poll::Pending,
}
}
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> {
poll_01_to_03(self.in_notify(cx, Future01::poll))
}
}
impl<St: Stream01> Stream03 for Compat01As03<St> {
type Item = Result<St::Item, St::Error>;
fn poll_next(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> task03::Poll<Option<Self::Item>> {
match self.in_notify(cx, Stream01::poll)? {
Async01::Ready(Some(t)) => task03::Poll::Ready(Some(Ok(t))),
Async01::Ready(None) => task03::Poll::Ready(None),
Async01::NotReady => task03::Poll::Pending,
}
}
}
/// Converts a futures 0.1 Sink object to a futures 0.3-compatible version
#[cfg(feature = "sink")]
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
#[derive(Debug)]
#[must_use = "sinks do nothing unless polled"]
pub struct Compat01As03Sink<S, SinkItem> {
pub(crate) inner: Spawn01<S>,
pub(crate) buffer: Option<SinkItem>,
pub(crate) close_started: bool,
}
#[cfg(feature = "sink")]
impl<S, SinkItem> Unpin for Compat01As03Sink<S, SinkItem> {}
#[cfg(feature = "sink")]
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 }
}
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)
}
/// Get a reference to 0.1 Sink object contained within.
pub fn get_ref(&self) -> &S {
self.inner.get_ref()
}
/// Get a mutable reference to 0.1 Sink contained within.
pub fn get_mut(&mut self) -> &mut S {
self.inner.get_mut()
}
/// Consume this wrapper to return the underlying 0.1 Sink.
pub fn into_inner(self) -> S {
self.inner.into_inner()
}
}
#[cfg(feature = "sink")]
impl<S, SinkItem> Stream03 for Compat01As03Sink<S, SinkItem>
where
S: Stream01,
{
type Item = Result<S::Item, S::Error>;
fn poll_next(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> task03::Poll<Option<Self::Item>> {
match self.in_notify(cx, Stream01::poll)? {
Async01::Ready(Some(t)) => task03::Poll::Ready(Some(Ok(t))),
Async01::Ready(None) => task03::Poll::Ready(None),
Async01::NotReady => task03::Poll::Pending,
}
}
}
#[cfg(feature = "sink")]
impl<S, SinkItem> Sink03<SinkItem> for Compat01As03Sink<S, SinkItem>
where
S: Sink01<SinkItem = SinkItem>,
{
type Error = S::SinkError;
fn start_send(mut self: Pin<&mut Self>, item: SinkItem) -> Result<(), Self::Error> {
debug_assert!(self.buffer.is_none());
self.buffer = Some(item);
Ok(())
}
fn poll_ready(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> task03::Poll<Result<(), Self::Error>> {
match self.buffer.take() {
Some(item) => match self.in_notify(cx, |f| f.start_send(item))? {
AsyncSink01::Ready => task03::Poll::Ready(Ok(())),
AsyncSink01::NotReady(i) => {
self.buffer = Some(i);
task03::Poll::Pending
}
},
None => task03::Poll::Ready(Ok(())),
}
}
fn poll_flush(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> task03::Poll<Result<(), Self::Error>> {
let item = self.buffer.take();
match self.in_notify(cx, |f| match item {
Some(i) => match f.start_send(i)? {
AsyncSink01::Ready => f.poll_complete().map(|i| (i, None)),
AsyncSink01::NotReady(t) => Ok((Async01::NotReady, Some(t))),
},
None => f.poll_complete().map(|i| (i, None)),
})? {
(Async01::Ready(_), _) => task03::Poll::Ready(Ok(())),
(Async01::NotReady, item) => {
self.buffer = item;
task03::Poll::Pending
}
}
}
fn poll_close(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> task03::Poll<Result<(), Self::Error>> {
let item = self.buffer.take();
let close_started = self.close_started;
let result = self.in_notify(cx, |f| {
if !close_started {
if let Some(item) = item {
if let AsyncSink01::NotReady(item) = f.start_send(item)? {
return Ok((Async01::NotReady, Some(item), false));
}
}
if let Async01::NotReady = f.poll_complete()? {
return Ok((Async01::NotReady, None, false));
}
}
Ok((<S as Sink01>::close(f)?, None, true))
});
match result? {
(Async01::Ready(_), _, _) => task03::Poll::Ready(Ok(())),
(Async01::NotReady, item, close_started) => {
self.buffer = item;
self.close_started = close_started;
task03::Poll::Pending
}
}
}
}
struct NotifyWaker(task03::Waker);
#[allow(missing_debug_implementations)] // false positive: this is private type
#[derive(Clone)]
struct WakerToHandle<'a>(&'a task03::Waker);
impl From<WakerToHandle<'_>> for NotifyHandle01 {
fn from(handle: WakerToHandle<'_>) -> Self {
let ptr = Box::new(NotifyWaker(handle.0.clone()));
unsafe { Self::new(Box::into_raw(ptr)) }
}
}
impl Notify01 for NotifyWaker {
fn notify(&self, _: usize) {
self.0.wake_by_ref();
}
}
unsafe impl UnsafeNotify01 for NotifyWaker {
unsafe fn clone_raw(&self) -> NotifyHandle01 {
WakerToHandle(&self.0).into()
}
unsafe fn drop_raw(&self) {
let ptr: *const dyn UnsafeNotify01 = self;
drop(unsafe { Box::from_raw(ptr as *mut dyn UnsafeNotify01) });
}
}
#[cfg(feature = "io-compat")]
#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
mod io {
use super::*;
use futures_io::{AsyncRead as AsyncRead03, AsyncWrite as AsyncWrite03};
use std::io::Error;
use tokio_io::{AsyncRead as AsyncRead01, AsyncWrite as AsyncWrite01};
/// Extension trait for tokio-io [`AsyncRead`](tokio_io::AsyncRead)
#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
pub trait AsyncRead01CompatExt: AsyncRead01 {
/// Converts a tokio-io [`AsyncRead`](tokio_io::AsyncRead) into a futures-io 0.3
/// [`AsyncRead`](futures_io::AsyncRead).
///
/// ```
/// # if cfg!(miri) { return; } // https://github.com/rust-lang/futures-rs/issues/2514
/// # futures::executor::block_on(async {
/// use futures::io::AsyncReadExt;
/// use futures_util::compat::AsyncRead01CompatExt;
///
/// let input = b"Hello World!";
/// let reader /* : impl tokio_io::AsyncRead */ = std::io::Cursor::new(input);
/// let mut reader /* : impl futures::io::AsyncRead + Unpin */ = reader.compat();
///
/// let mut output = Vec::with_capacity(12);
/// reader.read_to_end(&mut output).await.unwrap();
/// assert_eq!(output, input);
/// # });
/// ```
fn compat(self) -> Compat01As03<Self>
where
Self: Sized,
{
Compat01As03::new(self)
}
}
impl<R: AsyncRead01> AsyncRead01CompatExt for R {}
/// Extension trait for tokio-io [`AsyncWrite`](tokio_io::AsyncWrite)
#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
pub trait AsyncWrite01CompatExt: AsyncWrite01 {
/// Converts a tokio-io [`AsyncWrite`](tokio_io::AsyncWrite) into a futures-io 0.3
/// [`AsyncWrite`](futures_io::AsyncWrite).
///
/// ```
/// # if cfg!(miri) { return; } // https://github.com/rust-lang/futures-rs/issues/2514
/// # futures::executor::block_on(async {
/// use futures::io::AsyncWriteExt;
/// use futures_util::compat::AsyncWrite01CompatExt;
///
/// let input = b"Hello World!";
/// let mut cursor = std::io::Cursor::new(Vec::with_capacity(12));
///
/// let mut writer = (&mut cursor).compat();
/// writer.write_all(input).await.unwrap();
///
/// assert_eq!(cursor.into_inner(), input);
/// # });
/// ```
fn compat(self) -> Compat01As03<Self>
where
Self: Sized,
{
Compat01As03::new(self)
}
}
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>> {
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>> {
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>> {
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>> {
poll_01_to_03(self.in_notify(cx, AsyncWrite01::shutdown))
}
}
}

View File

@@ -0,0 +1,268 @@
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,
};
#[cfg(feature = "sink")]
use futures_01::{AsyncSink as AsyncSink01, Sink as Sink01, StartSend as StartSend01};
use futures_core::{
future::TryFuture as TryFuture03,
stream::TryStream as TryStream03,
task::{RawWaker, RawWakerVTable},
};
#[cfg(feature = "sink")]
use futures_sink::Sink as Sink03;
#[cfg(feature = "sink")]
use std::marker::PhantomData;
use std::{mem, pin::Pin, sync::Arc, task::Context};
#[allow(clippy::too_long_first_doc_paragraph)] // clippy bug, see https://github.com/rust-lang/rust-clippy/issues/13315
/// Converts a futures 0.3 [`TryFuture`](futures_core::future::TryFuture) or
/// [`TryStream`](futures_core::stream::TryStream) into a futures 0.1
/// [`Future`](futures_01::future::Future) or
/// [`Stream`](futures_01::stream::Stream).
#[derive(Debug, Clone, Copy)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Compat<T> {
pub(crate) inner: T,
}
/// Converts a futures 0.3 [`Sink`](futures_sink::Sink) into a futures 0.1
/// [`Sink`](futures_01::sink::Sink).
#[cfg(feature = "sink")]
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
#[derive(Debug)]
#[must_use = "sinks do nothing unless polled"]
pub struct CompatSink<T, Item> {
inner: T,
_phantom: PhantomData<fn(Item)>,
}
impl<T> Compat<T> {
/// Creates a new [`Compat`].
///
/// For types which implement appropriate futures `0.3`
/// traits, the result will be a type which implements
/// the corresponding futures 0.1 type.
pub fn new(inner: T) -> Self {
Self { inner }
}
/// Get a reference to 0.3 Future, Stream, AsyncRead, or AsyncWrite object
/// contained within.
pub fn get_ref(&self) -> &T {
&self.inner
}
/// Get a mutable reference to 0.3 Future, Stream, AsyncRead, or AsyncWrite object
/// contained within.
pub fn get_mut(&mut self) -> &mut T {
&mut self.inner
}
/// Returns the inner item.
pub fn into_inner(self) -> T {
self.inner
}
}
#[cfg(feature = "sink")]
impl<T, Item> CompatSink<T, Item> {
/// Creates a new [`CompatSink`].
pub fn new(inner: T) -> Self {
Self { inner, _phantom: PhantomData }
}
/// Get a reference to 0.3 Sink contained within.
pub fn get_ref(&self) -> &T {
&self.inner
}
/// Get a mutable reference to 0.3 Sink contained within.
pub fn get_mut(&mut self) -> &mut T {
&mut self.inner
}
/// Returns the inner item.
pub fn into_inner(self) -> T {
self.inner
}
}
fn poll_03_to_01<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),
}
}
impl<Fut> Future01 for Compat<Fut>
where
Fut: TryFuture03 + Unpin,
{
type Item = Fut::Ok;
type Error = Fut::Error;
fn poll(&mut self) -> Poll01<Self::Item, Self::Error> {
with_context(self, |inner, cx| poll_03_to_01(inner.try_poll(cx)))
}
}
impl<St> Stream01 for Compat<St>
where
St: TryStream03 + Unpin,
{
type Item = St::Ok;
type Error = St::Error;
fn poll(&mut self) -> Poll01<Option<Self::Item>, Self::Error> {
with_context(self, |inner, cx| match inner.try_poll_next(cx)? {
task03::Poll::Ready(None) => Ok(Async01::Ready(None)),
task03::Poll::Ready(Some(t)) => Ok(Async01::Ready(Some(t))),
task03::Poll::Pending => Ok(Async01::NotReady),
})
}
}
#[cfg(feature = "sink")]
impl<T, Item> Sink01 for CompatSink<T, Item>
where
T: Sink03<Item> + Unpin,
{
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 poll_complete(&mut self) -> Poll01<(), Self::SinkError> {
with_sink_context(self, |inner, cx| poll_03_to_01(inner.poll_flush(cx)))
}
fn close(&mut self) -> Poll01<(), Self::SinkError> {
with_sink_context(self, |inner, cx| poll_03_to_01(inner.poll_close(cx)))
}
}
#[derive(Clone)]
struct Current(task01::Task);
impl Current {
fn new() -> Self {
Self(task01::current())
}
fn as_waker(&self) -> WakerRef<'_> {
unsafe fn ptr_to_current<'a>(ptr: *const ()) -> &'a Current {
unsafe { &*(ptr as *const Current) }
}
fn current_to_ptr(current: &Current) -> *const () {
current as *const Current as *const ()
}
unsafe fn clone(ptr: *const ()) -> RawWaker {
// Lazily create the `Arc` only when the waker is actually cloned.
// FIXME: remove `transmute` when a `Waker` -> `RawWaker` conversion
// function is landed in `core`.
unsafe {
mem::transmute::<task03::Waker, RawWaker>(task03::waker(Arc::new(
ptr_to_current(ptr).clone(),
)))
}
}
unsafe fn drop(_: *const ()) {}
unsafe fn wake(ptr: *const ()) {
unsafe { ptr_to_current(ptr).0.notify() }
}
let ptr = current_to_ptr(self);
let vtable = &RawWakerVTable::new(clone, wake, wake, drop);
WakerRef::new_unowned(std::mem::ManuallyDrop::new(unsafe {
task03::Waker::from_raw(RawWaker::new(ptr, vtable))
}))
}
}
impl ArcWake03 for Current {
fn wake_by_ref(arc_self: &Arc<Self>) {
arc_self.0.notify();
}
}
fn with_context<T, R, F>(compat: &mut Compat<T>, f: F) -> R
where
T: Unpin,
F: FnOnce(Pin<&mut T>, &mut Context<'_>) -> R,
{
let current = Current::new();
let waker = current.as_waker();
let mut cx = Context::from_waker(&waker);
f(Pin::new(&mut compat.inner), &mut cx)
}
#[cfg(feature = "sink")]
fn with_sink_context<T, Item, R, F>(compat: &mut CompatSink<T, Item>, f: F) -> R
where
T: Unpin,
F: FnOnce(Pin<&mut T>, &mut Context<'_>) -> R,
{
let current = Current::new();
let waker = current.as_waker();
let mut cx = Context::from_waker(&waker);
f(Pin::new(&mut compat.inner), &mut cx)
}
#[cfg(feature = "io-compat")]
#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
mod io {
use super::*;
use futures_io::{AsyncRead as AsyncRead03, AsyncWrite as AsyncWrite03};
use tokio_io::{AsyncRead as AsyncRead01, AsyncWrite as AsyncWrite01};
fn poll_03_to_io<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()),
task03::Poll::Ready(Err(e)) => Err(e),
}
}
impl<R: AsyncRead03 + Unpin> std::io::Read for Compat<R> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
let current = Current::new();
let waker = current.as_waker();
let mut cx = Context::from_waker(&waker);
poll_03_to_io(Pin::new(&mut self.inner).poll_read(&mut cx, buf))
}
}
impl<R: AsyncRead03 + Unpin> AsyncRead01 for Compat<R> {}
impl<W: AsyncWrite03 + Unpin> std::io::Write for Compat<W> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
let current = Current::new();
let waker = current.as_waker();
let mut cx = Context::from_waker(&waker);
poll_03_to_io(Pin::new(&mut self.inner).poll_write(&mut cx, buf))
}
fn flush(&mut self) -> std::io::Result<()> {
let current = Current::new();
let waker = current.as_waker();
let mut cx = Context::from_waker(&waker);
poll_03_to_io(Pin::new(&mut self.inner).poll_flush(&mut cx))
}
}
impl<W: AsyncWrite03 + Unpin> AsyncWrite01 for Compat<W> {
fn shutdown(&mut self) -> std::io::Result<Async01<()>> {
let current = Current::new();
let waker = current.as_waker();
let mut cx = Context::from_waker(&waker);
poll_03_to_01(Pin::new(&mut self.inner).poll_close(&mut cx))
}
}
}

View File

@@ -0,0 +1,86 @@
use super::{Compat, Future01CompatExt};
use crate::{
future::{FutureExt, TryFutureExt, UnitError},
task::SpawnExt,
};
use futures_01::future::{ExecuteError as ExecuteError01, Executor as Executor01};
use futures_01::Future as Future01;
use futures_task::{FutureObj, Spawn as Spawn03, SpawnError as SpawnError03};
/// A future that can run on a futures 0.1
/// [`Executor`](futures_01::future::Executor).
pub type Executor01Future = Compat<UnitError<FutureObj<'static, ()>>>;
/// Extension trait for futures 0.1 [`Executor`](futures_01::future::Executor).
pub trait Executor01CompatExt: Executor01<Executor01Future> + Clone + Send + 'static {
/// Converts a futures 0.1 [`Executor`](futures_01::future::Executor) into a
/// futures 0.3 [`Spawn`](futures_task::Spawn).
///
/// ```
/// # if cfg!(miri) { return; } // Miri does not support epoll
/// use futures::task::SpawnExt;
/// use futures::future::{FutureExt, TryFutureExt};
/// use futures_util::compat::Executor01CompatExt;
/// use tokio::executor::DefaultExecutor;
///
/// # let (tx, rx) = futures::channel::oneshot::channel();
///
/// let spawner = DefaultExecutor::current().compat();
/// let future03 = async move {
/// println!("Running on the pool");
/// spawner.spawn(async {
/// println!("Spawned!");
/// # tx.send(42).unwrap();
/// }).unwrap();
/// };
///
/// let future01 = future03.unit_error().boxed().compat();
///
/// tokio::run(future01);
/// # futures::executor::block_on(rx).unwrap();
/// ```
fn compat(self) -> Executor01As03<Self>
where
Self: Sized;
}
impl<Ex> Executor01CompatExt for Ex
where
Ex: Executor01<Executor01Future> + Clone + Send + 'static,
{
fn compat(self) -> Executor01As03<Self> {
Executor01As03 { executor01: self }
}
}
/// Converts a futures 0.1 [`Executor`](futures_01::future::Executor) into a
/// futures 0.3 [`Spawn`](futures_task::Spawn).
#[derive(Debug, Clone)]
pub struct Executor01As03<Ex> {
executor01: Ex,
}
impl<Ex> Spawn03 for Executor01As03<Ex>
where
Ex: Executor01<Executor01Future> + Clone + Send + 'static,
{
fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError03> {
let future = future.unit_error().compat();
self.executor01.execute(future).map_err(|_| SpawnError03::shutdown())
}
}
#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
impl<Sp, Fut> Executor01<Fut> for Compat<Sp>
where
for<'a> &'a Sp: Spawn03,
Fut: Future01<Item = (), Error = ()> + Send + 'static,
{
fn execute(&self, future: Fut) -> Result<(), ExecuteError01<Fut>> {
(&self.inner)
.spawn(future.compat().map(|_| ()))
.expect("unable to spawn future from Compat executor");
Ok(())
}
}

22
vendor/futures-util/src/compat/mod.rs vendored Normal file
View File

@@ -0,0 +1,22 @@
//! Interop between `futures` 0.1 and 0.3.
//!
//! This module is only available when the `compat` feature of this
//! library is activated.
mod executor;
pub use self::executor::{Executor01As03, Executor01CompatExt, Executor01Future};
mod compat01as03;
#[cfg(feature = "io-compat")]
#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
pub use self::compat01as03::{AsyncRead01CompatExt, AsyncWrite01CompatExt};
pub use self::compat01as03::{Compat01As03, Future01CompatExt, Stream01CompatExt};
#[cfg(feature = "sink")]
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
pub use self::compat01as03::{Compat01As03Sink, Sink01CompatExt};
mod compat03as01;
pub use self::compat03as01::Compat;
#[cfg(feature = "sink")]
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
pub use self::compat03as01::CompatSink;

372
vendor/futures-util/src/fns.rs vendored Normal file
View File

@@ -0,0 +1,372 @@
use core::fmt::{self, Debug};
use core::marker::PhantomData;
pub trait FnOnce1<A> {
type Output;
fn call_once(self, arg: A) -> Self::Output;
}
impl<T, A, R> FnOnce1<A> for T
where
T: FnOnce(A) -> R,
{
type Output = R;
fn call_once(self, arg: A) -> R {
self(arg)
}
}
pub trait FnMut1<A>: FnOnce1<A> {
fn call_mut(&mut self, arg: A) -> Self::Output;
}
impl<T, A, R> FnMut1<A> for T
where
T: FnMut(A) -> R,
{
fn call_mut(&mut self, arg: A) -> R {
self(arg)
}
}
// Not used, but present for completeness
#[allow(dead_code, unreachable_pub)]
pub trait Fn1<A>: FnMut1<A> {
fn call(&self, arg: A) -> Self::Output;
}
impl<T, A, R> Fn1<A> for T
where
T: Fn(A) -> R,
{
fn call(&self, arg: A) -> R {
self(arg)
}
}
macro_rules! trivial_fn_impls {
($name:ident <$($arg:ident),*> $t:ty = $debug:literal) => {
impl<$($arg),*> Copy for $t {}
impl<$($arg),*> Clone for $t {
fn clone(&self) -> Self { *self }
}
impl<$($arg),*> Debug for $t {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str($debug)
}
}
impl<$($arg,)* A> FnMut1<A> for $t where Self: FnOnce1<A> {
fn call_mut(&mut self, arg: A) -> Self::Output {
self.call_once(arg)
}
}
impl<$($arg,)* A> Fn1<A> for $t where Self: FnOnce1<A> {
fn call(&self, arg: A) -> Self::Output {
self.call_once(arg)
}
}
pub(crate) fn $name<$($arg),*>() -> $t {
Default::default()
}
}
}
pub struct OkFn<E>(PhantomData<fn(E)>);
impl<E> Default for OkFn<E> {
fn default() -> Self {
Self(PhantomData)
}
}
impl<A, E> FnOnce1<A> for OkFn<E> {
type Output = Result<A, E>;
fn call_once(self, arg: A) -> Self::Output {
Ok(arg)
}
}
trivial_fn_impls!(ok_fn <T> OkFn<T> = "Ok");
#[derive(Debug, Copy, Clone, Default)]
pub struct ChainFn<F, G>(F, G);
impl<F, G, A> FnOnce1<A> for ChainFn<F, G>
where
F: FnOnce1<A>,
G: FnOnce1<F::Output>,
{
type Output = G::Output;
fn call_once(self, arg: A) -> Self::Output {
self.1.call_once(self.0.call_once(arg))
}
}
impl<F, G, A> FnMut1<A> for ChainFn<F, G>
where
F: FnMut1<A>,
G: FnMut1<F::Output>,
{
fn call_mut(&mut self, arg: A) -> Self::Output {
self.1.call_mut(self.0.call_mut(arg))
}
}
impl<F, G, A> Fn1<A> for ChainFn<F, G>
where
F: Fn1<A>,
G: Fn1<F::Output>,
{
fn call(&self, arg: A) -> Self::Output {
self.1.call(self.0.call(arg))
}
}
pub(crate) fn chain_fn<F, G>(f: F, g: G) -> ChainFn<F, G> {
ChainFn(f, g)
}
#[derive(Default)]
pub struct MergeResultFn;
impl<T> FnOnce1<Result<T, T>> for MergeResultFn {
type Output = T;
fn call_once(self, arg: Result<T, T>) -> Self::Output {
match arg {
Ok(x) => x,
Err(x) => x,
}
}
}
trivial_fn_impls!(merge_result_fn <> MergeResultFn = "merge_result");
#[derive(Debug, Copy, Clone, Default)]
pub struct InspectFn<F>(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 = ()>,
{
type Output = A;
fn call_once(self, arg: A) -> Self::Output {
self.0.call_once(&arg);
arg
}
}
#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
impl<F, A> FnMut1<A> for InspectFn<F>
where
F: for<'a> FnMut1<&'a A, Output = ()>,
{
fn call_mut(&mut self, arg: A) -> Self::Output {
self.0.call_mut(&arg);
arg
}
}
#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
impl<F, A> Fn1<A> for InspectFn<F>
where
F: for<'a> Fn1<&'a A, Output = ()>,
{
fn call(&self, arg: A) -> Self::Output {
self.0.call(&arg);
arg
}
}
pub(crate) fn inspect_fn<F>(f: F) -> InspectFn<F> {
InspectFn(f)
}
#[derive(Debug, Copy, Clone, Default)]
pub struct MapOkFn<F>(F);
impl<F, T, E> FnOnce1<Result<T, E>> for MapOkFn<F>
where
F: FnOnce1<T>,
{
type Output = Result<F::Output, E>;
fn call_once(self, arg: Result<T, E>) -> Self::Output {
arg.map(|x| self.0.call_once(x))
}
}
impl<F, T, E> FnMut1<Result<T, E>> for MapOkFn<F>
where
F: FnMut1<T>,
{
fn call_mut(&mut self, arg: Result<T, E>) -> Self::Output {
arg.map(|x| self.0.call_mut(x))
}
}
impl<F, T, E> Fn1<Result<T, E>> for MapOkFn<F>
where
F: Fn1<T>,
{
fn call(&self, arg: Result<T, E>) -> Self::Output {
arg.map(|x| self.0.call(x))
}
}
pub(crate) fn map_ok_fn<F>(f: F) -> MapOkFn<F> {
MapOkFn(f)
}
#[derive(Debug, Copy, Clone, Default)]
pub struct MapErrFn<F>(F);
impl<F, T, E> FnOnce1<Result<T, E>> for MapErrFn<F>
where
F: FnOnce1<E>,
{
type Output = Result<T, F::Output>;
fn call_once(self, arg: Result<T, E>) -> Self::Output {
arg.map_err(|x| self.0.call_once(x))
}
}
impl<F, T, E> FnMut1<Result<T, E>> for MapErrFn<F>
where
F: FnMut1<E>,
{
fn call_mut(&mut self, arg: Result<T, E>) -> Self::Output {
arg.map_err(|x| self.0.call_mut(x))
}
}
impl<F, T, E> Fn1<Result<T, E>> for MapErrFn<F>
where
F: Fn1<E>,
{
fn call(&self, arg: Result<T, E>) -> Self::Output {
arg.map_err(|x| self.0.call(x))
}
}
pub(crate) fn map_err_fn<F>(f: F) -> MapErrFn<F> {
MapErrFn(f)
}
#[derive(Debug, Copy, Clone)]
pub struct InspectOkFn<F>(F);
impl<'a, F, T, E> FnOnce1<&'a Result<T, E>> for InspectOkFn<F>
where
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)
}
}
}
impl<'a, F, T, E> FnMut1<&'a Result<T, E>> for InspectOkFn<F>
where
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)
}
}
}
impl<'a, F, T, E> Fn1<&'a Result<T, E>> for InspectOkFn<F>
where
F: Fn1<&'a T, Output = ()>,
{
fn call(&self, arg: &'a Result<T, E>) -> Self::Output {
if let Ok(x) = arg {
self.0.call(x)
}
}
}
pub(crate) fn inspect_ok_fn<F>(f: F) -> InspectOkFn<F> {
InspectOkFn(f)
}
#[derive(Debug, Copy, Clone)]
pub struct InspectErrFn<F>(F);
impl<'a, F, T, E> FnOnce1<&'a Result<T, E>> for InspectErrFn<F>
where
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)
}
}
}
impl<'a, F, T, E> FnMut1<&'a Result<T, E>> for InspectErrFn<F>
where
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)
}
}
}
impl<'a, F, T, E> Fn1<&'a Result<T, E>> for InspectErrFn<F>
where
F: Fn1<&'a E, Output = ()>,
{
fn call(&self, arg: &'a Result<T, E>) -> Self::Output {
if let Err(x) = arg {
self.0.call(x)
}
}
}
pub(crate) fn inspect_err_fn<F>(f: F) -> InspectErrFn<F> {
InspectErrFn(f)
}
pub(crate) type MapOkOrElseFn<F, G> = ChainFn<MapOkFn<F>, ChainFn<MapErrFn<G>, MergeResultFn>>;
pub(crate) fn map_ok_or_else_fn<F, G>(f: F, g: G) -> MapOkOrElseFn<F, G> {
chain_fn(map_ok_fn(f), chain_fn(map_err_fn(g), merge_result_fn()))
}
#[derive(Debug, Copy, Clone, Default)]
pub struct UnwrapOrElseFn<F>(F);
impl<F, T, E> FnOnce1<Result<T, E>> for UnwrapOrElseFn<F>
where
F: FnOnce1<E, Output = T>,
{
type Output = T;
fn call_once(self, arg: Result<T, E>) -> Self::Output {
arg.unwrap_or_else(|x| self.0.call_once(x))
}
}
impl<F, T, E> FnMut1<Result<T, E>> for UnwrapOrElseFn<F>
where
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))
}
}
impl<F, T, E> Fn1<Result<T, E>> for UnwrapOrElseFn<F>
where
F: Fn1<E, Output = T>,
{
fn call(&self, arg: Result<T, E>) -> Self::Output {
arg.unwrap_or_else(|x| self.0.call(x))
}
}
pub(crate) fn unwrap_or_else_fn<F>(f: F) -> UnwrapOrElseFn<F> {
UnwrapOrElseFn(f)
}
pub struct IntoFn<T>(PhantomData<fn() -> T>);
impl<T> Default for IntoFn<T> {
fn default() -> Self {
Self(PhantomData)
}
}
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()
}
}
trivial_fn_impls!(into_fn <T> IntoFn<T> = "Into::into");

View File

@@ -0,0 +1,19 @@
use super::assert_future;
use crate::future::{AbortHandle, Abortable, Aborted};
use futures_core::future::Future;
/// Creates a new `Abortable` future and an `AbortHandle` which can be used to stop it.
///
/// This function is a convenient (but less flexible) alternative to calling
/// `AbortHandle::new` and `Abortable::new` manually.
///
/// This function is only available when the `std` or `alloc` feature of this
/// library is activated, and it is activated by default.
pub fn abortable<Fut>(future: Fut) -> (Abortable<Fut>, AbortHandle)
where
Fut: Future,
{
let (handle, reg) = AbortHandle::new_pair();
let abortable = assert_future::<Result<Fut::Output, Aborted>, _>(Abortable::new(future, reg));
(abortable, handle)
}

View File

@@ -0,0 +1,62 @@
use super::assert_future;
use core::pin::Pin;
use futures_core::future::{FusedFuture, Future};
use futures_core::task::{Context, Poll};
/// Future for the [`always_ready`](always_ready()) function.
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct AlwaysReady<T, F: Fn() -> T>(F);
impl<T, F: Fn() -> T> core::fmt::Debug for AlwaysReady<T, F> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_tuple("AlwaysReady").finish()
}
}
impl<T, F: Fn() -> T + Clone> Clone for AlwaysReady<T, F> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<T, F: Fn() -> T + Copy> Copy for AlwaysReady<T, F> {}
impl<T, F: Fn() -> T> Unpin for AlwaysReady<T, F> {}
impl<T, F: Fn() -> T> FusedFuture for AlwaysReady<T, F> {
fn is_terminated(&self) -> bool {
false
}
}
impl<T, F: Fn() -> T> Future for AlwaysReady<T, F> {
type Output = T;
#[inline]
fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<T> {
Poll::Ready(self.0())
}
}
/// Creates a future that is always immediately ready with a value.
///
/// This is particularly useful in avoiding a heap allocation when an API needs `Box<dyn Future<Output = T>>`,
/// as [`AlwaysReady`] does not have to store a boolean for `is_finished`.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use std::mem::size_of_val;
///
/// use futures::future;
///
/// let a = future::always_ready(|| 1);
/// assert_eq!(size_of_val(&a), 0);
/// assert_eq!(a.await, 1);
/// assert_eq!(a.await, 1);
/// # });
/// ```
pub fn always_ready<T, F: Fn() -> T>(prod: F) -> AlwaysReady<T, F> {
assert_future::<T, _>(AlwaysReady(prod))
}

314
vendor/futures-util/src/future/either.rs vendored Normal file
View File

@@ -0,0 +1,314 @@
use core::pin::Pin;
use core::task::{Context, Poll};
use futures_core::future::{FusedFuture, Future};
use futures_core::stream::{FusedStream, Stream};
#[cfg(feature = "sink")]
use futures_sink::Sink;
/// Combines two different futures, streams, or sinks having the same associated types into a single type.
///
/// This is useful when conditionally choosing between two distinct future types:
///
/// ```rust
/// use futures::future::Either;
///
/// # futures::executor::block_on(async {
/// let cond = true;
///
/// let fut = if cond {
/// Either::Left(async move { 12 })
/// } else {
/// Either::Right(async move { 44 })
/// };
///
/// assert_eq!(fut.await, 12);
/// # })
/// ```
#[derive(Debug, Clone)]
pub enum Either<A, B> {
/// First branch of the type
Left(/* #[pin] */ A),
/// Second branch of the type
Right(/* #[pin] */ B),
}
impl<A, B> Either<A, B> {
/// Convert `Pin<&Either<A, B>>` to `Either<Pin<&A>, Pin<&B>>`,
/// pinned projections of the inner variants.
pub fn as_pin_ref(self: Pin<&Self>) -> Either<Pin<&A>, Pin<&B>> {
// SAFETY: We can use `new_unchecked` because the `inner` parts are
// guaranteed to be pinned, as they come from `self` which is pinned.
unsafe {
match self.get_ref() {
Self::Left(inner) => Either::Left(Pin::new_unchecked(inner)),
Self::Right(inner) => Either::Right(Pin::new_unchecked(inner)),
}
}
}
/// Convert `Pin<&mut Either<A, B>>` to `Either<Pin<&mut A>, Pin<&mut B>>`,
/// pinned projections of the inner variants.
pub fn as_pin_mut(self: Pin<&mut Self>) -> Either<Pin<&mut A>, Pin<&mut B>> {
// SAFETY: `get_unchecked_mut` is fine because we don't move anything.
// We can use `new_unchecked` because the `inner` parts are guaranteed
// to be pinned, as they come from `self` which is pinned, and we never
// offer an unpinned `&mut A` or `&mut B` through `Pin<&mut Self>`. We
// also don't have an implementation of `Drop`, nor manual `Unpin`.
unsafe {
match self.get_unchecked_mut() {
Self::Left(inner) => Either::Left(Pin::new_unchecked(inner)),
Self::Right(inner) => Either::Right(Pin::new_unchecked(inner)),
}
}
}
}
impl<A, B, T> Either<(T, A), (T, B)> {
/// Factor out a homogeneous type from an either of pairs.
///
/// Here, the homogeneous type is the first element of the pairs.
pub fn factor_first(self) -> (T, Either<A, B>) {
match self {
Self::Left((x, a)) => (x, Either::Left(a)),
Self::Right((x, b)) => (x, Either::Right(b)),
}
}
}
impl<A, B, T> Either<(A, T), (B, T)> {
/// Factor out a homogeneous type from an either of pairs.
///
/// Here, the homogeneous type is the second element of the pairs.
pub fn factor_second(self) -> (Either<A, B>, T) {
match self {
Self::Left((a, x)) => (Either::Left(a), x),
Self::Right((b, x)) => (Either::Right(b), x),
}
}
}
impl<T> Either<T, T> {
/// Extract the value of an either over two equivalent types.
pub fn into_inner(self) -> T {
match self {
Self::Left(x) | Self::Right(x) => x,
}
}
}
impl<A, B> Future for Either<A, B>
where
A: Future,
B: Future<Output = A::Output>,
{
type Output = A::Output;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match self.as_pin_mut() {
Either::Left(x) => x.poll(cx),
Either::Right(x) => x.poll(cx),
}
}
}
impl<A, B> FusedFuture for Either<A, B>
where
A: FusedFuture,
B: FusedFuture<Output = A::Output>,
{
fn is_terminated(&self) -> bool {
match self {
Self::Left(x) => x.is_terminated(),
Self::Right(x) => x.is_terminated(),
}
}
}
impl<A, B> Stream for Either<A, B>
where
A: Stream,
B: Stream<Item = A::Item>,
{
type Item = A::Item;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
match self.as_pin_mut() {
Either::Left(x) => x.poll_next(cx),
Either::Right(x) => x.poll_next(cx),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
match self {
Self::Left(x) => x.size_hint(),
Self::Right(x) => x.size_hint(),
}
}
}
impl<A, B> FusedStream for Either<A, B>
where
A: FusedStream,
B: FusedStream<Item = A::Item>,
{
fn is_terminated(&self) -> bool {
match self {
Self::Left(x) => x.is_terminated(),
Self::Right(x) => x.is_terminated(),
}
}
}
#[cfg(feature = "sink")]
impl<A, B, Item> Sink<Item> for Either<A, B>
where
A: Sink<Item>,
B: Sink<Item, Error = A::Error>,
{
type Error = A::Error;
fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
match self.as_pin_mut() {
Either::Left(x) => x.poll_ready(cx),
Either::Right(x) => x.poll_ready(cx),
}
}
fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
match self.as_pin_mut() {
Either::Left(x) => x.start_send(item),
Either::Right(x) => x.start_send(item),
}
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
match self.as_pin_mut() {
Either::Left(x) => x.poll_flush(cx),
Either::Right(x) => x.poll_flush(cx),
}
}
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
match self.as_pin_mut() {
Either::Left(x) => x.poll_close(cx),
Either::Right(x) => x.poll_close(cx),
}
}
}
#[cfg(feature = "io")]
#[cfg(feature = "std")]
mod if_std {
use super::*;
use futures_io::{
AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, Result, SeekFrom,
};
impl<A, B> AsyncRead for Either<A, B>
where
A: AsyncRead,
B: AsyncRead,
{
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<Result<usize>> {
match self.as_pin_mut() {
Either::Left(x) => x.poll_read(cx, buf),
Either::Right(x) => x.poll_read(cx, buf),
}
}
fn poll_read_vectored(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &mut [IoSliceMut<'_>],
) -> Poll<Result<usize>> {
match self.as_pin_mut() {
Either::Left(x) => x.poll_read_vectored(cx, bufs),
Either::Right(x) => x.poll_read_vectored(cx, bufs),
}
}
}
impl<A, B> AsyncWrite for Either<A, B>
where
A: AsyncWrite,
B: AsyncWrite,
{
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize>> {
match self.as_pin_mut() {
Either::Left(x) => x.poll_write(cx, buf),
Either::Right(x) => x.poll_write(cx, buf),
}
}
fn poll_write_vectored(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &[IoSlice<'_>],
) -> Poll<Result<usize>> {
match self.as_pin_mut() {
Either::Left(x) => x.poll_write_vectored(cx, bufs),
Either::Right(x) => x.poll_write_vectored(cx, bufs),
}
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
match self.as_pin_mut() {
Either::Left(x) => x.poll_flush(cx),
Either::Right(x) => x.poll_flush(cx),
}
}
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
match self.as_pin_mut() {
Either::Left(x) => x.poll_close(cx),
Either::Right(x) => x.poll_close(cx),
}
}
}
impl<A, B> AsyncSeek for Either<A, B>
where
A: AsyncSeek,
B: AsyncSeek,
{
fn poll_seek(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
pos: SeekFrom,
) -> Poll<Result<u64>> {
match self.as_pin_mut() {
Either::Left(x) => x.poll_seek(cx, pos),
Either::Right(x) => x.poll_seek(cx, pos),
}
}
}
impl<A, B> AsyncBufRead for Either<A, B>
where
A: AsyncBufRead,
B: AsyncBufRead,
{
fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> {
match self.as_pin_mut() {
Either::Left(x) => x.poll_fill_buf(cx),
Either::Right(x) => x.poll_fill_buf(cx),
}
}
fn consume(self: Pin<&mut Self>, amt: usize) {
match self.as_pin_mut() {
Either::Left(x) => x.consume(amt),
Either::Right(x) => x.consume(amt),
}
}
}
}

View File

@@ -0,0 +1,39 @@
use core::any::Any;
use core::pin::Pin;
use std::boxed::Box;
use std::panic::{catch_unwind, AssertUnwindSafe, UnwindSafe};
use futures_core::future::Future;
use futures_core::task::{Context, Poll};
use pin_project_lite::pin_project;
pin_project! {
/// Future for the [`catch_unwind`](super::FutureExt::catch_unwind) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct CatchUnwind<Fut> {
#[pin]
future: Fut,
}
}
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,
{
type Output = Result<Fut::Output, Box<dyn Any + Send>>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let f = self.project().future;
catch_unwind(AssertUnwindSafe(|| f.poll(cx)))?.map(Ok)
}
}

View File

@@ -0,0 +1,153 @@
use core::pin::Pin;
use futures_core::future::{FusedFuture, Future};
use futures_core::ready;
use futures_core::stream::{FusedStream, Stream};
use futures_core::task::{Context, Poll};
#[cfg(feature = "sink")]
use futures_sink::Sink;
use pin_project_lite::pin_project;
pin_project! {
#[project = FlattenProj]
#[derive(Debug)]
pub enum Flatten<Fut1, Fut2> {
First { #[pin] f: Fut1 },
Second { #[pin] f: Fut2 },
Empty,
}
}
impl<Fut1, Fut2> Flatten<Fut1, Fut2> {
pub(crate) fn new(future: Fut1) -> Self {
Self::First { f: future }
}
}
impl<Fut> FusedFuture for Flatten<Fut, Fut::Output>
where
Fut: Future,
Fut::Output: Future,
{
fn is_terminated(&self) -> bool {
match self {
Self::Empty => true,
_ => false,
}
}
}
impl<Fut> Future for Flatten<Fut, Fut::Output>
where
Fut: Future,
Fut::Output: Future,
{
type Output = <Fut::Output as Future>::Output;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Poll::Ready(loop {
match self.as_mut().project() {
FlattenProj::First { f } => {
let f = ready!(f.poll(cx));
self.set(Self::Second { f });
}
FlattenProj::Second { f } => {
let output = ready!(f.poll(cx));
self.set(Self::Empty);
break output;
}
FlattenProj::Empty => panic!("Flatten polled after completion"),
}
})
}
}
impl<Fut> FusedStream for Flatten<Fut, Fut::Output>
where
Fut: Future,
Fut::Output: Stream,
{
fn is_terminated(&self) -> bool {
match self {
Self::Empty => true,
_ => false,
}
}
}
impl<Fut> Stream for Flatten<Fut, Fut::Output>
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 } => {
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
Fut: Future,
Fut::Output: Sink<Item>,
{
type Error = <Fut::Output as Sink<Item>>::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"),
}
})
}
fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
match self.project() {
FlattenProj::First { .. } => panic!("poll_ready not called first"),
FlattenProj::Second { f } => f.start_send(item),
FlattenProj::Empty => panic!("start_send called after eof"),
}
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
match self.project() {
FlattenProj::First { .. } => Poll::Ready(Ok(())),
FlattenProj::Second { f } => f.poll_flush(cx),
FlattenProj::Empty => panic!("poll_flush called after eof"),
}
}
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
let res = match self.as_mut().project() {
FlattenProj::Second { f } => f.poll_close(cx),
_ => Poll::Ready(Ok(())),
};
if res.is_ready() {
self.set(Self::Empty);
}
res
}
}

View File

@@ -0,0 +1,92 @@
use core::pin::Pin;
use futures_core::future::{FusedFuture, Future};
use futures_core::task::{Context, Poll};
use pin_project_lite::pin_project;
pin_project! {
/// Future for the [`fuse`](super::FutureExt::fuse) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Fuse<Fut> {
#[pin]
inner: Option<Fut>,
}
}
impl<Fut> Fuse<Fut> {
pub(super) fn new(f: Fut) -> Self {
Self { inner: Some(f) }
}
}
impl<Fut: Future> Fuse<Fut> {
/// Creates a new `Fuse`-wrapped future which is already terminated.
///
/// This can be useful in combination with looping and the `select!`
/// macro, which bypasses terminated futures.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use core::pin::pin;
///
/// use futures::channel::mpsc;
/// use futures::future::{Fuse, FusedFuture, FutureExt};
/// use futures::select;
/// use futures::stream::StreamExt;
///
/// let (sender, mut stream) = mpsc::unbounded();
///
/// // Send a few messages into the stream
/// sender.unbounded_send(()).unwrap();
/// sender.unbounded_send(()).unwrap();
/// drop(sender);
///
/// // Use `Fuse::terminated()` to create an already-terminated future
/// // which may be instantiated later.
/// let foo_printer = Fuse::terminated();
/// let mut foo_printer = pin!(foo_printer);
///
/// loop {
/// select! {
/// _ = foo_printer => {},
/// () = stream.select_next_some() => {
/// if !foo_printer.is_terminated() {
/// println!("Foo is already being printed!");
/// } else {
/// foo_printer.set(async {
/// // do some other async operations
/// println!("Printing foo from `foo_printer` future");
/// }.fuse());
/// }
/// },
/// complete => break, // `foo_printer` is terminated and the stream is done
/// }
/// }
/// # });
/// ```
pub fn terminated() -> Self {
Self { inner: None }
}
}
impl<Fut: Future> FusedFuture for Fuse<Fut> {
fn is_terminated(&self) -> bool {
self.inner.is_none()
}
}
impl<Fut: Future> Future for Fuse<Fut> {
type Output = Fut::Output;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Fut::Output> {
match self.as_mut().project().inner.as_pin_mut() {
Some(fut) => fut.poll(cx).map(|output| {
self.project().inner.set(None);
output
}),
None => Poll::Pending,
}
}
}

View File

@@ -0,0 +1,66 @@
use core::pin::Pin;
use futures_core::future::{FusedFuture, Future};
use futures_core::ready;
use futures_core::task::{Context, Poll};
use pin_project_lite::pin_project;
use crate::fns::FnOnce1;
pin_project! {
/// Internal Map future
#[project = MapProj]
#[project_replace = MapProjReplace]
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub enum Map<Fut, F> {
Incomplete {
#[pin]
future: Fut,
f: F,
},
Complete,
}
}
impl<Fut, F> Map<Fut, F> {
/// Creates a new Map.
pub(crate) fn new(future: Fut, f: F) -> Self {
Self::Incomplete { future, f }
}
}
impl<Fut, F, T> FusedFuture for Map<Fut, F>
where
Fut: Future,
F: FnOnce1<Fut::Output, Output = T>,
{
fn is_terminated(&self) -> bool {
match self {
Self::Incomplete { .. } => false,
Self::Complete => true,
}
}
}
impl<Fut, F, T> Future for Map<Fut, F>
where
Fut: Future,
F: FnOnce1<Fut::Output, Output = T>,
{
type Output = T;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
match self.as_mut().project() {
MapProj::Incomplete { future, .. } => {
let output = ready!(future.poll(cx));
match self.project_replace(Self::Complete) {
MapProjReplace::Incomplete { f, .. } => Poll::Ready(f.call_once(output)),
MapProjReplace::Complete => unreachable!(),
}
}
MapProj::Complete => {
panic!("Map must not be polled after it returned `Poll::Ready`")
}
}
}
}

View File

@@ -0,0 +1,603 @@
//! Futures
//!
//! This module contains a number of functions for working with `Future`s,
//! including the `FutureExt` trait which adds methods to `Future` types.
use crate::fns::{inspect_fn, into_fn, ok_fn, InspectFn, IntoFn, OkFn};
use crate::future::{assert_future, Either};
use crate::never::Never;
use crate::stream::assert_stream;
#[cfg(feature = "alloc")]
use alloc::boxed::Box;
use core::pin::pin;
use core::pin::Pin;
#[cfg(feature = "alloc")]
use futures_core::future::{BoxFuture, LocalBoxFuture};
use futures_core::{
future::Future,
stream::Stream,
task::{Context, Poll},
};
// Combinators
mod flatten;
mod fuse;
mod map;
delegate_all!(
/// Future for the [`flatten`](super::FutureExt::flatten) method.
Flatten<F>(
flatten::Flatten<F, <F as Future>::Output>
): Debug + Future + FusedFuture + New[|x: F| flatten::Flatten::new(x)]
where F: Future
);
delegate_all!(
/// Stream for the [`flatten_stream`](FutureExt::flatten_stream) method.
FlattenStream<F>(
flatten::Flatten<F, <F as Future>::Output>
): Debug + Sink + Stream + FusedStream + New[|x: F| flatten::Flatten::new(x)]
where F: Future
);
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use fuse::Fuse;
delegate_all!(
/// Future for the [`map`](super::FutureExt::map) method.
Map<Fut, F>(
map::Map<Fut, F>
): Debug + Future + FusedFuture + New[|x: Fut, f: F| map::Map::new(x, f)]
);
delegate_all!(
/// Stream for the [`into_stream`](FutureExt::into_stream) method.
IntoStream<F>(
crate::stream::Once<F>
): Debug + Stream + FusedStream + New[|x: F| crate::stream::Once::new(x)]
);
delegate_all!(
/// Future for the [`map_into`](FutureExt::map_into) combinator.
MapInto<Fut, T>(
Map<Fut, IntoFn<T>>
): Debug + Future + FusedFuture + New[|x: Fut| Map::new(x, into_fn())]
);
delegate_all!(
/// Future for the [`then`](FutureExt::then) method.
Then<Fut1, Fut2, F>(
flatten::Flatten<Map<Fut1, F>, Fut2>
): Debug + Future + FusedFuture + New[|x: Fut1, y: F| flatten::Flatten::new(Map::new(x, y))]
);
delegate_all!(
/// Future for the [`inspect`](FutureExt::inspect) method.
Inspect<Fut, F>(
map::Map<Fut, InspectFn<F>>
): Debug + Future + FusedFuture + New[|x: Fut, f: F| map::Map::new(x, inspect_fn(f))]
);
delegate_all!(
/// Future for the [`never_error`](super::FutureExt::never_error) combinator.
NeverError<Fut>(
Map<Fut, OkFn<Never>>
): Debug + Future + FusedFuture + New[|x: Fut| Map::new(x, ok_fn())]
);
delegate_all!(
/// Future for the [`unit_error`](super::FutureExt::unit_error) combinator.
UnitError<Fut>(
Map<Fut, OkFn<()>>
): Debug + Future + FusedFuture + New[|x: Fut| Map::new(x, ok_fn())]
);
#[cfg(feature = "std")]
mod catch_unwind;
#[cfg(feature = "std")]
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::catch_unwind::CatchUnwind;
#[cfg(feature = "channel")]
#[cfg_attr(docsrs, doc(cfg(feature = "channel")))]
#[cfg(feature = "std")]
mod remote_handle;
#[cfg(feature = "channel")]
#[cfg_attr(docsrs, doc(cfg(feature = "channel")))]
#[cfg(feature = "std")]
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::remote_handle::{Remote, RemoteHandle};
#[cfg(any(feature = "std", all(feature = "alloc", feature = "spin")))]
mod shared;
#[cfg(any(feature = "std", all(feature = "alloc", feature = "spin")))]
pub use self::shared::{Shared, WeakShared};
impl<T: ?Sized> FutureExt for T where T: Future {}
/// An extension trait for `Future`s that provides a variety of convenient
/// adapters.
pub trait FutureExt: Future {
/// Map this future's output to a different type, returning a new future of
/// the resulting type.
///
/// This function is similar to the `Option::map` or `Iterator::map` where
/// it will change the type of the underlying future. This is useful to
/// chain along a computation once a future has been resolved.
///
/// Note that this function consumes the receiving future and returns a
/// wrapped version of it, similar to the existing `map` methods in the
/// standard library.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::FutureExt;
///
/// let future = async { 1 };
/// let new_future = future.map(|x| x + 3);
/// assert_eq!(new_future.await, 4);
/// # });
/// ```
fn map<U, F>(self, f: F) -> Map<Self, F>
where
F: FnOnce(Self::Output) -> U,
Self: Sized,
{
assert_future::<U, _>(Map::new(self, f))
}
/// Map this future's output to a different type, returning a new future of
/// the resulting type.
///
/// This function is equivalent to calling `map(Into::into)` but allows naming
/// the return type.
fn map_into<U>(self) -> MapInto<Self, U>
where
Self::Output: Into<U>,
Self: Sized,
{
assert_future::<U, _>(MapInto::new(self))
}
/// Chain on a computation for when a future finished, passing the result of
/// the future to the provided closure `f`.
///
/// The returned value of the closure must implement the `Future` trait
/// and can represent some more work to be done before the composed future
/// is finished.
///
/// The closure `f` is only run *after* successful completion of the `self`
/// future.
///
/// Note that this function consumes the receiving future and returns a
/// wrapped version of it.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::FutureExt;
///
/// let future_of_1 = async { 1 };
/// let future_of_4 = future_of_1.then(|x| async move { x + 3 });
/// assert_eq!(future_of_4.await, 4);
/// # });
/// ```
fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where
F: FnOnce(Self::Output) -> Fut,
Fut: Future,
Self: Sized,
{
assert_future::<Fut::Output, _>(Then::new(self, f))
}
/// Wrap this future in an `Either` future, making it the left-hand variant
/// of that `Either`.
///
/// This can be used in combination with the `right_future` method to write `if`
/// statements that evaluate to different futures in different branches.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::FutureExt;
///
/// let x = 6;
/// let future = if x < 10 {
/// async { true }.left_future()
/// } else {
/// async { false }.right_future()
/// };
///
/// assert_eq!(future.await, true);
/// # });
/// ```
fn left_future<B>(self) -> Either<Self, B>
where
B: Future<Output = Self::Output>,
Self: Sized,
{
assert_future::<Self::Output, _>(Either::Left(self))
}
/// Wrap this future in an `Either` future, making it the right-hand variant
/// of that `Either`.
///
/// This can be used in combination with the `left_future` method to write `if`
/// statements that evaluate to different futures in different branches.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::FutureExt;
///
/// let x = 6;
/// let future = if x > 10 {
/// async { true }.left_future()
/// } else {
/// async { false }.right_future()
/// };
///
/// assert_eq!(future.await, false);
/// # });
/// ```
fn right_future<A>(self) -> Either<A, Self>
where
A: Future<Output = Self::Output>,
Self: Sized,
{
assert_future::<Self::Output, _>(Either::Right(self))
}
/// Convert this future into a single element stream.
///
/// The returned stream contains single success if this future resolves to
/// success or single error if this future resolves into error.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::FutureExt;
/// use futures::stream::StreamExt;
///
/// let future = async { 17 };
/// let stream = future.into_stream();
/// let collected: Vec<_> = stream.collect().await;
/// assert_eq!(collected, vec![17]);
/// # });
/// ```
fn into_stream(self) -> IntoStream<Self>
where
Self: Sized,
{
assert_stream::<Self::Output, _>(IntoStream::new(self))
}
/// Flatten the execution of this future when the output of this
/// future is itself another future.
///
/// This can be useful when combining futures together to flatten the
/// computation out the final result.
///
/// This method is roughly equivalent to `self.then(|x| x)`.
///
/// Note that this function consumes the receiving future and returns a
/// wrapped version of it.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::FutureExt;
///
/// let nested_future = async { async { 1 } };
/// let future = nested_future.flatten();
/// assert_eq!(future.await, 1);
/// # });
/// ```
fn flatten(self) -> Flatten<Self>
where
Self::Output: Future,
Self: Sized,
{
let f = Flatten::new(self);
assert_future::<<<Self as Future>::Output as Future>::Output, _>(f)
}
/// Flatten the execution of this future when the successful result of this
/// future is a stream.
///
/// This can be useful when stream initialization is deferred, and it is
/// convenient to work with that stream as if stream was available at the
/// call site.
///
/// Note that this function consumes this future and returns a wrapped
/// version of it.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::FutureExt;
/// use futures::stream::{self, StreamExt};
///
/// let stream_items = vec![17, 18, 19];
/// let future_of_a_stream = async { stream::iter(stream_items) };
///
/// let stream = future_of_a_stream.flatten_stream();
/// let list: Vec<_> = stream.collect().await;
/// assert_eq!(list, vec![17, 18, 19]);
/// # });
/// ```
fn flatten_stream(self) -> FlattenStream<Self>
where
Self::Output: Stream,
Self: Sized,
{
assert_stream::<<Self::Output as Stream>::Item, _>(FlattenStream::new(self))
}
/// Fuse a future such that `poll` will never again be called once it has
/// completed. This method can be used to turn any `Future` into a
/// `FusedFuture`.
///
/// Normally, once a future has returned `Poll::Ready` from `poll`,
/// any further calls could exhibit bad behavior such as blocking
/// forever, panicking, never returning, etc. If it is known that `poll`
/// may be called too often then this method can be used to ensure that it
/// has defined semantics.
///
/// If a `fuse`d future is `poll`ed after having returned `Poll::Ready`
/// previously, it will return `Poll::Pending`, from `poll` again (and will
/// continue to do so for all future calls to `poll`).
///
/// This combinator will drop the underlying future as soon as it has been
/// completed to ensure resources are reclaimed as soon as possible.
fn fuse(self) -> Fuse<Self>
where
Self: Sized,
{
let f = Fuse::new(self);
assert_future::<Self::Output, _>(f)
}
/// Do something with the output of a future before passing it on.
///
/// When using futures, you'll often chain several of them together. While
/// working on such code, you might want to check out what's happening at
/// various parts in the pipeline, without consuming the intermediate
/// value. To do that, insert a call to `inspect`.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::FutureExt;
///
/// let future = async { 1 };
/// let new_future = future.inspect(|&x| println!("about to resolve: {}", x));
/// assert_eq!(new_future.await, 1);
/// # });
/// ```
fn inspect<F>(self, f: F) -> Inspect<Self, F>
where
F: FnOnce(&Self::Output),
Self: Sized,
{
assert_future::<Self::Output, _>(Inspect::new(self, f))
}
/// Catches unwinding panics while polling the future.
///
/// In general, panics within a future can propagate all the way out to the
/// task level. This combinator makes it possible to halt unwinding within
/// the future itself. It's most commonly used within task executors. It's
/// not recommended to use this for error handling.
///
/// Note that this method requires the `UnwindSafe` bound from the standard
/// library. This isn't always applied automatically, and the standard
/// library provides an `AssertUnwindSafe` wrapper type to apply it
/// after-the fact. To assist using this method, the `Future` trait is also
/// implemented for `AssertUnwindSafe<F>` where `F` implements `Future`.
///
/// This method is only available when the `std` feature of this
/// library is activated, and it is activated by default.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::{self, FutureExt, Ready};
///
/// let future = future::ready(2);
/// assert!(future.catch_unwind().await.is_ok());
///
/// let future = future::lazy(|_| -> Ready<i32> {
/// unimplemented!()
/// });
/// assert!(future.catch_unwind().await.is_err());
/// # });
/// ```
#[cfg(feature = "std")]
fn catch_unwind(self) -> CatchUnwind<Self>
where
Self: Sized + ::std::panic::UnwindSafe,
{
assert_future::<Result<Self::Output, Box<dyn std::any::Any + Send>>, _>(CatchUnwind::new(
self,
))
}
/// Create a cloneable handle to this future where all handles will resolve
/// to the same result.
///
/// The `shared` combinator method provides a method to convert any future
/// into a cloneable future. It enables a future to be polled by multiple
/// threads.
///
/// This method is only available when the `std` or 'spin' feature of this
/// library is activated, and it is activated by default.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::FutureExt;
///
/// let future = async { 6 };
/// let shared1 = future.shared();
/// let shared2 = shared1.clone();
///
/// assert_eq!(6, shared1.await);
/// assert_eq!(6, shared2.await);
/// # });
/// ```
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::FutureExt;
/// use futures::executor::block_on;
/// use std::thread;
///
/// let future = async { 6 };
/// let shared1 = future.shared();
/// let shared2 = shared1.clone();
/// let join_handle = thread::spawn(move || {
/// assert_eq!(6, block_on(shared2));
/// });
/// assert_eq!(6, shared1.await);
/// join_handle.join().unwrap();
/// # });
/// ```
#[cfg(any(feature = "std", all(feature = "alloc", feature = "spin")))]
fn shared(self) -> Shared<Self>
where
Self: Sized,
Self::Output: Clone,
{
assert_future::<Self::Output, _>(Shared::new(self))
}
/// Turn this future into a future that yields `()` on completion and sends
/// its output to another future on a separate task.
///
/// This can be used with spawning executors to easily retrieve the result
/// of a future executing on a separate task or thread.
///
/// This method is only available when the `std` feature of this
/// library is activated, and it is activated by default.
#[cfg(feature = "channel")]
#[cfg_attr(docsrs, doc(cfg(feature = "channel")))]
#[cfg(feature = "std")]
fn remote_handle(self) -> (Remote<Self>, RemoteHandle<Self::Output>)
where
Self: Sized,
{
let (wrapped, handle) = remote_handle::remote_handle(self);
(assert_future::<(), _>(wrapped), handle)
}
/// Wrap the future in a Box, pinning it.
///
/// This method is only available when the `std` or `alloc` feature of this
/// library is activated, and it is activated by default.
#[cfg(feature = "alloc")]
fn boxed<'a>(self) -> BoxFuture<'a, Self::Output>
where
Self: Sized + Send + 'a,
{
assert_future::<Self::Output, _>(Box::pin(self))
}
/// Wrap the future in a Box, pinning it.
///
/// Similar to `boxed`, but without the `Send` requirement.
///
/// This method is only available when the `std` or `alloc` feature of this
/// library is activated, and it is activated by default.
#[cfg(feature = "alloc")]
fn boxed_local<'a>(self) -> LocalBoxFuture<'a, Self::Output>
where
Self: Sized + 'a,
{
assert_future::<Self::Output, _>(Box::pin(self))
}
/// Turns a [`Future<Output = T>`](Future) into a
/// [`TryFuture<Ok = T, Error = ()`>](futures_core::future::TryFuture).
fn unit_error(self) -> UnitError<Self>
where
Self: Sized,
{
assert_future::<Result<Self::Output, ()>, _>(UnitError::new(self))
}
/// Turns a [`Future<Output = T>`](Future) into a
/// [`TryFuture<Ok = T, Error = Never`>](futures_core::future::TryFuture).
fn never_error(self) -> NeverError<Self>
where
Self: Sized,
{
assert_future::<Result<Self::Output, Never>, _>(NeverError::new(self))
}
/// A convenience for calling `Future::poll` on `Unpin` future types.
fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where
Self: Unpin,
{
Pin::new(self).poll(cx)
}
/// Evaluates and consumes the future, returning the resulting output if
/// the future is ready after the first call to `Future::poll`.
///
/// If `poll` instead returns `Poll::Pending`, `None` is returned.
///
/// This method is useful in cases where immediacy is more important than
/// waiting for a result. It is also convenient for quickly obtaining
/// the value of a future that is known to always resolve immediately.
///
/// # Examples
///
/// ```
/// # use futures::prelude::*;
/// use futures::{future::ready, future::pending};
/// let future_ready = ready("foobar");
/// let future_pending = pending::<&'static str>();
///
/// assert_eq!(future_ready.now_or_never(), Some("foobar"));
/// assert_eq!(future_pending.now_or_never(), None);
/// ```
///
/// In cases where it is absolutely known that a future should always
/// resolve immediately and never return `Poll::Pending`, this method can
/// be combined with `expect()`:
///
/// ```
/// # use futures::{prelude::*, future::ready};
/// let future_ready = ready("foobar");
///
/// assert_eq!(future_ready.now_or_never().expect("Future not ready"), "foobar");
/// ```
fn now_or_never(self) -> Option<Self::Output>
where
Self: Sized,
{
let noop_waker = crate::task::noop_waker();
let mut cx = Context::from_waker(&noop_waker);
let this = pin!(self);
match this.poll(&mut cx) {
Poll::Ready(x) => Some(x),
_ => None,
}
}
}

View File

@@ -0,0 +1,127 @@
use {
crate::future::{CatchUnwind, FutureExt},
futures_channel::oneshot::{self, Receiver, Sender},
futures_core::{
future::Future,
ready,
task::{Context, Poll},
},
pin_project_lite::pin_project,
std::{
any::Any,
boxed::Box,
fmt,
panic::{self, AssertUnwindSafe},
pin::Pin,
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
thread,
},
};
/// The handle to a remote future returned by
/// [`remote_handle`](crate::future::FutureExt::remote_handle). When you drop this,
/// the remote future will be woken up to be dropped by the executor.
///
/// ## Unwind safety
///
/// When the remote future panics, [Remote] will catch the unwind and transfer it to
/// the thread where `RemoteHandle` is being awaited. This is good for the common
/// case where [Remote] is spawned on a threadpool. It is unlikely that other code
/// in the executor working thread shares mutable data with the spawned future and we
/// preserve the executor from losing its working threads.
///
/// If you run the future locally and send the handle of to be awaited elsewhere, you
/// must be careful with regard to unwind safety because the thread in which the future
/// is polled will keep running after the panic and the thread running the [RemoteHandle]
/// will unwind.
#[must_use = "dropping a remote handle cancels the underlying future"]
#[derive(Debug)]
#[cfg_attr(docsrs, doc(cfg(feature = "channel")))]
pub struct RemoteHandle<T> {
rx: Receiver<thread::Result<T>>,
keep_running: Arc<AtomicBool>,
}
impl<T> RemoteHandle<T> {
/// Drops this handle *without* canceling the underlying future.
///
/// This method can be used if you want to drop the handle, but let the
/// execution continue.
pub fn forget(self) {
self.keep_running.store(true, Ordering::SeqCst);
}
}
impl<T: 'static> Future for RemoteHandle<T> {
type Output = T;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
match ready!(self.rx.poll_unpin(cx)) {
Ok(Ok(output)) => Poll::Ready(output),
// the remote future panicked.
Ok(Err(e)) => panic::resume_unwind(e),
// The oneshot sender was dropped.
Err(e) => panic::resume_unwind(Box::new(e)),
}
}
}
type SendMsg<Fut> = Result<<Fut as Future>::Output, Box<dyn Any + Send + 'static>>;
pin_project! {
/// A future which sends its output to the corresponding `RemoteHandle`.
/// Created by [`remote_handle`](crate::future::FutureExt::remote_handle).
#[must_use = "futures do nothing unless you `.await` or poll them"]
#[cfg_attr(docsrs, doc(cfg(feature = "channel")))]
pub struct Remote<Fut: Future> {
tx: Option<Sender<SendMsg<Fut>>>,
keep_running: Arc<AtomicBool>,
#[pin]
future: CatchUnwind<AssertUnwindSafe<Fut>>,
}
}
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()
}
}
impl<Fut: Future> Future for Remote<Fut> {
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
let this = self.project();
if this.tx.as_mut().unwrap().poll_canceled(cx).is_ready()
&& !this.keep_running.load(Ordering::SeqCst)
{
// Cancelled, bail out
return Poll::Ready(());
}
let output = ready!(this.future.poll(cx));
// if the receiving end has gone away then that's ok, we just ignore the
// send error here.
drop(this.tx.take().unwrap().send(output));
Poll::Ready(())
}
}
pub(super) fn remote_handle<Fut: Future>(future: Fut) -> (Remote<Fut>, RemoteHandle<Fut::Output>) {
let (tx, rx) = oneshot::channel();
let keep_running = Arc::new(AtomicBool::new(false));
// Unwind Safety: See the docs for RemoteHandle.
let wrapped = Remote {
future: AssertUnwindSafe(future).catch_unwind(),
tx: Some(tx),
keep_running: keep_running.clone(),
};
(wrapped, RemoteHandle { rx, keep_running })
}

View File

@@ -0,0 +1,430 @@
use crate::task::{waker_ref, ArcWake};
use alloc::sync::{Arc, Weak};
use core::cell::UnsafeCell;
use core::fmt;
use core::hash::Hasher;
use core::pin::Pin;
use core::ptr;
use core::sync::atomic::AtomicUsize;
use core::sync::atomic::Ordering::{Acquire, SeqCst};
use futures_core::future::{FusedFuture, Future};
use futures_core::task::{Context, Poll, Waker};
use slab::Slab;
#[cfg(feature = "std")]
type Mutex<T> = std::sync::Mutex<T>;
#[cfg(not(feature = "std"))]
type Mutex<T> = spin::Mutex<T>;
/// Future for the [`shared`](super::FutureExt::shared) method.
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Shared<Fut: Future> {
inner: Option<Arc<Inner<Fut>>>,
waker_key: usize,
}
struct Inner<Fut: Future> {
future_or_output: UnsafeCell<FutureOrOutput<Fut>>,
notifier: Arc<Notifier>,
}
struct Notifier {
state: AtomicUsize,
wakers: Mutex<Option<Slab<Option<Waker>>>>,
}
/// 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())
}
}
impl<Fut: Future> fmt::Debug for Shared<Fut> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Shared")
.field("inner", &self.inner)
.field("waker_key", &self.waker_key)
.finish()
}
}
impl<Fut: Future> fmt::Debug for Inner<Fut> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Inner").finish()
}
}
impl<Fut: Future> fmt::Debug for WeakShared<Fut> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("WeakShared").finish()
}
}
enum FutureOrOutput<Fut: Future> {
Future(Fut),
Output(Fut::Output),
}
unsafe impl<Fut> Send for Inner<Fut>
where
Fut: Future + Send,
Fut::Output: Send + Sync,
{
}
unsafe impl<Fut> Sync for Inner<Fut>
where
Fut: Future + Send,
Fut::Output: Send + Sync,
{
}
const IDLE: usize = 0;
const POLLING: usize = 1;
const COMPLETE: usize = 2;
const POISONED: usize = 3;
const NULL_WAKER_KEY: usize = usize::MAX;
impl<Fut: Future> Shared<Fut> {
pub(super) fn new(future: Fut) -> Self {
let inner = Inner {
future_or_output: UnsafeCell::new(FutureOrOutput::Future(future)),
notifier: Arc::new(Notifier {
state: AtomicUsize::new(IDLE),
wakers: Mutex::new(Some(Slab::new())),
}),
};
Self { inner: Some(Arc::new(inner)), waker_key: NULL_WAKER_KEY }
}
}
impl<Fut> Shared<Fut>
where
Fut: Future,
{
/// Returns [`Some`] containing a reference to this [`Shared`]'s output if
/// it has already been computed by a clone or [`None`] if it hasn't been
/// computed yet or this [`Shared`] already returned its output from
/// [`poll`](Future::poll).
pub fn peek(&self) -> Option<&Fut::Output> {
if let Some(inner) = self.inner.as_ref() {
match inner.notifier.state.load(SeqCst) {
COMPLETE => unsafe { return Some(inner.output()) },
POISONED => panic!("inner future panicked during poll"),
_ => {}
}
}
None
}
/// Creates a new [`WeakShared`] for this [`Shared`].
///
/// Returns [`None`] if it has already been polled to completion.
pub fn downgrade(&self) -> Option<WeakShared<Fut>> {
if let Some(inner) = self.inner.as_ref() {
return Some(WeakShared(Arc::downgrade(inner)));
}
None
}
/// Gets the number of strong pointers to this allocation.
///
/// Returns [`None`] if it has already been polled to completion.
///
/// # Safety
///
/// This method by itself is safe, but using it correctly requires extra care. Another thread
/// can change the strong count at any time, including potentially between calling this method
/// and acting on the result.
#[allow(clippy::unnecessary_safety_doc)]
pub fn strong_count(&self) -> Option<usize> {
self.inner.as_ref().map(|arc| Arc::strong_count(arc))
}
/// Gets the number of weak pointers to this allocation.
///
/// Returns [`None`] if it has already been polled to completion.
///
/// # Safety
///
/// This method by itself is safe, but using it correctly requires extra care. Another thread
/// can change the weak count at any time, including potentially between calling this method
/// and acting on the result.
#[allow(clippy::unnecessary_safety_doc)]
pub fn weak_count(&self) -> Option<usize> {
self.inner.as_ref().map(|arc| Arc::weak_count(arc))
}
/// Hashes the internal state of this `Shared` in a way that's compatible with `ptr_eq`.
pub fn ptr_hash<H: Hasher>(&self, state: &mut H) {
match self.inner.as_ref() {
Some(arc) => {
state.write_u8(1);
ptr::hash(Arc::as_ptr(arc), state);
}
None => {
state.write_u8(0);
}
}
}
/// Returns `true` if the two `Shared`s point to the same future (in a vein similar to
/// `Arc::ptr_eq`).
///
/// Returns `false` if either `Shared` has terminated.
pub fn ptr_eq(&self, rhs: &Self) -> bool {
let lhs = match self.inner.as_ref() {
Some(lhs) => lhs,
None => return false,
};
let rhs = match rhs.inner.as_ref() {
Some(rhs) => rhs,
None => return false,
};
Arc::ptr_eq(lhs, rhs)
}
}
impl<Fut> Inner<Fut>
where
Fut: Future,
{
/// Safety: callers must first ensure that `self.inner.state`
/// is `COMPLETE`
unsafe fn output(&self) -> &Fut::Output {
match unsafe { &*self.future_or_output.get() } {
FutureOrOutput::Output(item) => item,
FutureOrOutput::Future(_) => unreachable!(),
}
}
}
impl<Fut> Inner<Fut>
where
Fut: Future,
Fut::Output: Clone,
{
/// Registers the current task to receive a wakeup when we are awoken.
fn record_waker(&self, waker_key: &mut usize, cx: &mut Context<'_>) {
#[cfg(feature = "std")]
let mut wakers_guard = self.notifier.wakers.lock().unwrap();
#[cfg(not(feature = "std"))]
let mut wakers_guard = self.notifier.wakers.lock();
let wakers = match wakers_guard.as_mut() {
Some(wakers) => wakers,
None => return,
};
let new_waker = cx.waker();
if *waker_key == NULL_WAKER_KEY {
*waker_key = wakers.insert(Some(new_waker.clone()));
} else {
match wakers[*waker_key] {
Some(ref old_waker) if new_waker.will_wake(old_waker) => {}
// Could use clone_from here, but Waker doesn't specialize it.
ref mut slot => *slot = Some(new_waker.clone()),
}
}
debug_assert!(*waker_key != NULL_WAKER_KEY);
}
/// Safety: callers must first ensure that `inner.state`
/// is `COMPLETE`
unsafe fn take_or_clone_output(self: Arc<Self>) -> Fut::Output {
match Arc::try_unwrap(self) {
Ok(inner) => match inner.future_or_output.into_inner() {
FutureOrOutput::Output(item) => item,
FutureOrOutput::Future(_) => unreachable!(),
},
Err(inner) => unsafe { inner.output().clone() },
}
}
}
impl<Fut> FusedFuture for Shared<Fut>
where
Fut: Future,
Fut::Output: Clone,
{
fn is_terminated(&self) -> bool {
self.inner.is_none()
}
}
impl<Fut> Future for Shared<Fut>
where
Fut: Future,
Fut::Output: Clone,
{
type Output = Fut::Output;
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");
// Fast path for when the wrapped future has already completed
if inner.notifier.state.load(Acquire) == COMPLETE {
// Safety: We're in the COMPLETE state
return unsafe { Poll::Ready(inner.take_or_clone_output()) };
}
inner.record_waker(&mut this.waker_key, cx);
match inner
.notifier
.state
.compare_exchange(IDLE, POLLING, SeqCst, SeqCst)
.unwrap_or_else(|x| x)
{
IDLE => {
// Lock acquired, fall through
}
POLLING => {
// Another task is currently polling, at this point we just want
// to ensure that the waker for this task is registered
this.inner = Some(inner);
return Poll::Pending;
}
COMPLETE => {
// Safety: We're in the COMPLETE state
return unsafe { Poll::Ready(inner.take_or_clone_output()) };
}
POISONED => panic!("inner future panicked during poll"),
_ => unreachable!(),
}
let waker = waker_ref(&inner.notifier);
let mut cx = Context::from_waker(&waker);
struct Reset<'a> {
state: &'a AtomicUsize,
did_not_panic: bool,
}
impl Drop for Reset<'_> {
fn drop(&mut self) {
if !self.did_not_panic {
self.state.store(POISONED, SeqCst);
}
}
}
let mut reset = Reset { state: &inner.notifier.state, did_not_panic: false };
let output = {
let future = unsafe {
match &mut *inner.future_or_output.get() {
FutureOrOutput::Future(fut) => Pin::new_unchecked(fut),
_ => unreachable!(),
}
};
let poll_result = future.poll(&mut cx);
reset.did_not_panic = true;
match poll_result {
Poll::Pending => {
if inner.notifier.state.compare_exchange(POLLING, IDLE, SeqCst, SeqCst).is_ok()
{
// Success
drop(reset);
this.inner = Some(inner);
return Poll::Pending;
} else {
unreachable!()
}
}
Poll::Ready(output) => output,
}
};
unsafe {
*inner.future_or_output.get() = FutureOrOutput::Output(output);
}
inner.notifier.state.store(COMPLETE, SeqCst);
// Wake all tasks and drop the slab
#[cfg(feature = "std")]
let mut wakers_guard = inner.notifier.wakers.lock().unwrap();
#[cfg(not(feature = "std"))]
let mut wakers_guard = inner.notifier.wakers.lock();
let mut wakers = wakers_guard.take().unwrap();
for waker in wakers.drain().flatten() {
waker.wake();
}
drop(reset); // Make borrow checker happy
drop(wakers_guard);
// Safety: We're in the COMPLETE state
unsafe { Poll::Ready(inner.take_or_clone_output()) }
}
}
impl<Fut> Clone for Shared<Fut>
where
Fut: Future,
{
fn clone(&self) -> Self {
Self { inner: self.inner.clone(), waker_key: NULL_WAKER_KEY }
}
}
impl<Fut> Drop for Shared<Fut>
where
Fut: Future,
{
fn drop(&mut self) {
if self.waker_key != NULL_WAKER_KEY {
if let Some(ref inner) = self.inner {
#[cfg(feature = "std")]
if let Ok(mut wakers) = inner.notifier.wakers.lock() {
if let Some(wakers) = wakers.as_mut() {
wakers.remove(self.waker_key);
}
}
#[cfg(not(feature = "std"))]
if let Some(wakers) = inner.notifier.wakers.lock().as_mut() {
wakers.remove(self.waker_key);
}
}
}
}
}
impl ArcWake for Notifier {
fn wake_by_ref(arc_self: &Arc<Self>) {
#[cfg(feature = "std")]
let wakers = &mut *arc_self.wakers.lock().unwrap();
#[cfg(not(feature = "std"))]
let wakers = &mut *arc_self.wakers.lock();
if let Some(wakers) = wakers.as_mut() {
for (_key, opt_waker) in wakers {
if let Some(waker) = opt_waker.take() {
waker.wake();
}
}
}
}
}
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 })
}
}

217
vendor/futures-util/src/future/join.rs vendored Normal file
View File

@@ -0,0 +1,217 @@
#![allow(non_snake_case)]
use super::assert_future;
use crate::future::{maybe_done, MaybeDone};
use core::fmt;
use core::pin::Pin;
use futures_core::future::{FusedFuture, Future};
use futures_core::task::{Context, Poll};
use pin_project_lite::pin_project;
macro_rules! generate {
($(
$(#[$doc:meta])*
($Join:ident, <$($Fut:ident),*>),
)*) => ($(
pin_project! {
$(#[$doc])*
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct $Join<$($Fut: Future),*> {
$(#[pin] $Fut: MaybeDone<$Fut>,)*
}
}
impl<$($Fut),*> fmt::Debug for $Join<$($Fut),*>
where
$(
$Fut: Future + fmt::Debug,
$Fut::Output: fmt::Debug,
)*
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct(stringify!($Join))
$(.field(stringify!($Fut), &self.$Fut))*
.finish()
}
}
impl<$($Fut: Future),*> $Join<$($Fut),*> {
fn new($($Fut: $Fut),*) -> Self {
Self {
$($Fut: maybe_done($Fut)),*
}
}
}
impl<$($Fut: Future),*> Future for $Join<$($Fut),*> {
type Output = ($($Fut::Output),*);
fn poll(
self: Pin<&mut Self>, cx: &mut Context<'_>
) -> Poll<Self::Output> {
let mut all_done = true;
let mut futures = self.project();
$(
all_done &= futures.$Fut.as_mut().poll(cx).is_ready();
)*
if all_done {
Poll::Ready(($(futures.$Fut.take_output().unwrap()), *))
} else {
Poll::Pending
}
}
}
impl<$($Fut: FusedFuture),*> FusedFuture for $Join<$($Fut),*> {
fn is_terminated(&self) -> bool {
$(
self.$Fut.is_terminated()
) && *
}
}
)*)
}
generate! {
/// Future for the [`join`](join()) function.
(Join, <Fut1, Fut2>),
/// Future for the [`join3`] function.
(Join3, <Fut1, Fut2, Fut3>),
/// Future for the [`join4`] function.
(Join4, <Fut1, Fut2, Fut3, Fut4>),
/// Future for the [`join5`] function.
(Join5, <Fut1, Fut2, Fut3, Fut4, Fut5>),
}
/// Joins the result of two futures, waiting for them both to complete.
///
/// This function will return a new future which awaits both futures to
/// complete. The returned future will finish with a tuple of both results.
///
/// Note that this function consumes the passed futures and returns a
/// wrapped version of it.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
///
/// let a = async { 1 };
/// let b = async { 2 };
/// let pair = future::join(a, b);
///
/// assert_eq!(pair.await, (1, 2));
/// # });
/// ```
pub fn join<Fut1, Fut2>(future1: Fut1, future2: Fut2) -> Join<Fut1, Fut2>
where
Fut1: Future,
Fut2: Future,
{
let f = Join::new(future1, future2);
assert_future::<(Fut1::Output, Fut2::Output), _>(f)
}
/// Same as [`join`](join()), but with more futures.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
///
/// let a = async { 1 };
/// let b = async { 2 };
/// let c = async { 3 };
/// let tuple = future::join3(a, b, c);
///
/// assert_eq!(tuple.await, (1, 2, 3));
/// # });
/// ```
pub fn join3<Fut1, Fut2, Fut3>(
future1: Fut1,
future2: Fut2,
future3: Fut3,
) -> Join3<Fut1, Fut2, Fut3>
where
Fut1: Future,
Fut2: Future,
Fut3: Future,
{
let f = Join3::new(future1, future2, future3);
assert_future::<(Fut1::Output, Fut2::Output, Fut3::Output), _>(f)
}
/// Same as [`join`](join()), but with more futures.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
///
/// let a = async { 1 };
/// let b = async { 2 };
/// let c = async { 3 };
/// let d = async { 4 };
/// let tuple = future::join4(a, b, c, d);
///
/// assert_eq!(tuple.await, (1, 2, 3, 4));
/// # });
/// ```
pub fn join4<Fut1, Fut2, Fut3, Fut4>(
future1: Fut1,
future2: Fut2,
future3: Fut3,
future4: Fut4,
) -> Join4<Fut1, Fut2, Fut3, Fut4>
where
Fut1: Future,
Fut2: Future,
Fut3: Future,
Fut4: Future,
{
let f = Join4::new(future1, future2, future3, future4);
assert_future::<(Fut1::Output, Fut2::Output, Fut3::Output, Fut4::Output), _>(f)
}
/// Same as [`join`](join()), but with more futures.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
///
/// let a = async { 1 };
/// let b = async { 2 };
/// let c = async { 3 };
/// let d = async { 4 };
/// let e = async { 5 };
/// let tuple = future::join5(a, b, c, d, e);
///
/// assert_eq!(tuple.await, (1, 2, 3, 4, 5));
/// # });
/// ```
pub fn join5<Fut1, Fut2, Fut3, Fut4, Fut5>(
future1: Fut1,
future2: Fut2,
future3: Fut3,
future4: Fut4,
future5: Fut5,
) -> Join5<Fut1, Fut2, Fut3, Fut4, Fut5>
where
Fut1: Future,
Fut2: Future,
Fut3: Future,
Fut4: Future,
Fut5: Future,
{
let f = Join5::new(future1, future2, future3, future4, future5);
assert_future::<(Fut1::Output, Fut2::Output, Fut3::Output, Fut4::Output, Fut5::Output), _>(f)
}

View File

@@ -0,0 +1,167 @@
//! Definition of the `JoinAll` combinator, waiting for all of a list of futures
//! to finish.
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::fmt;
use core::future::Future;
use core::iter::FromIterator;
use core::mem;
use core::pin::Pin;
use core::task::{Context, Poll};
use super::{assert_future, MaybeDone};
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
use crate::stream::{Collect, FuturesOrdered, StreamExt};
pub(crate) fn iter_pin_mut<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) })
}
#[must_use = "futures do nothing unless you `.await` or poll them"]
/// Future for the [`join_all`] function.
pub struct JoinAll<F>
where
F: Future,
{
kind: JoinAllKind<F>,
}
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
pub(crate) const SMALL: usize = 30;
enum JoinAllKind<F>
where
F: Future,
{
Small {
elems: Pin<Box<[MaybeDone<F>]>>,
},
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
Big {
fut: Collect<FuturesOrdered<F>, Vec<F::Output>>,
},
}
impl<F> fmt::Debug for JoinAll<F>
where
F: Future + fmt::Debug,
F::Output: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.kind {
JoinAllKind::Small { ref elems } => {
f.debug_struct("JoinAll").field("elems", elems).finish()
}
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
JoinAllKind::Big { ref fut, .. } => fmt::Debug::fmt(fut, f),
}
}
}
/// Creates a future which represents a collection of the outputs of the futures
/// given.
///
/// The returned future will drive execution for all of its underlying futures,
/// collecting the results into a destination `Vec<T>` in the same order as they
/// were provided.
///
/// This function is only available when the `std` or `alloc` feature of this
/// library is activated, and it is activated by default.
///
/// # See Also
///
/// `join_all` will switch to the more powerful [`FuturesOrdered`] for performance
/// reasons if the number of futures is large. You may want to look into using it or
/// its counterpart [`FuturesUnordered`][crate::stream::FuturesUnordered] directly.
///
/// Some examples for additional functionality provided by these are:
///
/// * Adding new futures to the set even after it has been started.
///
/// * Only polling the specific futures that have been woken. In cases where
/// you have a lot of futures this will result in much more efficient polling.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::join_all;
///
/// async fn foo(i: u32) -> u32 { i }
///
/// let futures = vec![foo(1), foo(2), foo(3)];
///
/// assert_eq!(join_all(futures).await, [1, 2, 3]);
/// # });
/// ```
pub fn join_all<I>(iter: I) -> JoinAll<I::Item>
where
I: IntoIterator,
I::Item: Future,
{
let iter = iter.into_iter();
#[cfg(target_os = "none")]
#[cfg_attr(target_os = "none", cfg(not(target_has_atomic = "ptr")))]
{
let kind =
JoinAllKind::Small { elems: iter.map(MaybeDone::Future).collect::<Box<[_]>>().into() };
assert_future::<Vec<<I::Item as Future>::Output>, _>(JoinAll { kind })
}
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
{
let kind = match iter.size_hint().1 {
Some(max) if max <= SMALL => JoinAllKind::Small {
elems: iter.map(MaybeDone::Future).collect::<Box<[_]>>().into(),
},
_ => JoinAllKind::Big { fut: iter.collect::<FuturesOrdered<_>>().collect() },
};
assert_future::<Vec<<I::Item as Future>::Output>, _>(JoinAll { kind })
}
}
impl<F> Future for JoinAll<F>
where
F: Future,
{
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;
}
}
if all_done {
let mut elems = mem::replace(elems, Box::pin([]));
let result =
iter_pin_mut(elems.as_mut()).map(|e| e.take_output().unwrap()).collect();
Poll::Ready(result)
} else {
Poll::Pending
}
}
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
JoinAllKind::Big { fut } => Pin::new(fut).poll(cx),
}
}
}
impl<F: Future> FromIterator<F> for JoinAll<F> {
fn from_iter<T: IntoIterator<Item = F>>(iter: T) -> Self {
join_all(iter)
}
}

60
vendor/futures-util/src/future/lazy.rs vendored Normal file
View File

@@ -0,0 +1,60 @@
use super::assert_future;
use core::pin::Pin;
use futures_core::future::{FusedFuture, Future};
use futures_core::task::{Context, Poll};
/// Future for the [`lazy`] function.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Lazy<F> {
f: Option<F>,
}
// safe because we never generate `Pin<&mut F>`
impl<F> Unpin for Lazy<F> {}
/// Creates a new future that allows delayed execution of a closure.
///
/// The provided closure is only run once the future is polled.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
///
/// let a = future::lazy(|_| 1);
/// assert_eq!(a.await, 1);
///
/// let b = future::lazy(|_| -> i32 {
/// panic!("oh no!")
/// });
/// drop(b); // closure is never run
/// # });
/// ```
pub fn lazy<F, R>(f: F) -> Lazy<F>
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,
{
fn is_terminated(&self) -> bool {
self.f.is_none()
}
}
impl<F, R> Future for Lazy<F>
where
F: FnOnce(&mut Context<'_>) -> R,
{
type Output = R;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<R> {
Poll::Ready((self.f.take().expect("Lazy polled after completion"))(cx))
}
}

View File

@@ -0,0 +1,105 @@
//! Definition of the MaybeDone combinator
use super::assert_future;
use core::mem;
use core::pin::Pin;
use futures_core::future::{FusedFuture, Future};
use futures_core::ready;
use futures_core::task::{Context, Poll};
/// A future that may have completed.
///
/// This is created by the [`maybe_done()`] function.
#[derive(Debug)]
pub enum MaybeDone<Fut: Future> {
/// A not-yet-completed future
Future(/* #[pin] */ Fut),
/// The output of the completed future
Done(Fut::Output),
/// The empty variant after the result of a [`MaybeDone`] has been
/// taken using the [`take_output`](MaybeDone::take_output) method.
Gone,
}
impl<Fut: Future + Unpin> Unpin for MaybeDone<Fut> {}
/// Wraps a future into a `MaybeDone`
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use core::pin::pin;
///
/// use futures::future;
///
/// let future = future::maybe_done(async { 5 });
/// let mut future = pin!(future);
/// assert_eq!(future.as_mut().take_output(), None);
/// let () = future.as_mut().await;
/// assert_eq!(future.as_mut().take_output(), Some(5));
/// assert_eq!(future.as_mut().take_output(), None);
/// # });
/// ```
pub fn maybe_done<Fut: Future>(future: Fut) -> MaybeDone<Fut> {
assert_future::<(), _>(MaybeDone::Future(future))
}
impl<Fut: Future> MaybeDone<Fut> {
/// Returns an [`Option`] containing a mutable reference to the output of the future.
/// The output of this method will be [`Some`] if and only if the inner
/// future has been completed and [`take_output`](MaybeDone::take_output)
/// has not yet been called.
#[inline]
pub fn output_mut(self: Pin<&mut Self>) -> Option<&mut Fut::Output> {
unsafe {
match self.get_unchecked_mut() {
Self::Done(res) => Some(res),
_ => None,
}
}
}
/// Attempt to take the output of a `MaybeDone` without driving it
/// towards completion.
#[inline]
pub fn take_output(self: Pin<&mut Self>) -> Option<Fut::Output> {
match &*self {
Self::Done(_) => {}
Self::Future(_) | Self::Gone => return None,
}
unsafe {
match mem::replace(self.get_unchecked_mut(), Self::Gone) {
Self::Done(output) => Some(output),
_ => unreachable!(),
}
}
}
}
impl<Fut: Future> FusedFuture for MaybeDone<Fut> {
fn is_terminated(&self) -> bool {
match self {
Self::Future(_) => false,
Self::Done(_) | Self::Gone => true,
}
}
}
impl<Fut: Future> Future for MaybeDone<Fut> {
type Output = ();
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
unsafe {
match self.as_mut().get_unchecked_mut() {
Self::Future(f) => {
let res = ready!(Pin::new_unchecked(f).poll(cx));
self.set(Self::Done(res));
}
Self::Done(_) => {}
Self::Gone => panic!("MaybeDone polled after value taken"),
}
}
Poll::Ready(())
}
}

134
vendor/futures-util/src/future/mod.rs vendored Normal file
View File

@@ -0,0 +1,134 @@
//! Asynchronous values.
//!
//! This module contains:
//!
//! - The [`Future`] trait.
//! - The [`FutureExt`] and [`TryFutureExt`] trait, which provides adapters for
//! chaining and composing futures.
//! - Top-level future combinators like [`lazy`](lazy()) which creates a future
//! from a closure that defines its return value, and [`ready`](ready()),
//! which constructs a future with an immediate defined value.
#[doc(no_inline)]
pub use core::future::Future;
#[cfg(feature = "alloc")]
pub use futures_core::future::{BoxFuture, LocalBoxFuture};
pub use futures_core::future::{FusedFuture, TryFuture};
pub use futures_task::{FutureObj, LocalFutureObj, UnsafeFutureObj};
// Extension traits and combinators
#[allow(clippy::module_inception)]
mod future;
pub use self::future::{
Flatten, Fuse, FutureExt, Inspect, IntoStream, Map, MapInto, NeverError, Then, UnitError,
};
#[deprecated(note = "This is now an alias for [Flatten](Flatten)")]
pub use self::future::FlattenStream;
#[cfg(feature = "std")]
pub use self::future::CatchUnwind;
#[cfg(feature = "channel")]
#[cfg_attr(docsrs, doc(cfg(feature = "channel")))]
#[cfg(feature = "std")]
pub use self::future::{Remote, RemoteHandle};
#[cfg(any(feature = "std", all(feature = "alloc", feature = "spin")))]
pub use self::future::{Shared, WeakShared};
mod try_future;
pub use self::try_future::{
AndThen, ErrInto, InspectErr, InspectOk, IntoFuture, MapErr, MapOk, MapOkOrElse, OkInto,
OrElse, TryFlatten, TryFlattenStream, TryFutureExt, UnwrapOrElse,
};
#[cfg(feature = "sink")]
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
pub use self::try_future::FlattenSink;
// Primitive futures
mod lazy;
pub use self::lazy::{lazy, Lazy};
mod pending;
pub use self::pending::{pending, Pending};
mod maybe_done;
pub use self::maybe_done::{maybe_done, MaybeDone};
mod try_maybe_done;
pub use self::try_maybe_done::{try_maybe_done, TryMaybeDone};
mod option;
pub use self::option::OptionFuture;
mod poll_fn;
pub use self::poll_fn::{poll_fn, PollFn};
mod poll_immediate;
pub use self::poll_immediate::{poll_immediate, PollImmediate};
mod ready;
pub use self::ready::{err, ok, ready, Ready};
mod always_ready;
pub use self::always_ready::{always_ready, AlwaysReady};
mod join;
pub use self::join::{join, join3, join4, join5, Join, Join3, Join4, Join5};
#[cfg(feature = "alloc")]
mod join_all;
#[cfg(feature = "alloc")]
pub use self::join_all::{join_all, JoinAll};
mod select;
pub use self::select::{select, Select};
#[cfg(feature = "alloc")]
mod select_all;
#[cfg(feature = "alloc")]
pub use self::select_all::{select_all, SelectAll};
mod try_join;
pub use self::try_join::{
try_join, try_join3, try_join4, try_join5, TryJoin, TryJoin3, TryJoin4, TryJoin5,
};
#[cfg(feature = "alloc")]
mod try_join_all;
#[cfg(feature = "alloc")]
pub use self::try_join_all::{try_join_all, TryJoinAll};
mod try_select;
pub use self::try_select::{try_select, TrySelect};
#[cfg(feature = "alloc")]
mod select_ok;
#[cfg(feature = "alloc")]
pub use self::select_ok::{select_ok, SelectOk};
mod either;
pub use self::either::Either;
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
#[cfg(feature = "alloc")]
mod abortable;
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
#[cfg(feature = "alloc")]
pub use crate::abortable::{AbortHandle, AbortRegistration, Abortable, Aborted};
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
#[cfg(feature = "alloc")]
pub use abortable::abortable;
// Just a helper function to ensure the futures we're returning all have the
// right implementations.
pub(crate) fn assert_future<T, F>(future: F) -> F
where
F: Future<Output = T>,
{
future
}

View File

@@ -0,0 +1,64 @@
//! Definition of the `Option` (optional step) combinator
use core::pin::Pin;
use futures_core::future::{FusedFuture, Future};
use futures_core::task::{Context, Poll};
use pin_project_lite::pin_project;
pin_project! {
/// A future representing a value which may or may not be present.
///
/// Created by the [`From`] implementation for [`Option`](std::option::Option).
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::OptionFuture;
///
/// let mut a: OptionFuture<_> = Some(async { 123 }).into();
/// assert_eq!(a.await, Some(123));
///
/// a = None.into();
/// assert_eq!(a.await, None);
/// # });
/// ```
#[derive(Debug, Clone)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct OptionFuture<F> {
#[pin]
inner: Option<F>,
}
}
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> {
match self.project().inner.as_pin_mut() {
Some(x) => x.poll(cx).map(Some),
None => Poll::Ready(None),
}
}
}
impl<F: FusedFuture> FusedFuture for OptionFuture<F> {
fn is_terminated(&self) -> bool {
match &self.inner {
Some(x) => x.is_terminated(),
None => true,
}
}
}
impl<T> From<Option<T>> for OptionFuture<T> {
fn from(option: Option<T>) -> Self {
Self { inner: option }
}
}

View File

@@ -0,0 +1,55 @@
use super::assert_future;
use core::marker;
use core::pin::Pin;
use futures_core::future::{FusedFuture, Future};
use futures_core::task::{Context, Poll};
/// Future for the [`pending()`] function.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Pending<T> {
_data: marker::PhantomData<T>,
}
impl<T> FusedFuture for Pending<T> {
fn is_terminated(&self) -> bool {
true
}
}
/// Creates a future which never resolves, representing a computation that never
/// finishes.
///
/// The returned future will forever return [`Poll::Pending`].
///
/// # Examples
///
/// ```ignore
/// # futures::executor::block_on(async {
/// use futures::future;
///
/// let future = future::pending();
/// let () = future.await;
/// unreachable!();
/// # });
/// ```
#[cfg_attr(docsrs, doc(alias = "never"))]
pub fn pending<T>() -> Pending<T> {
assert_future::<T, _>(Pending { _data: marker::PhantomData })
}
impl<T> Future for Pending<T> {
type Output = T;
fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<T> {
Poll::Pending
}
}
impl<T> Unpin for Pending<T> {}
impl<T> Clone for Pending<T> {
fn clone(&self) -> Self {
pending()
}
}

View File

@@ -0,0 +1,58 @@
//! Definition of the `PollFn` adapter combinator
use super::assert_future;
use core::fmt;
use core::pin::Pin;
use futures_core::future::Future;
use futures_core::task::{Context, Poll};
/// Future for the [`poll_fn`] function.
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct PollFn<F> {
f: F,
}
impl<F> Unpin for PollFn<F> {}
/// Creates a new future wrapping around a function returning [`Poll`].
///
/// Polling the returned future delegates to the wrapped function.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::poll_fn;
/// use futures::task::{Context, Poll};
///
/// fn read_line(_cx: &mut Context<'_>) -> Poll<String> {
/// Poll::Ready("Hello, World!".into())
/// }
///
/// let read_future = poll_fn(read_line);
/// assert_eq!(read_future.await, "Hello, World!".to_owned());
/// # });
/// ```
pub fn poll_fn<T, F>(f: F) -> PollFn<F>
where
F: FnMut(&mut Context<'_>) -> Poll<T>,
{
assert_future::<T, _>(PollFn { f })
}
impl<F> fmt::Debug for PollFn<F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PollFn").finish()
}
}
impl<T, F> Future for PollFn<F>
where
F: FnMut(&mut Context<'_>) -> Poll<T>,
{
type Output = T;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
(&mut self.f)(cx)
}
}

View File

@@ -0,0 +1,131 @@
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 core::pin::pin;
///
/// use futures::task::Poll;
/// use futures::{StreamExt, future};
/// use future::FusedFuture;
///
/// let f = async { 1_u32 };
/// let f = pin!(f);
/// let mut r = future::poll_immediate(f);
/// assert_eq!(r.next().await, Some(Poll::Ready(1)));
///
/// let f = async {futures::pending!(); 42_u8};
/// let f = pin!(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 core::pin::pin;
///
/// use futures::future;
///
/// let f = async {futures::pending!(); 42_u8};
/// let mut f = pin!(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) })
}

82
vendor/futures-util/src/future/ready.rs vendored Normal file
View File

@@ -0,0 +1,82 @@
use super::assert_future;
use core::pin::Pin;
use futures_core::future::{FusedFuture, Future};
use futures_core::task::{Context, Poll};
/// Future for the [`ready`](ready()) function.
#[derive(Debug, Clone)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Ready<T>(Option<T>);
impl<T> Ready<T> {
/// Unwraps the value from this immediately ready future.
#[inline]
pub fn into_inner(mut self) -> T {
self.0.take().unwrap()
}
}
impl<T> Unpin for Ready<T> {}
impl<T> FusedFuture for Ready<T> {
fn is_terminated(&self) -> bool {
self.0.is_none()
}
}
impl<T> Future for Ready<T> {
type Output = T;
#[inline]
fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<T> {
Poll::Ready(self.0.take().expect("Ready polled after completion"))
}
}
/// Creates a future that is immediately ready with a value.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
///
/// let a = future::ready(1);
/// assert_eq!(a.await, 1);
/// # });
/// ```
pub fn ready<T>(t: T) -> Ready<T> {
assert_future::<T, _>(Ready(Some(t)))
}
/// Create a future that is immediately ready with a success value.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
///
/// let a = future::ok::<i32, i32>(1);
/// assert_eq!(a.await, Ok(1));
/// # });
/// ```
pub fn ok<T, E>(t: T) -> Ready<Result<T, E>> {
Ready(Some(Ok(t)))
}
/// Create a future that is immediately ready with an error value.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
///
/// let a = future::err::<i32, i32>(1);
/// assert_eq!(a.await, Err(1));
/// # });
/// ```
pub fn err<T, E>(err: E) -> Ready<Result<T, E>> {
Ready(Some(Err(err)))
}

133
vendor/futures-util/src/future/select.rs vendored Normal file
View File

@@ -0,0 +1,133 @@
use super::assert_future;
use crate::future::{Either, FutureExt};
use core::pin::Pin;
use futures_core::future::{FusedFuture, Future};
use futures_core::task::{Context, Poll};
/// Future for the [`select()`] function.
#[must_use = "futures do nothing unless you `.await` or poll them"]
#[derive(Debug)]
pub struct Select<A, B> {
inner: Option<(A, B)>,
}
impl<A: Unpin, B: Unpin> Unpin for Select<A, B> {}
/// Waits for either one of two differently-typed futures to complete.
///
/// This function will return a new future which awaits for either one of both
/// futures to complete. The returned future will finish with both the value
/// resolved and a future representing the completion of the other work.
///
/// Note that this function consumes the receiving futures and returns a
/// wrapped version of them.
///
/// Also note that if both this and the second future have the same
/// output type you can use the `Either::factor_first` method to
/// conveniently extract out the value at the end.
///
/// # Examples
///
/// A simple example
///
/// ```
/// # futures::executor::block_on(async {
/// use core::pin::pin;
///
/// use futures::future;
/// use futures::future::Either;
///
/// // These two futures have different types even though their outputs have the same type.
/// let future1 = async {
/// future::pending::<()>().await; // will never finish
/// 1
/// };
/// let future2 = async {
/// future::ready(2).await
/// };
///
/// // 'select' requires Future + Unpin bounds
/// let future1 = pin!(future1);
/// let future2 = pin!(future2);
///
/// let value = match future::select(future1, future2).await {
/// Either::Left((value1, _)) => value1, // `value1` is resolved from `future1`
/// // `_` represents `future2`
/// Either::Right((value2, _)) => value2, // `value2` is resolved from `future2`
/// // `_` represents `future1`
/// };
///
/// assert!(value == 2);
/// # });
/// ```
///
/// A more complex example
///
/// ```
/// use futures::future::{self, Either, Future, FutureExt};
///
/// // A poor-man's join implemented on top of select
///
/// fn join<A, B>(a: A, b: B) -> impl Future<Output=(A::Output, B::Output)>
/// where A: Future + Unpin,
/// B: Future + Unpin,
/// {
/// future::select(a, b).then(|either| {
/// match either {
/// Either::Left((x, b)) => b.map(move |y| (x, y)).left_future(),
/// Either::Right((y, a)) => a.map(move |x| (x, y)).right_future(),
/// }
/// })
/// }
/// ```
pub fn select<A, B>(future1: A, future2: B) -> Select<A, B>
where
A: Future + Unpin,
B: Future + Unpin,
{
assert_future::<Either<(A::Output, B), (B::Output, A)>, _>(Select {
inner: Some((future1, future2)),
})
}
impl<A, B> Future for Select<A, B>
where
A: Future + Unpin,
B: Future + Unpin,
{
type Output = Either<(A::Output, B), (B::Output, A)>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
/// When compiled with `-C opt-level=z`, this function will help the compiler eliminate the `None` branch, where
/// `Option::unwrap` does not.
#[inline(always)]
fn unwrap_option<T>(value: Option<T>) -> T {
match value {
None => unreachable!(),
Some(value) => value,
}
}
let (a, b) = self.inner.as_mut().expect("cannot poll Select twice");
if let Poll::Ready(val) = a.poll_unpin(cx) {
return Poll::Ready(Either::Left((val, unwrap_option(self.inner.take()).1)));
}
if let Poll::Ready(val) = b.poll_unpin(cx) {
return Poll::Ready(Either::Right((val, unwrap_option(self.inner.take()).0)));
}
Poll::Pending
}
}
impl<A, B> FusedFuture for Select<A, B>
where
A: Future + Unpin,
B: Future + Unpin,
{
fn is_terminated(&self) -> bool {
self.inner.is_none()
}
}

View File

@@ -0,0 +1,75 @@
use super::assert_future;
use crate::future::FutureExt;
use alloc::vec::Vec;
use core::iter::FromIterator;
use core::mem;
use core::pin::Pin;
use futures_core::future::Future;
use futures_core::task::{Context, Poll};
/// Future for the [`select_all`] function.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct SelectAll<Fut> {
inner: Vec<Fut>,
}
impl<Fut: Unpin> Unpin for SelectAll<Fut> {}
/// Creates a new future which will select over a list of futures.
///
/// The returned future will wait for any future within `iter` to be ready. Upon
/// completion the item resolved will be returned, along with the index of the
/// future that was ready and the list of all the remaining futures.
///
/// There are no guarantees provided on the order of the list with the remaining
/// futures. They might be swapped around, reversed, or completely random.
///
/// This function is only available when the `std` or `alloc` feature of this
/// library is activated, and it is activated by default.
///
/// # Panics
///
/// This function will panic if the iterator specified contains no items.
pub fn select_all<I>(iter: I) -> SelectAll<I::Item>
where
I: IntoIterator,
I::Item: Future + Unpin,
{
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)),
});
match item {
Some((idx, res)) => {
#[allow(clippy::let_underscore_future)]
let _ = self.inner.swap_remove(idx);
let rest = mem::take(&mut self.inner);
Poll::Ready((res, idx, rest))
}
None => Poll::Pending,
}
}
}
impl<Fut: Future + Unpin> FromIterator<Fut> for SelectAll<Fut> {
fn from_iter<T: IntoIterator<Item = Fut>>(iter: T) -> Self {
select_all(iter)
}
}

View File

@@ -0,0 +1,85 @@
use super::assert_future;
use crate::future::TryFutureExt;
use alloc::vec::Vec;
use core::iter::FromIterator;
use core::mem;
use core::pin::Pin;
use futures_core::future::{Future, TryFuture};
use futures_core::task::{Context, Poll};
/// Future for the [`select_ok`] function.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct SelectOk<Fut> {
inner: Vec<Fut>,
}
impl<Fut: Unpin> Unpin for SelectOk<Fut> {}
/// Creates a new future which will select the first successful future over a list of futures.
///
/// The returned future will wait for any future within `iter` to be ready and Ok. Unlike
/// `select_all`, this will only return the first successful completion, or the last
/// failure. This is useful in contexts where any success is desired and failures
/// are ignored, unless all the futures fail.
///
/// This function is only available when the `std` or `alloc` feature of this
/// library is activated, and it is activated by default.
///
/// # Panics
///
/// This function will panic if the iterator specified contains no items.
pub fn select_ok<I>(iter: I) -> SelectOk<I::Item>
where
I: IntoIterator,
I::Item: TryFuture + Unpin,
{
let ret = SelectOk { inner: iter.into_iter().collect() };
assert!(!ret.inner.is_empty(), "iterator provided to select_ok was empty");
assert_future::<
Result<(<I::Item as TryFuture>::Ok, Vec<I::Item>), <I::Item as TryFuture>::Error>,
_,
>(ret)
}
impl<Fut: TryFuture + Unpin> Future for SelectOk<Fut> {
type Output = Result<(Fut::Ok, Vec<Fut>), Fut::Error>;
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) {
Poll::Pending => None,
Poll::Ready(e) => Some((i, e)),
});
match item {
Some((idx, res)) => {
// always remove Ok or Err, if it's not the last Err continue looping
drop(self.inner.remove(idx));
match res {
Ok(e) => {
let rest = mem::take(&mut self.inner);
return Poll::Ready(Ok((e, rest)));
}
Err(e) => {
if self.inner.is_empty() {
return Poll::Ready(Err(e));
}
}
}
}
None => {
// based on the filter above, nothing is ready, return
return Poll::Pending;
}
}
}
}
}
impl<Fut: TryFuture + Unpin> FromIterator<Fut> for SelectOk<Fut> {
fn from_iter<T: IntoIterator<Item = Fut>>(iter: T) -> Self {
select_ok(iter)
}
}

View File

@@ -0,0 +1,36 @@
use core::pin::Pin;
use futures_core::future::{FusedFuture, Future, TryFuture};
use futures_core::task::{Context, Poll};
use pin_project_lite::pin_project;
pin_project! {
/// Future for the [`into_future`](super::TryFutureExt::into_future) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct IntoFuture<Fut> {
#[pin]
future: Fut,
}
}
impl<Fut> IntoFuture<Fut> {
#[inline]
pub(crate) fn new(future: Fut) -> Self {
Self { future }
}
}
impl<Fut: TryFuture + FusedFuture> FusedFuture for IntoFuture<Fut> {
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> {
self.project().future.try_poll(cx)
}
}

View File

@@ -0,0 +1,625 @@
//! Futures
//!
//! This module contains a number of functions for working with `Future`s,
//! including the `FutureExt` trait which adds methods to `Future` types.
#[cfg(feature = "compat")]
use crate::compat::Compat;
use core::pin::Pin;
use futures_core::{
future::TryFuture,
stream::TryStream,
task::{Context, Poll},
};
#[cfg(feature = "sink")]
use futures_sink::Sink;
use crate::fns::{
inspect_err_fn, inspect_ok_fn, into_fn, map_err_fn, map_ok_fn, map_ok_or_else_fn,
unwrap_or_else_fn, InspectErrFn, InspectOkFn, IntoFn, MapErrFn, MapOkFn, MapOkOrElseFn,
UnwrapOrElseFn,
};
use crate::future::{assert_future, Inspect, Map};
use crate::stream::assert_stream;
// Combinators
mod into_future;
mod try_flatten;
mod try_flatten_err;
delegate_all!(
/// Future for the [`try_flatten`](TryFutureExt::try_flatten) method.
TryFlatten<Fut1, Fut2>(
try_flatten::TryFlatten<Fut1, Fut2>
): Debug + Future + FusedFuture + New[|x: Fut1| try_flatten::TryFlatten::new(x)]
);
delegate_all!(
/// Future for the [`try_flatten_err`](TryFutureExt::try_flatten_err) method.
TryFlattenErr<Fut1, Fut2>(
try_flatten_err::TryFlattenErr<Fut1, Fut2>
): Debug + Future + FusedFuture + New[|x: Fut1| try_flatten_err::TryFlattenErr::new(x)]
);
delegate_all!(
/// Future for the [`try_flatten_stream`](TryFutureExt::try_flatten_stream) method.
TryFlattenStream<Fut>(
try_flatten::TryFlatten<Fut, Fut::Ok>
): Debug + Sink + Stream + FusedStream + New[|x: Fut| try_flatten::TryFlatten::new(x)]
where Fut: TryFuture
);
#[cfg(feature = "sink")]
delegate_all!(
/// Sink for the [`flatten_sink`](TryFutureExt::flatten_sink) method.
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
FlattenSink<Fut, Si>(
try_flatten::TryFlatten<Fut, Si>
): Debug + Sink + Stream + FusedStream + New[|x: Fut| try_flatten::TryFlatten::new(x)]
);
delegate_all!(
/// Future for the [`and_then`](TryFutureExt::and_then) method.
AndThen<Fut1, Fut2, F>(
TryFlatten<MapOk<Fut1, F>, Fut2>
): Debug + Future + FusedFuture + New[|x: Fut1, f: F| TryFlatten::new(MapOk::new(x, f))]
);
delegate_all!(
/// Future for the [`or_else`](TryFutureExt::or_else) method.
OrElse<Fut1, Fut2, F>(
TryFlattenErr<MapErr<Fut1, F>, Fut2>
): Debug + Future + FusedFuture + New[|x: Fut1, f: F| TryFlattenErr::new(MapErr::new(x, f))]
);
delegate_all!(
/// Future for the [`err_into`](TryFutureExt::err_into) method.
ErrInto<Fut, E>(
MapErr<Fut, IntoFn<E>>
): Debug + Future + FusedFuture + New[|x: Fut| MapErr::new(x, into_fn())]
);
delegate_all!(
/// Future for the [`ok_into`](TryFutureExt::ok_into) method.
OkInto<Fut, E>(
MapOk<Fut, IntoFn<E>>
): Debug + Future + FusedFuture + New[|x: Fut| MapOk::new(x, into_fn())]
);
delegate_all!(
/// Future for the [`inspect_ok`](super::TryFutureExt::inspect_ok) method.
InspectOk<Fut, F>(
Inspect<IntoFuture<Fut>, InspectOkFn<F>>
): Debug + Future + FusedFuture + New[|x: Fut, f: F| Inspect::new(IntoFuture::new(x), inspect_ok_fn(f))]
);
delegate_all!(
/// Future for the [`inspect_err`](super::TryFutureExt::inspect_err) method.
InspectErr<Fut, F>(
Inspect<IntoFuture<Fut>, InspectErrFn<F>>
): Debug + Future + FusedFuture + New[|x: Fut, f: F| Inspect::new(IntoFuture::new(x), inspect_err_fn(f))]
);
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
pub use self::into_future::IntoFuture;
delegate_all!(
/// Future for the [`map_ok`](TryFutureExt::map_ok) method.
MapOk<Fut, F>(
Map<IntoFuture<Fut>, MapOkFn<F>>
): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(IntoFuture::new(x), map_ok_fn(f))]
);
delegate_all!(
/// Future for the [`map_err`](TryFutureExt::map_err) method.
MapErr<Fut, F>(
Map<IntoFuture<Fut>, MapErrFn<F>>
): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(IntoFuture::new(x), map_err_fn(f))]
);
delegate_all!(
/// Future for the [`map_ok_or_else`](TryFutureExt::map_ok_or_else) method.
MapOkOrElse<Fut, F, G>(
Map<IntoFuture<Fut>, MapOkOrElseFn<F, G>>
): Debug + Future + FusedFuture + New[|x: Fut, f: F, g: G| Map::new(IntoFuture::new(x), map_ok_or_else_fn(f, g))]
);
delegate_all!(
/// Future for the [`unwrap_or_else`](TryFutureExt::unwrap_or_else) method.
UnwrapOrElse<Fut, F>(
Map<IntoFuture<Fut>, UnwrapOrElseFn<F>>
): Debug + Future + FusedFuture + New[|x: Fut, f: F| Map::new(IntoFuture::new(x), unwrap_or_else_fn(f))]
);
impl<Fut: ?Sized + TryFuture> TryFutureExt for Fut {}
/// Adapters specific to [`Result`]-returning futures
pub trait TryFutureExt: TryFuture {
/// Flattens the execution of this future when the successful result of this
/// future is a [`Sink`].
///
/// This can be useful when sink initialization is deferred, and it is
/// convenient to work with that sink as if the sink was available at the
/// call site.
///
/// Note that this function consumes this future and returns a wrapped
/// version of it.
///
/// # Examples
///
/// ```
/// use futures::future::{Future, TryFutureExt};
/// use futures::sink::Sink;
/// # use futures::channel::mpsc::{self, SendError};
/// # type T = i32;
/// # type E = SendError;
///
/// fn make_sink_async() -> impl Future<Output = Result<
/// impl Sink<T, Error = E>,
/// E,
/// >> { // ... }
/// # let (tx, _rx) = mpsc::unbounded::<i32>();
/// # futures::future::ready(Ok(tx))
/// # }
/// fn take_sink(sink: impl Sink<T, Error = E>) { /* ... */ }
///
/// let fut = make_sink_async();
/// take_sink(fut.flatten_sink())
/// ```
#[cfg(feature = "sink")]
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>
where
Self::Ok: Sink<Item, Error = Self::Error>,
Self: Sized,
{
crate::sink::assert_sink::<Item, Self::Error, _>(FlattenSink::new(self))
}
/// Maps this future's success value to a different value.
///
/// This method can be used to change the [`Ok`](TryFuture::Ok) type of the
/// future into a different type. It is similar to the [`Result::map`]
/// method. You can use this method to chain along a computation once the
/// future has been resolved.
///
/// The provided closure `f` will only be called if this future is resolved
/// to an [`Ok`]. If it resolves to an [`Err`], panics, or is dropped, then
/// the provided closure will never be invoked.
///
/// Note that this method consumes the future it is called on and returns a
/// wrapped version of it.
///
/// # Examples
///
/// ```
/// use futures::future::TryFutureExt;
///
/// # futures::executor::block_on(async {
/// let future = async { Ok::<i32, i32>(1) };
/// let future = future.map_ok(|x| x + 3);
/// assert_eq!(future.await, Ok(4));
/// # });
/// ```
///
/// Calling [`map_ok`](TryFutureExt::map_ok) on an errored future has no
/// effect:
///
/// ```
/// use futures::future::TryFutureExt;
///
/// # futures::executor::block_on(async {
/// let future = async { Err::<i32, i32>(1) };
/// let future = future.map_ok(|x| x + 3);
/// assert_eq!(future.await, Err(1));
/// # });
/// ```
fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where
F: FnOnce(Self::Ok) -> T,
Self: Sized,
{
assert_future::<Result<T, Self::Error>, _>(MapOk::new(self, f))
}
/// Maps this future's success value to a different value, and permits for error handling resulting in the same type.
///
/// This method can be used to coalesce your [`Ok`](TryFuture::Ok) type and [`Error`](TryFuture::Error) into another type,
/// where that type is the same for both outcomes.
///
/// The provided closure `f` will only be called if this future is resolved
/// to an [`Ok`]. If it resolves to an [`Err`], panics, or is dropped, then
/// the provided closure will never be invoked.
///
/// The provided closure `e` will only be called if this future is resolved
/// to an [`Err`]. If it resolves to an [`Ok`], panics, or is dropped, then
/// the provided closure will never be invoked.
///
/// Note that this method consumes the future it is called on and returns a
/// wrapped version of it.
///
/// # Examples
///
/// ```
/// use futures::future::TryFutureExt;
///
/// # futures::executor::block_on(async {
/// let future = async { Ok::<i32, i32>(5) };
/// let future = future.map_ok_or_else(|x| x * 2, |x| x + 3);
/// assert_eq!(future.await, 8);
///
/// let future = async { Err::<i32, i32>(5) };
/// let future = future.map_ok_or_else(|x| x * 2, |x| x + 3);
/// assert_eq!(future.await, 10);
/// # });
/// ```
///
fn map_ok_or_else<T, E, F>(self, e: E, f: F) -> MapOkOrElse<Self, F, E>
where
F: FnOnce(Self::Ok) -> T,
E: FnOnce(Self::Error) -> T,
Self: Sized,
{
assert_future::<T, _>(MapOkOrElse::new(self, f, e))
}
/// Maps this future's error value to a different value.
///
/// This method can be used to change the [`Error`](TryFuture::Error) type
/// of the future into a different type. It is similar to the
/// [`Result::map_err`] method. You can use this method for example to
/// ensure that futures have the same [`Error`](TryFuture::Error) type when
/// using [`select!`] or [`join!`].
///
/// The provided closure `f` will only be called if this future is resolved
/// to an [`Err`]. If it resolves to an [`Ok`], panics, or is dropped, then
/// the provided closure will never be invoked.
///
/// Note that this method consumes the future it is called on and returns a
/// wrapped version of it.
///
/// # Examples
///
/// ```
/// use futures::future::TryFutureExt;
///
/// # futures::executor::block_on(async {
/// let future = async { Err::<i32, i32>(1) };
/// let future = future.map_err(|x| x + 3);
/// assert_eq!(future.await, Err(4));
/// # });
/// ```
///
/// Calling [`map_err`](TryFutureExt::map_err) on a successful future has
/// no effect:
///
/// ```
/// use futures::future::TryFutureExt;
///
/// # futures::executor::block_on(async {
/// let future = async { Ok::<i32, i32>(1) };
/// let future = future.map_err(|x| x + 3);
/// assert_eq!(future.await, Ok(1));
/// # });
/// ```
///
/// [`join!`]: crate::join
/// [`select!`]: crate::select
fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where
F: FnOnce(Self::Error) -> E,
Self: Sized,
{
assert_future::<Result<Self::Ok, E>, _>(MapErr::new(self, f))
}
/// Maps this future's [`Error`](TryFuture::Error) to a new error type
/// using the [`Into`](std::convert::Into) trait.
///
/// This method does for futures what the `?`-operator does for
/// [`Result`]: It lets the compiler infer the type of the resulting
/// error. Just as [`map_err`](TryFutureExt::map_err), this is useful for
/// example to ensure that futures have the same [`Error`](TryFuture::Error)
/// type when using [`select!`] or [`join!`].
///
/// Note that this method consumes the future it is called on and returns a
/// wrapped version of it.
///
/// # Examples
///
/// ```
/// use futures::future::TryFutureExt;
///
/// # futures::executor::block_on(async {
/// let future_err_u8 = async { Err::<(), u8>(1) };
/// let future_err_i32 = future_err_u8.err_into::<i32>();
/// # });
/// ```
///
/// [`join!`]: crate::join
/// [`select!`]: crate::select
fn err_into<E>(self) -> ErrInto<Self, E>
where
Self: Sized,
Self::Error: Into<E>,
{
assert_future::<Result<Self::Ok, E>, _>(ErrInto::new(self))
}
/// Maps this future's [`Ok`](TryFuture::Ok) to a new type
/// using the [`Into`](std::convert::Into) trait.
fn ok_into<U>(self) -> OkInto<Self, U>
where
Self: Sized,
Self::Ok: Into<U>,
{
assert_future::<Result<U, Self::Error>, _>(OkInto::new(self))
}
/// Executes another future after this one resolves successfully. The
/// success value is passed to a closure to create this subsequent future.
///
/// The provided closure `f` will only be called if this future is resolved
/// to an [`Ok`]. If this future resolves to an [`Err`], panics, or is
/// dropped, then the provided closure will never be invoked. The
/// [`Error`](TryFuture::Error) type of this future and the future
/// returned by `f` have to match.
///
/// Note that this method consumes the future it is called on and returns a
/// wrapped version of it.
///
/// # Examples
///
/// ```
/// use futures::future::TryFutureExt;
///
/// # futures::executor::block_on(async {
/// let future = async { Ok::<i32, i32>(1) };
/// let future = future.and_then(|x| async move { Ok::<i32, i32>(x + 3) });
/// assert_eq!(future.await, Ok(4));
/// # });
/// ```
///
/// Calling [`and_then`](TryFutureExt::and_then) on an errored future has no
/// effect:
///
/// ```
/// use futures::future::TryFutureExt;
///
/// # futures::executor::block_on(async {
/// let future = async { Err::<i32, i32>(1) };
/// let future = future.and_then(|x| async move { Err::<i32, i32>(x + 3) });
/// assert_eq!(future.await, Err(1));
/// # });
/// ```
fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where
F: FnOnce(Self::Ok) -> Fut,
Fut: TryFuture<Error = Self::Error>,
Self: Sized,
{
assert_future::<Result<Fut::Ok, Fut::Error>, _>(AndThen::new(self, f))
}
/// Executes another future if this one resolves to an error. The
/// error value is passed to a closure to create this subsequent future.
///
/// The provided closure `f` will only be called if this future is resolved
/// to an [`Err`]. If this future resolves to an [`Ok`], panics, or is
/// dropped, then the provided closure will never be invoked. The
/// [`Ok`](TryFuture::Ok) type of this future and the future returned by `f`
/// have to match.
///
/// Note that this method consumes the future it is called on and returns a
/// wrapped version of it.
///
/// # Examples
///
/// ```
/// use futures::future::TryFutureExt;
///
/// # futures::executor::block_on(async {
/// let future = async { Err::<i32, i32>(1) };
/// let future = future.or_else(|x| async move { Err::<i32, i32>(x + 3) });
/// assert_eq!(future.await, Err(4));
/// # });
/// ```
///
/// Calling [`or_else`](TryFutureExt::or_else) on a successful future has
/// no effect:
///
/// ```
/// use futures::future::TryFutureExt;
///
/// # futures::executor::block_on(async {
/// let future = async { Ok::<i32, i32>(1) };
/// let future = future.or_else(|x| async move { Ok::<i32, i32>(x + 3) });
/// assert_eq!(future.await, Ok(1));
/// # });
/// ```
fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where
F: FnOnce(Self::Error) -> Fut,
Fut: TryFuture<Ok = Self::Ok>,
Self: Sized,
{
assert_future::<Result<Fut::Ok, Fut::Error>, _>(OrElse::new(self, f))
}
/// Do something with the success value of a future before passing it on.
///
/// When using futures, you'll often chain several of them together. While
/// working on such code, you might want to check out what's happening at
/// various parts in the pipeline, without consuming the intermediate
/// value. To do that, insert a call to `inspect_ok`.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::TryFutureExt;
///
/// let future = async { Ok::<_, ()>(1) };
/// let new_future = future.inspect_ok(|&x| println!("about to resolve: {}", x));
/// assert_eq!(new_future.await, Ok(1));
/// # });
/// ```
fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where
F: FnOnce(&Self::Ok),
Self: Sized,
{
assert_future::<Result<Self::Ok, Self::Error>, _>(InspectOk::new(self, f))
}
/// Do something with the error value of a future before passing it on.
///
/// When using futures, you'll often chain several of them together. While
/// working on such code, you might want to check out what's happening at
/// various parts in the pipeline, without consuming the intermediate
/// value. To do that, insert a call to `inspect_err`.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::TryFutureExt;
///
/// let future = async { Err::<(), _>(1) };
/// let new_future = future.inspect_err(|&x| println!("about to error: {}", x));
/// assert_eq!(new_future.await, Err(1));
/// # });
/// ```
fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where
F: FnOnce(&Self::Error),
Self: Sized,
{
assert_future::<Result<Self::Ok, Self::Error>, _>(InspectErr::new(self, f))
}
/// Flatten the execution of this future when the successful result of this
/// future is another future.
///
/// This is equivalent to `future.and_then(|x| x)`.
fn try_flatten(self) -> TryFlatten<Self, Self::Ok>
where
Self::Ok: TryFuture<Error = Self::Error>,
Self: Sized,
{
assert_future::<Result<<Self::Ok as TryFuture>::Ok, Self::Error>, _>(TryFlatten::new(self))
}
/// Flatten the execution of this future when the successful result of this
/// future is a stream.
///
/// This can be useful when stream initialization is deferred, and it is
/// convenient to work with that stream as if stream was available at the
/// call site.
///
/// Note that this function consumes this future and returns a wrapped
/// version of it.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::TryFutureExt;
/// use futures::stream::{self, TryStreamExt};
///
/// let stream_items = vec![17, 18, 19].into_iter().map(Ok);
/// let future_of_a_stream = async { Ok::<_, ()>(stream::iter(stream_items)) };
///
/// let stream = future_of_a_stream.try_flatten_stream();
/// let list = stream.try_collect::<Vec<_>>().await;
/// assert_eq!(list, Ok(vec![17, 18, 19]));
/// # });
/// ```
fn try_flatten_stream(self) -> TryFlattenStream<Self>
where
Self::Ok: TryStream<Error = Self::Error>,
Self: Sized,
{
assert_stream::<Result<<Self::Ok as TryStream>::Ok, Self::Error>, _>(TryFlattenStream::new(
self,
))
}
/// Unwraps this future's output, producing a future with this future's
/// [`Ok`](TryFuture::Ok) type as its
/// [`Output`](std::future::Future::Output) type.
///
/// If this future is resolved successfully, the returned future will
/// contain the original future's success value as output. Otherwise, the
/// closure `f` is called with the error value to produce an alternate
/// success value.
///
/// This method is similar to the [`Result::unwrap_or_else`] method.
///
/// # Examples
///
/// ```
/// use futures::future::TryFutureExt;
///
/// # futures::executor::block_on(async {
/// let future = async { Err::<(), &str>("Boom!") };
/// let future = future.unwrap_or_else(|_| ());
/// assert_eq!(future.await, ());
/// # });
/// ```
fn unwrap_or_else<F>(self, f: F) -> UnwrapOrElse<Self, F>
where
Self: Sized,
F: FnOnce(Self::Error) -> Self::Ok,
{
assert_future::<Self::Ok, _>(UnwrapOrElse::new(self, f))
}
/// Wraps a [`TryFuture`] into a future compatible with libraries using
/// futures 0.1 future definitions. Requires the `compat` feature to enable.
#[cfg(feature = "compat")]
#[cfg_attr(docsrs, doc(cfg(feature = "compat")))]
fn compat(self) -> Compat<Self>
where
Self: Sized + Unpin,
{
Compat::new(self)
}
/// Wraps a [`TryFuture`] into a type that implements
/// [`Future`](std::future::Future).
///
/// [`TryFuture`]s currently do not implement the
/// [`Future`](std::future::Future) trait due to limitations of the
/// compiler.
///
/// # Examples
///
/// ```
/// use futures::future::{Future, TryFuture, TryFutureExt};
///
/// # type T = i32;
/// # type E = ();
/// fn make_try_future() -> impl TryFuture<Ok = T, Error = E> { // ... }
/// # async { Ok::<i32, ()>(1) }
/// # }
/// fn take_future(future: impl Future<Output = Result<T, E>>) { /* ... */ }
///
/// take_future(make_try_future().into_future());
/// ```
fn into_future(self) -> IntoFuture<Self>
where
Self: Sized,
{
assert_future::<Result<Self::Ok, Self::Error>, _>(IntoFuture::new(self))
}
/// A convenience method for calling [`TryFuture::try_poll`] on [`Unpin`]
/// future types.
fn try_poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Result<Self::Ok, Self::Error>>
where
Self: Unpin,
{
Pin::new(self).try_poll(cx)
}
}

View File

@@ -0,0 +1,162 @@
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 pin_project_lite::pin_project;
pin_project! {
#[project = TryFlattenProj]
#[derive(Debug)]
pub enum TryFlatten<Fut1, Fut2> {
First { #[pin] f: Fut1 },
Second { #[pin] f: Fut2 },
Empty,
}
}
impl<Fut1, Fut2> TryFlatten<Fut1, Fut2> {
pub(crate) fn new(future: Fut1) -> Self {
Self::First { f: future }
}
}
impl<Fut> FusedFuture for TryFlatten<Fut, Fut::Ok>
where
Fut: TryFuture,
Fut::Ok: TryFuture<Error = Fut::Error>,
{
fn is_terminated(&self) -> bool {
match self {
Self::Empty => true,
_ => false,
}
}
}
impl<Fut> Future for TryFlatten<Fut, Fut::Ok>
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::Second { f } => {
let output = ready!(f.try_poll(cx));
self.set(Self::Empty);
break output;
}
TryFlattenProj::Empty => panic!("TryFlatten polled after completion"),
}
})
}
}
impl<Fut> FusedStream for TryFlatten<Fut, Fut::Ok>
where
Fut: TryFuture,
Fut::Ok: TryStream<Error = Fut::Error>,
{
fn is_terminated(&self) -> bool {
match self {
Self::Empty => true,
_ => false,
}
}
}
impl<Fut> Stream for TryFlatten<Fut, Fut::Ok>
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::Second { f } => {
let output = ready!(f.try_poll_next(cx));
if output.is_none() {
self.set(Self::Empty);
}
break output;
}
TryFlattenProj::Empty => break None,
}
})
}
}
#[cfg(feature = "sink")]
impl<Fut, Item> Sink<Item> for TryFlatten<Fut, Fut::Ok>
where
Fut: TryFuture,
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>> {
Poll::Ready(loop {
match self.as_mut().project() {
TryFlattenProj::First { f } => match ready!(f.try_poll(cx)) {
Ok(f) => self.set(Self::Second { f }),
Err(e) => {
self.set(Self::Empty);
break Err(e);
}
},
TryFlattenProj::Second { f } => {
break ready!(f.poll_ready(cx));
}
TryFlattenProj::Empty => panic!("poll_ready called after eof"),
}
})
}
fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
match self.project() {
TryFlattenProj::First { .. } => panic!("poll_ready not called first"),
TryFlattenProj::Second { f } => f.start_send(item),
TryFlattenProj::Empty => panic!("start_send called after eof"),
}
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
match self.project() {
TryFlattenProj::First { .. } => Poll::Ready(Ok(())),
TryFlattenProj::Second { f } => f.poll_flush(cx),
TryFlattenProj::Empty => panic!("poll_flush called after eof"),
}
}
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
let res = match self.as_mut().project() {
TryFlattenProj::Second { f } => f.poll_close(cx),
_ => Poll::Ready(Ok(())),
};
if res.is_ready() {
self.set(Self::Empty);
}
res
}
}

View File

@@ -0,0 +1,62 @@
use core::pin::Pin;
use futures_core::future::{FusedFuture, Future, TryFuture};
use futures_core::ready;
use futures_core::task::{Context, Poll};
use pin_project_lite::pin_project;
pin_project! {
#[project = TryFlattenErrProj]
#[derive(Debug)]
pub enum TryFlattenErr<Fut1, Fut2> {
First { #[pin] f: Fut1 },
Second { #[pin] f: Fut2 },
Empty,
}
}
impl<Fut1, Fut2> TryFlattenErr<Fut1, Fut2> {
pub(crate) fn new(future: Fut1) -> Self {
Self::First { f: future }
}
}
impl<Fut> FusedFuture for TryFlattenErr<Fut, Fut::Error>
where
Fut: TryFuture,
Fut::Error: TryFuture<Ok = Fut::Ok>,
{
fn is_terminated(&self) -> bool {
match self {
Self::Empty => true,
_ => false,
}
}
}
impl<Fut> Future for TryFlattenErr<Fut, Fut::Error>
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::Second { f } => {
let output = ready!(f.try_poll(cx));
self.set(Self::Empty);
break output;
}
TryFlattenErrProj::Empty => panic!("TryFlattenErr polled after completion"),
}
})
}
}

View File

@@ -0,0 +1,256 @@
#![allow(non_snake_case)]
use crate::future::{assert_future, try_maybe_done, TryMaybeDone};
use core::fmt;
use core::pin::Pin;
use futures_core::future::{Future, TryFuture};
use futures_core::task::{Context, Poll};
use pin_project_lite::pin_project;
macro_rules! generate {
($(
$(#[$doc:meta])*
($Join:ident, <Fut1, $($Fut:ident),*>),
)*) => ($(
pin_project! {
$(#[$doc])*
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct $Join<Fut1: TryFuture, $($Fut: TryFuture),*> {
#[pin] Fut1: TryMaybeDone<Fut1>,
$(#[pin] $Fut: TryMaybeDone<$Fut>,)*
}
}
impl<Fut1, $($Fut),*> fmt::Debug for $Join<Fut1, $($Fut),*>
where
Fut1: TryFuture + fmt::Debug,
Fut1::Ok: fmt::Debug,
Fut1::Error: fmt::Debug,
$(
$Fut: TryFuture + fmt::Debug,
$Fut::Ok: fmt::Debug,
$Fut::Error: fmt::Debug,
)*
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct(stringify!($Join))
.field("Fut1", &self.Fut1)
$(.field(stringify!($Fut), &self.$Fut))*
.finish()
}
}
impl<Fut1, $($Fut),*> $Join<Fut1, $($Fut),*>
where
Fut1: TryFuture,
$(
$Fut: TryFuture<Error=Fut1::Error>
),*
{
fn new(Fut1: Fut1, $($Fut: $Fut),*) -> Self {
Self {
Fut1: try_maybe_done(Fut1),
$($Fut: try_maybe_done($Fut)),*
}
}
}
impl<Fut1, $($Fut),*> Future for $Join<Fut1, $($Fut),*>
where
Fut1: TryFuture,
$(
$Fut: TryFuture<Error=Fut1::Error>
),*
{
type Output = Result<(Fut1::Ok, $($Fut::Ok),*), Fut1::Error>;
fn poll(
self: Pin<&mut Self>, cx: &mut Context<'_>
) -> Poll<Self::Output> {
let mut all_done = true;
let mut futures = self.project();
all_done &= futures.Fut1.as_mut().poll(cx)?.is_ready();
$(
all_done &= futures.$Fut.as_mut().poll(cx)?.is_ready();
)*
if all_done {
Poll::Ready(Ok((
futures.Fut1.take_output().unwrap(),
$(
futures.$Fut.take_output().unwrap()
),*
)))
} else {
Poll::Pending
}
}
}
)*)
}
generate! {
/// Future for the [`try_join`](try_join()) function.
(TryJoin, <Fut1, Fut2>),
/// Future for the [`try_join3`] function.
(TryJoin3, <Fut1, Fut2, Fut3>),
/// Future for the [`try_join4`] function.
(TryJoin4, <Fut1, Fut2, Fut3, Fut4>),
/// Future for the [`try_join5`] function.
(TryJoin5, <Fut1, Fut2, Fut3, Fut4, Fut5>),
}
/// Joins the result of two futures, waiting for them both to complete or
/// for one to produce an error.
///
/// This function will return a new future which awaits both futures to
/// complete. If successful, the returned future will finish with a tuple of
/// both results. If unsuccessful, it will complete with the first error
/// encountered.
///
/// Note that this function consumes the passed futures and returns a
/// wrapped version of it.
///
/// # Examples
///
/// When used on multiple futures that return [`Ok`], `try_join` will return
/// [`Ok`] of a tuple of the values:
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
///
/// let a = future::ready(Ok::<i32, i32>(1));
/// let b = future::ready(Ok::<i32, i32>(2));
/// let pair = future::try_join(a, b);
///
/// assert_eq!(pair.await, Ok((1, 2)));
/// # });
/// ```
///
/// If one of the futures resolves to an error, `try_join` will return
/// that error:
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
///
/// let a = future::ready(Ok::<i32, i32>(1));
/// let b = future::ready(Err::<i32, i32>(2));
/// let pair = future::try_join(a, b);
///
/// assert_eq!(pair.await, Err(2));
/// # });
/// ```
pub fn try_join<Fut1, Fut2>(future1: Fut1, future2: Fut2) -> TryJoin<Fut1, Fut2>
where
Fut1: TryFuture,
Fut2: TryFuture<Error = Fut1::Error>,
{
assert_future::<Result<(Fut1::Ok, Fut2::Ok), Fut1::Error>, _>(TryJoin::new(future1, future2))
}
/// Same as [`try_join`](try_join()), but with more futures.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
///
/// let a = future::ready(Ok::<i32, i32>(1));
/// let b = future::ready(Ok::<i32, i32>(2));
/// let c = future::ready(Ok::<i32, i32>(3));
/// let tuple = future::try_join3(a, b, c);
///
/// assert_eq!(tuple.await, Ok((1, 2, 3)));
/// # });
/// ```
pub fn try_join3<Fut1, Fut2, Fut3>(
future1: Fut1,
future2: Fut2,
future3: Fut3,
) -> TryJoin3<Fut1, Fut2, Fut3>
where
Fut1: TryFuture,
Fut2: TryFuture<Error = Fut1::Error>,
Fut3: TryFuture<Error = Fut1::Error>,
{
assert_future::<Result<(Fut1::Ok, Fut2::Ok, Fut3::Ok), Fut1::Error>, _>(TryJoin3::new(
future1, future2, future3,
))
}
/// Same as [`try_join`](try_join()), but with more futures.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
///
/// let a = future::ready(Ok::<i32, i32>(1));
/// let b = future::ready(Ok::<i32, i32>(2));
/// let c = future::ready(Ok::<i32, i32>(3));
/// let d = future::ready(Ok::<i32, i32>(4));
/// let tuple = future::try_join4(a, b, c, d);
///
/// assert_eq!(tuple.await, Ok((1, 2, 3, 4)));
/// # });
/// ```
pub fn try_join4<Fut1, Fut2, Fut3, Fut4>(
future1: Fut1,
future2: Fut2,
future3: Fut3,
future4: Fut4,
) -> TryJoin4<Fut1, Fut2, Fut3, Fut4>
where
Fut1: TryFuture,
Fut2: TryFuture<Error = Fut1::Error>,
Fut3: TryFuture<Error = Fut1::Error>,
Fut4: TryFuture<Error = Fut1::Error>,
{
assert_future::<Result<(Fut1::Ok, Fut2::Ok, Fut3::Ok, Fut4::Ok), Fut1::Error>, _>(
TryJoin4::new(future1, future2, future3, future4),
)
}
/// Same as [`try_join`](try_join()), but with more futures.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future;
///
/// let a = future::ready(Ok::<i32, i32>(1));
/// let b = future::ready(Ok::<i32, i32>(2));
/// let c = future::ready(Ok::<i32, i32>(3));
/// let d = future::ready(Ok::<i32, i32>(4));
/// let e = future::ready(Ok::<i32, i32>(5));
/// let tuple = future::try_join5(a, b, c, d, e);
///
/// assert_eq!(tuple.await, Ok((1, 2, 3, 4, 5)));
/// # });
/// ```
pub fn try_join5<Fut1, Fut2, Fut3, Fut4, Fut5>(
future1: Fut1,
future2: Fut2,
future3: Fut3,
future4: Fut4,
future5: Fut5,
) -> TryJoin5<Fut1, Fut2, Fut3, Fut4, Fut5>
where
Fut1: TryFuture,
Fut2: TryFuture<Error = Fut1::Error>,
Fut3: TryFuture<Error = Fut1::Error>,
Fut4: TryFuture<Error = Fut1::Error>,
Fut5: TryFuture<Error = Fut1::Error>,
{
assert_future::<Result<(Fut1::Ok, Fut2::Ok, Fut3::Ok, Fut4::Ok, Fut5::Ok), Fut1::Error>, _>(
TryJoin5::new(future1, future2, future3, future4, future5),
)
}

View File

@@ -0,0 +1,201 @@
//! Definition of the `TryJoinAll` combinator, waiting for all of a list of
//! futures to finish with either success or error.
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::fmt;
use core::future::Future;
use core::iter::FromIterator;
use core::mem;
use core::pin::Pin;
use core::task::{Context, Poll};
use super::{assert_future, join_all, IntoFuture, TryFuture, TryMaybeDone};
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
use crate::stream::{FuturesOrdered, TryCollect, TryStreamExt};
use crate::TryFutureExt;
enum FinalState<E = ()> {
Pending,
AllDone,
Error(E),
}
/// Future for the [`try_join_all`] function.
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct TryJoinAll<F>
where
F: TryFuture,
{
kind: TryJoinAllKind<F>,
}
enum TryJoinAllKind<F>
where
F: TryFuture,
{
Small {
elems: Pin<Box<[TryMaybeDone<IntoFuture<F>>]>>,
},
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
Big {
fut: TryCollect<FuturesOrdered<IntoFuture<F>>, Vec<F::Ok>>,
},
}
impl<F> fmt::Debug for TryJoinAll<F>
where
F: TryFuture + fmt::Debug,
F::Ok: fmt::Debug,
F::Error: fmt::Debug,
F::Output: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.kind {
TryJoinAllKind::Small { ref elems } => {
f.debug_struct("TryJoinAll").field("elems", elems).finish()
}
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
TryJoinAllKind::Big { ref fut, .. } => fmt::Debug::fmt(fut, f),
}
}
}
/// Creates a future which represents either a collection of the results of the
/// futures given or an error.
///
/// The returned future will drive execution for all of its underlying futures,
/// collecting the results into a destination `Vec<T>` in the same order as they
/// were provided.
///
/// If any future returns an error then all other futures will be canceled and
/// an error will be returned immediately. If all futures complete successfully,
/// however, then the returned future will succeed with a `Vec` of all the
/// successful results.
///
/// This function is only available when the `std` or `alloc` feature of this
/// library is activated, and it is activated by default.
///
/// # See Also
///
/// `try_join_all` will switch to the more powerful [`FuturesOrdered`] for performance
/// reasons if the number of futures is large. You may want to look into using it or
/// it's counterpart [`FuturesUnordered`][crate::stream::FuturesUnordered] directly.
///
/// Some examples for additional functionality provided by these are:
///
/// * Adding new futures to the set even after it has been started.
///
/// * Only polling the specific futures that have been woken. In cases where
/// you have a lot of futures this will result in much more efficient polling.
///
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::future::{self, try_join_all};
///
/// let futures = vec![
/// future::ok::<u32, u32>(1),
/// future::ok::<u32, u32>(2),
/// future::ok::<u32, u32>(3),
/// ];
///
/// assert_eq!(try_join_all(futures).await, Ok(vec![1, 2, 3]));
///
/// let futures = vec![
/// future::ok::<u32, u32>(1),
/// future::err::<u32, u32>(2),
/// future::ok::<u32, u32>(3),
/// ];
///
/// assert_eq!(try_join_all(futures).await, Err(2));
/// # });
/// ```
pub fn try_join_all<I>(iter: I) -> TryJoinAll<I::Item>
where
I: IntoIterator,
I::Item: TryFuture,
{
let iter = iter.into_iter().map(TryFutureExt::into_future);
#[cfg(target_os = "none")]
#[cfg_attr(target_os = "none", cfg(not(target_has_atomic = "ptr")))]
{
let kind = TryJoinAllKind::Small {
elems: iter.map(TryMaybeDone::Future).collect::<Box<[_]>>().into(),
};
assert_future::<Result<Vec<<I::Item as TryFuture>::Ok>, <I::Item as TryFuture>::Error>, _>(
TryJoinAll { kind },
)
}
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
{
let kind = match iter.size_hint().1 {
Some(max) if max <= join_all::SMALL => TryJoinAllKind::Small {
elems: iter.map(TryMaybeDone::Future).collect::<Box<[_]>>().into(),
},
_ => TryJoinAllKind::Big { fut: iter.collect::<FuturesOrdered<_>>().try_collect() },
};
assert_future::<Result<Vec<<I::Item as TryFuture>::Ok>, <I::Item as TryFuture>::Error>, _>(
TryJoinAll { kind },
)
}
}
impl<F> Future for TryJoinAll<F>
where
F: TryFuture,
{
type Output = Result<Vec<F::Ok>, F::Error>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match &mut self.kind {
TryJoinAllKind::Small { elems } => {
let mut state = FinalState::AllDone;
for elem in join_all::iter_pin_mut(elems.as_mut()) {
match elem.try_poll(cx) {
Poll::Pending => state = FinalState::Pending,
Poll::Ready(Ok(())) => {}
Poll::Ready(Err(e)) => {
state = FinalState::Error(e);
break;
}
}
}
match state {
FinalState::Pending => Poll::Pending,
FinalState::AllDone => {
let mut elems = mem::replace(elems, Box::pin([]));
let results = join_all::iter_pin_mut(elems.as_mut())
.map(|e| e.take_output().unwrap())
.collect();
Poll::Ready(Ok(results))
}
FinalState::Error(e) => {
let _ = mem::replace(elems, Box::pin([]));
Poll::Ready(Err(e))
}
}
}
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
TryJoinAllKind::Big { fut } => Pin::new(fut).poll(cx),
}
}
}
impl<F> FromIterator<F> for TryJoinAll<F>
where
F: TryFuture,
{
fn from_iter<T: IntoIterator<Item = F>>(iter: T) -> Self {
try_join_all(iter)
}
}

View File

@@ -0,0 +1,92 @@
//! Definition of the TryMaybeDone combinator
use super::assert_future;
use core::mem;
use core::pin::Pin;
use futures_core::future::{FusedFuture, Future, TryFuture};
use futures_core::ready;
use futures_core::task::{Context, Poll};
/// A future that may have completed with an error.
///
/// This is created by the [`try_maybe_done()`] function.
#[derive(Debug)]
pub enum TryMaybeDone<Fut: TryFuture> {
/// A not-yet-completed future
Future(/* #[pin] */ Fut),
/// The output of the completed future
Done(Fut::Ok),
/// The empty variant after the result of a [`TryMaybeDone`] has been
/// taken using the [`take_output`](TryMaybeDone::take_output) method,
/// or if the future returned an error.
Gone,
}
impl<Fut: TryFuture + Unpin> Unpin for TryMaybeDone<Fut> {}
/// Wraps a future into a `TryMaybeDone`
pub fn try_maybe_done<Fut: TryFuture>(future: Fut) -> TryMaybeDone<Fut> {
assert_future::<Result<(), Fut::Error>, _>(TryMaybeDone::Future(future))
}
impl<Fut: TryFuture> TryMaybeDone<Fut> {
/// Returns an [`Option`] containing a mutable reference to the output of the future.
/// The output of this method will be [`Some`] if and only if the inner
/// future has completed successfully and [`take_output`](TryMaybeDone::take_output)
/// has not yet been called.
#[inline]
pub fn output_mut(self: Pin<&mut Self>) -> Option<&mut Fut::Ok> {
unsafe {
match self.get_unchecked_mut() {
Self::Done(res) => Some(res),
_ => None,
}
}
}
/// Attempt to take the output of a `TryMaybeDone` without driving it
/// towards completion.
#[inline]
pub fn take_output(self: Pin<&mut Self>) -> Option<Fut::Ok> {
match &*self {
Self::Done(_) => {}
Self::Future(_) | Self::Gone => return None,
}
unsafe {
match mem::replace(self.get_unchecked_mut(), Self::Gone) {
Self::Done(output) => Some(output),
_ => unreachable!(),
}
}
}
}
impl<Fut: TryFuture> FusedFuture for TryMaybeDone<Fut> {
fn is_terminated(&self) -> bool {
match self {
Self::Future(_) => false,
Self::Done(_) | Self::Gone => true,
}
}
}
impl<Fut: TryFuture> Future for TryMaybeDone<Fut> {
type Output = Result<(), Fut::Error>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
unsafe {
match self.as_mut().get_unchecked_mut() {
Self::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));
}
},
Self::Done(_) => {}
Self::Gone => panic!("TryMaybeDone polled after value taken"),
}
}
Poll::Ready(Ok(()))
}
}

View File

@@ -0,0 +1,85 @@
use crate::future::{Either, TryFutureExt};
use core::pin::Pin;
use futures_core::future::{Future, TryFuture};
use futures_core::task::{Context, Poll};
/// Future for the [`try_select()`] function.
#[must_use = "futures do nothing unless you `.await` or poll them"]
#[derive(Debug)]
pub struct TrySelect<A, B> {
inner: Option<(A, B)>,
}
impl<A: Unpin, B: Unpin> Unpin for TrySelect<A, B> {}
type EitherOk<A, B> = Either<(<A as TryFuture>::Ok, B), (<B as TryFuture>::Ok, A)>;
type EitherErr<A, B> = Either<(<A as TryFuture>::Error, B), (<B as TryFuture>::Error, A)>;
/// Waits for either one of two differently-typed futures to complete.
///
/// This function will return a new future which awaits for either one of both
/// futures to complete. The returned future will finish with both the value
/// resolved and a future representing the completion of the other work.
///
/// Note that this function consumes the receiving futures and returns a
/// wrapped version of them.
///
/// Also note that if both this and the second future have the same
/// success/error type you can use the `Either::factor_first` method to
/// conveniently extract out the value at the end.
///
/// # Examples
///
/// ```
/// use futures::future::{self, Either, Future, FutureExt, TryFuture, TryFutureExt};
///
/// // A poor-man's try_join implemented on top of select
///
/// fn try_join<A, B, E>(a: A, b: B) -> impl TryFuture<Ok=(A::Ok, B::Ok), Error=E>
/// where A: TryFuture<Error = E> + Unpin + 'static,
/// B: TryFuture<Error = E> + Unpin + 'static,
/// E: 'static,
/// {
/// future::try_select(a, b).then(|res| -> Box<dyn Future<Output = Result<_, _>> + Unpin> {
/// match res {
/// Ok(Either::Left((x, b))) => Box::new(b.map_ok(move |y| (x, y))),
/// Ok(Either::Right((y, a))) => Box::new(a.map_ok(move |x| (x, y))),
/// Err(Either::Left((e, _))) => Box::new(future::err(e)),
/// Err(Either::Right((e, _))) => Box::new(future::err(e)),
/// }
/// })
/// }
/// ```
pub fn try_select<A, B>(future1: A, future2: B) -> TrySelect<A, B>
where
A: TryFuture + Unpin,
B: TryFuture + Unpin,
{
super::assert_future::<Result<EitherOk<A, B>, EitherErr<A, B>>, _>(TrySelect {
inner: Some((future1, future2)),
})
}
impl<A: Unpin, B: Unpin> Future for TrySelect<A, B>
where
A: TryFuture,
B: TryFuture,
{
type Output = Result<EitherOk<A, B>, EitherErr<A, B>>;
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");
match a.try_poll_unpin(cx) {
Poll::Ready(Err(x)) => Poll::Ready(Err(Either::Left((x, b)))),
Poll::Ready(Ok(x)) => Poll::Ready(Ok(Either::Left((x, b)))),
Poll::Pending => match b.try_poll_unpin(cx) {
Poll::Ready(Err(x)) => Poll::Ready(Err(Either::Right((x, a)))),
Poll::Ready(Ok(x)) => Poll::Ready(Ok(Either::Right((x, a)))),
Poll::Pending => {
self.inner = Some((a, b));
Poll::Pending
}
},
}
}
}

202
vendor/futures-util/src/io/allow_std.rs vendored Normal file
View File

@@ -0,0 +1,202 @@
use futures_core::task::{Context, Poll};
use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, SeekFrom};
use std::pin::Pin;
use std::string::String;
use std::vec::Vec;
use std::{fmt, io};
/// A simple wrapper type which allows types which implement only
/// implement `std::io::Read` or `std::io::Write`
/// to be used in contexts which expect an `AsyncRead` or `AsyncWrite`.
///
/// If these types issue an error with the kind `io::ErrorKind::WouldBlock`,
/// it is expected that they will notify the current task on readiness.
/// Synchronous `std` types should not issue errors of this kind and
/// are safe to use in this context. However, using these types with
/// `AllowStdIo` will cause the event loop to block, so they should be used
/// with care.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct AllowStdIo<T>(T);
impl<T> Unpin for AllowStdIo<T> {}
macro_rules! try_with_interrupt {
($e:expr) => {
loop {
match $e {
Ok(e) => {
break e;
}
Err(ref e) if e.kind() == ::std::io::ErrorKind::Interrupted => {
continue;
}
Err(e) => {
return Poll::Ready(Err(e));
}
}
}
};
}
impl<T> AllowStdIo<T> {
/// Creates a new `AllowStdIo` from an existing IO object.
pub fn new(io: T) -> Self {
Self(io)
}
/// Returns a reference to the contained IO object.
pub fn get_ref(&self) -> &T {
&self.0
}
/// Returns a mutable reference to the contained IO object.
pub fn get_mut(&mut self) -> &mut T {
&mut self.0
}
/// Consumes self and returns the contained IO object.
pub fn into_inner(self) -> T {
self.0
}
}
impl<T> io::Write for AllowStdIo<T>
where
T: io::Write,
{
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
}
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
self.0.write_vectored(bufs)
}
fn flush(&mut self) -> io::Result<()> {
self.0.flush()
}
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.0.write_all(buf)
}
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
self.0.write_fmt(fmt)
}
}
impl<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>> {
Poll::Ready(Ok(try_with_interrupt!(self.0.write_vectored(bufs))))
}
fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
try_with_interrupt!(self.0.flush());
Poll::Ready(Ok(()))
}
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.poll_flush(cx)
}
}
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)
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
self.0.read_to_end(buf)
}
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
self.0.read_to_string(buf)
}
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
self.0.read_exact(buf)
}
}
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>> {
Poll::Ready(Ok(try_with_interrupt!(self.0.read_vectored(bufs))))
}
}
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>> {
Poll::Ready(Ok(try_with_interrupt!(self.0.seek(pos))))
}
}
impl<T> io::BufRead for AllowStdIo<T>
where
T: io::BufRead,
{
fn fill_buf(&mut self) -> io::Result<&[u8]> {
self.0.fill_buf()
}
fn consume(&mut self, amt: usize) {
self.0.consume(amt)
}
}
impl<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())))
}
fn consume(mut self: Pin<&mut Self>, amt: usize) {
self.0.consume(amt)
}
}

264
vendor/futures-util/src/io/buf_reader.rs vendored Normal file
View File

@@ -0,0 +1,264 @@
use super::DEFAULT_BUF_SIZE;
use futures_core::future::Future;
use futures_core::ready;
use futures_core::task::{Context, Poll};
use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSliceMut, SeekFrom};
use pin_project_lite::pin_project;
use std::boxed::Box;
use std::io::{self, Read};
use std::pin::Pin;
use std::vec;
use std::{cmp, fmt};
pin_project! {
/// The `BufReader` struct adds buffering to any reader.
///
/// It can be excessively inefficient to work directly with a [`AsyncRead`]
/// instance. A `BufReader` performs large, infrequent reads on the underlying
/// [`AsyncRead`] and maintains an in-memory buffer of the results.
///
/// `BufReader` can improve the speed of programs that make *small* and
/// *repeated* read calls to the same file or network socket. It does not
/// help when reading very large amounts at once, or reading just one or a few
/// times. It also provides no advantage when reading from a source that is
/// already in memory, like a `Vec<u8>`.
///
/// When the `BufReader` is dropped, the contents of its buffer will be
/// discarded. Creating multiple instances of a `BufReader` on the same
/// stream can cause data loss.
///
/// [`AsyncRead`]: futures_io::AsyncRead
///
// TODO: Examples
pub struct BufReader<R> {
#[pin]
inner: R,
buffer: Box<[u8]>,
pos: usize,
cap: usize,
}
}
impl<R: AsyncRead> BufReader<R> {
/// Creates a new `BufReader` with a default buffer capacity. The default is currently 8 KB,
/// but may change in the future.
pub fn new(inner: R) -> Self {
Self::with_capacity(DEFAULT_BUF_SIZE, inner)
}
/// Creates a new `BufReader` with the specified buffer capacity.
pub fn with_capacity(capacity: usize, inner: R) -> Self {
// TODO: consider using Box<[u8]>::new_uninit_slice once it stabilized
let buffer = vec![0; capacity];
Self { inner, buffer: buffer.into_boxed_slice(), pos: 0, cap: 0 }
}
}
impl<R> BufReader<R> {
delegate_access_inner!(inner, R, ());
/// Returns a reference to the internally buffered data.
///
/// Unlike `fill_buf`, this will not attempt to fill the buffer if it is empty.
pub fn buffer(&self) -> &[u8] {
&self.buffer[self.pos..self.cap]
}
/// Invalidates all data in the internal buffer.
#[inline]
fn discard_buffer(self: Pin<&mut Self>) {
let this = self.project();
*this.pos = 0;
*this.cap = 0;
}
}
impl<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>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
// If we don't have any buffered data and we're doing a massive read
// (larger than our internal buffer), bypass our internal buffer
// entirely.
if self.pos == self.cap && buf.len() >= self.buffer.len() {
let res = ready!(self.as_mut().project().inner.poll_read(cx, buf));
self.discard_buffer();
return Poll::Ready(res);
}
let mut rem = ready!(self.as_mut().poll_fill_buf(cx))?;
let nread = rem.read(buf)?;
self.consume(nread);
Poll::Ready(Ok(nread))
}
fn poll_read_vectored(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &mut [IoSliceMut<'_>],
) -> Poll<io::Result<usize>> {
let total_len = bufs.iter().map(|b| b.len()).sum::<usize>();
if self.pos == self.cap && total_len >= self.buffer.len() {
let res = ready!(self.as_mut().project().inner.poll_read_vectored(cx, bufs));
self.discard_buffer();
return Poll::Ready(res);
}
let mut rem = ready!(self.as_mut().poll_fill_buf(cx))?;
let nread = rem.read_vectored(bufs)?;
self.consume(nread);
Poll::Ready(Ok(nread))
}
}
impl<R: AsyncRead> AsyncBufRead for BufReader<R> {
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
// some more data from the underlying reader.
// Branch using `>=` instead of the more correct `==`
// to tell the compiler that the pos..cap slice is always valid.
if *this.pos >= *this.cap {
debug_assert!(*this.pos == *this.cap);
*this.cap = ready!(this.inner.poll_read(cx, this.buffer))?;
*this.pos = 0;
}
Poll::Ready(Ok(&this.buffer[*this.pos..*this.cap]))
}
fn consume(self: Pin<&mut Self>, amt: usize) {
*self.project().pos = cmp::min(self.pos + amt, self.cap);
}
}
impl<R: AsyncWrite> AsyncWrite for BufReader<R> {
delegate_async_write!(inner);
}
impl<R: fmt::Debug> fmt::Debug for BufReader<R> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BufReader")
.field("reader", &self.inner)
.field("buffer", &format_args!("{}/{}", self.cap - self.pos, self.buffer.len()))
.finish()
}
}
impl<R: AsyncRead + AsyncSeek> AsyncSeek for BufReader<R> {
/// Seek to an offset, in bytes, in the underlying reader.
///
/// The position used for seeking with `SeekFrom::Current(_)` is the
/// position the underlying reader would be at if the `BufReader` had no
/// internal buffer.
///
/// Seeking always discards the internal buffer, even if the seek position
/// would otherwise fall within it. This guarantees that calling
/// `.into_inner()` immediately after a seek yields the underlying reader
/// at the same position.
///
/// To seek without discarding the internal buffer, use
/// [`BufReader::seek_relative`](BufReader::seek_relative) or
/// [`BufReader::poll_seek_relative`](BufReader::poll_seek_relative).
///
/// See [`AsyncSeek`](futures_io::AsyncSeek) for more details.
///
/// Note: In the edge case where you're seeking with `SeekFrom::Current(n)`
/// where `n` minus the internal buffer length overflows an `i64`, two
/// seeks will be performed instead of one. If the second seek returns
/// `Err`, the underlying reader will be left at the same position it would
/// have if you called `seek` with `SeekFrom::Current(0)`.
fn poll_seek(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
pos: SeekFrom,
) -> Poll<io::Result<u64>> {
let result: u64;
if let SeekFrom::Current(n) = pos {
let remainder = (self.cap - self.pos) as i64;
// it should be safe to assume that remainder fits within an i64 as the alternative
// means we managed to allocate 8 exbibytes and that's absurd.
// But it's not out of the realm of possibility for some weird underlying reader to
// support seeking by i64::MIN so we need to handle underflow when subtracting
// remainder.
if let Some(offset) = n.checked_sub(remainder) {
result =
ready!(self.as_mut().project().inner.poll_seek(cx, SeekFrom::Current(offset)))?;
} else {
// seek backwards by our remainder, and then by the offset
ready!(self.as_mut().project().inner.poll_seek(cx, SeekFrom::Current(-remainder)))?;
self.as_mut().discard_buffer();
result = ready!(self.as_mut().project().inner.poll_seek(cx, SeekFrom::Current(n)))?;
}
} else {
// Seeking with Start/End doesn't care about our buffer length.
result = ready!(self.as_mut().project().inner.poll_seek(cx, pos))?;
}
self.discard_buffer();
Poll::Ready(Ok(result))
}
}
/// Future for the [`BufReader::seek_relative`](self::BufReader::seek_relative) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless polled"]
pub struct SeeKRelative<'a, R> {
inner: Pin<&'a mut BufReader<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(|_| ()))
}
}
}

229
vendor/futures-util/src/io/buf_writer.rs vendored Normal file
View File

@@ -0,0 +1,229 @@
use super::DEFAULT_BUF_SIZE;
use futures_core::ready;
use futures_core::task::{Context, Poll};
use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, SeekFrom};
use pin_project_lite::pin_project;
use std::fmt;
use std::io::{self, Write};
use std::pin::Pin;
use std::ptr;
use std::vec::Vec;
pin_project! {
/// Wraps a writer and buffers its output.
///
/// It can be excessively inefficient to work directly with something that
/// implements [`AsyncWrite`]. A `BufWriter` keeps an in-memory buffer of data and
/// writes it to an underlying writer in large, infrequent batches.
///
/// `BufWriter` can improve the speed of programs that make *small* and
/// *repeated* write calls to the same file or network socket. It does not
/// help when writing very large amounts at once, or writing just one or a few
/// times. It also provides no advantage when writing to a destination that is
/// in memory, like a `Vec<u8>`.
///
/// When the `BufWriter` is dropped, the contents of its buffer will be
/// discarded. Creating multiple instances of a `BufWriter` on the same
/// stream can cause data loss. If you need to write out the contents of its
/// buffer, you must manually call flush before the writer is dropped.
///
/// [`AsyncWrite`]: futures_io::AsyncWrite
/// [`flush`]: super::AsyncWriteExt::flush
///
// TODO: Examples
pub struct BufWriter<W> {
#[pin]
inner: W,
buf: Vec<u8>,
written: usize,
}
}
impl<W: AsyncWrite> BufWriter<W> {
/// Creates a new `BufWriter` with a default buffer capacity. The default is currently 8 KB,
/// but may change in the future.
pub fn new(inner: W) -> Self {
Self::with_capacity(DEFAULT_BUF_SIZE, inner)
}
/// Creates a new `BufWriter` with the specified buffer capacity.
pub fn with_capacity(cap: usize, inner: W) -> Self {
Self { inner, buf: Vec::with_capacity(cap), written: 0 }
}
pub(super) fn flush_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
let mut this = self.project();
let len = this.buf.len();
let mut ret = Ok(());
while *this.written < len {
match ready!(this.inner.as_mut().poll_write(cx, &this.buf[*this.written..])) {
Ok(0) => {
ret = Err(io::Error::new(
io::ErrorKind::WriteZero,
"failed to write the buffered data",
));
break;
}
Ok(n) => *this.written += n,
Err(e) => {
ret = Err(e);
break;
}
}
}
if *this.written > 0 {
this.buf.drain(..*this.written);
}
*this.written = 0;
Poll::Ready(ret)
}
/// 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> BufWriter<W> {
delegate_access_inner!(inner, W, ());
/// Returns a reference to the internally buffered data.
pub fn buffer(&self) -> &[u8] {
&self.buf
}
/// Capacity of `buf`. how many chars can be held in buffer
pub(super) fn capacity(&self) -> usize {
self.buf.capacity()
}
/// Remaining number of bytes to reach `buf` 's capacity
#[inline]
pub(super) fn spare_capacity(&self) -> usize {
self.buf.capacity() - self.buf.len()
}
/// Write a byte slice directly into buffer
///
/// Will truncate the number of bytes written to `spare_capacity()` so you want to
/// calculate the size of your slice to avoid losing bytes
///
/// Based on `std::io::BufWriter`
pub(super) fn write_to_buf(self: Pin<&mut Self>, buf: &[u8]) -> usize {
let available = self.spare_capacity();
let amt_to_buffer = available.min(buf.len());
// SAFETY: `amt_to_buffer` is <= buffer's spare capacity by construction.
unsafe {
self.write_to_buffer_unchecked(&buf[..amt_to_buffer]);
}
amt_to_buffer
}
/// Write byte slice directly into `self.buf`
///
/// Based on `std::io::BufWriter`
#[inline]
unsafe fn write_to_buffer_unchecked(self: Pin<&mut Self>, buf: &[u8]) {
debug_assert!(buf.len() <= self.spare_capacity());
let this = self.project();
let old_len = this.buf.len();
let buf_len = buf.len();
let src = buf.as_ptr();
unsafe {
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);
}
}
}
impl<W: AsyncWrite> AsyncWrite for BufWriter<W> {
fn poll_write(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<io::Result<usize>> {
if self.buf.len() + buf.len() > self.buf.capacity() {
ready!(self.as_mut().flush_buf(cx))?;
}
if buf.len() >= self.buf.capacity() {
self.project().inner.poll_write(cx, buf)
} else {
Poll::Ready(self.project().buf.write(buf))
}
}
fn poll_write_vectored(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &[IoSlice<'_>],
) -> Poll<io::Result<usize>> {
let total_len = bufs.iter().map(|b| b.len()).sum::<usize>();
if self.buf.len() + total_len > self.buf.capacity() {
ready!(self.as_mut().flush_buf(cx))?;
}
if total_len >= self.buf.capacity() {
self.project().inner.poll_write_vectored(cx, bufs)
} else {
Poll::Ready(self.project().buf.write_vectored(bufs))
}
}
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
ready!(self.as_mut().flush_buf(cx))?;
self.project().inner.poll_flush(cx)
}
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
ready!(self.as_mut().flush_buf(cx))?;
self.project().inner.poll_close(cx)
}
}
impl<W: AsyncRead> AsyncRead for BufWriter<W> {
delegate_async_read!(inner);
}
impl<W: AsyncBufRead> AsyncBufRead for BufWriter<W> {
delegate_async_buf_read!(inner);
}
impl<W: fmt::Debug> fmt::Debug for BufWriter<W> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BufWriter")
.field("writer", &self.inner)
.field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity()))
.field("written", &self.written)
.finish()
}
}
impl<W: AsyncWrite + AsyncSeek> AsyncSeek for BufWriter<W> {
/// Seek to the offset, in bytes, in the underlying writer.
///
/// Seeking always writes out the internal buffer before seeking.
fn poll_seek(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
pos: SeekFrom,
) -> Poll<io::Result<u64>> {
ready!(self.as_mut().flush_buf(cx))?;
self.project().inner.poll_seek(cx, pos)
}
}

142
vendor/futures-util/src/io/chain.rs vendored Normal file
View File

@@ -0,0 +1,142 @@
use futures_core::ready;
use futures_core::task::{Context, Poll};
use futures_io::{AsyncBufRead, AsyncRead, IoSliceMut};
use pin_project_lite::pin_project;
use std::fmt;
use std::io;
use std::pin::Pin;
pin_project! {
/// Reader for the [`chain`](super::AsyncReadExt::chain) method.
#[must_use = "readers do nothing unless polled"]
pub struct Chain<T, U> {
#[pin]
first: T,
#[pin]
second: U,
done_first: bool,
}
}
impl<T, U> Chain<T, U>
where
T: AsyncRead,
U: AsyncRead,
{
pub(super) fn new(first: T, second: U) -> Self {
Self { first, second, done_first: false }
}
/// Gets references to the underlying readers in this `Chain`.
pub fn get_ref(&self) -> (&T, &U) {
(&self.first, &self.second)
}
/// Gets mutable references to the underlying readers in this `Chain`.
///
/// Care should be taken to avoid modifying the internal I/O state of the
/// underlying readers as doing so may corrupt the internal state of this
/// `Chain`.
pub fn get_mut(&mut self) -> (&mut T, &mut U) {
(&mut self.first, &mut self.second)
}
/// Gets pinned mutable references to the underlying readers in this `Chain`.
///
/// Care should be taken to avoid modifying the internal I/O state of the
/// underlying readers as doing so may corrupt the internal state of this
/// `Chain`.
pub fn get_pin_mut(self: Pin<&mut Self>) -> (Pin<&mut T>, Pin<&mut U>) {
let this = self.project();
(this.first, this.second)
}
/// Consumes the `Chain`, returning the wrapped readers.
pub fn into_inner(self) -> (T, U) {
(self.first, self.second)
}
}
impl<T, U> fmt::Debug for Chain<T, U>
where
T: fmt::Debug,
U: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Chain")
.field("t", &self.first)
.field("u", &self.second)
.field("done_first", &self.done_first)
.finish()
}
}
impl<T, U> AsyncRead for Chain<T, U>
where
T: AsyncRead,
U: AsyncRead,
{
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
let this = self.project();
if !*this.done_first {
match ready!(this.first.poll_read(cx, buf)?) {
0 if !buf.is_empty() => *this.done_first = true,
n => return Poll::Ready(Ok(n)),
}
}
this.second.poll_read(cx, buf)
}
fn poll_read_vectored(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &mut [IoSliceMut<'_>],
) -> Poll<io::Result<usize>> {
let this = self.project();
if !*this.done_first {
let n = ready!(this.first.poll_read_vectored(cx, bufs)?);
if n == 0 && bufs.iter().any(|b| !b.is_empty()) {
*this.done_first = true
} else {
return Poll::Ready(Ok(n));
}
}
this.second.poll_read_vectored(cx, bufs)
}
}
impl<T, U> AsyncBufRead for Chain<T, U>
where
T: AsyncBufRead,
U: AsyncBufRead,
{
fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
let this = self.project();
if !*this.done_first {
match ready!(this.first.poll_fill_buf(cx)?) {
buf if buf.is_empty() => {
*this.done_first = true;
}
buf => return Poll::Ready(Ok(buf)),
}
}
this.second.poll_fill_buf(cx)
}
fn consume(self: Pin<&mut Self>, amt: usize) {
let this = self.project();
if !*this.done_first {
this.first.consume(amt)
} else {
this.second.consume(amt)
}
}
}

28
vendor/futures-util/src/io/close.rs vendored Normal file
View File

@@ -0,0 +1,28 @@
use futures_core::future::Future;
use futures_core::task::{Context, Poll};
use futures_io::AsyncWrite;
use std::io;
use std::pin::Pin;
/// Future for the [`close`](super::AsyncWriteExt::close) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Close<'a, W: ?Sized> {
writer: &'a mut W,
}
impl<W: ?Sized + Unpin> Unpin for Close<'_, W> {}
impl<'a, W: AsyncWrite + ?Sized + Unpin> Close<'a, W> {
pub(super) fn new(writer: &'a mut W) -> Self {
Self { writer }
}
}
impl<W: AsyncWrite + ?Sized + Unpin> Future for Close<'_, W> {
type Output = io::Result<()>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Pin::new(&mut *self.writer).poll_close(cx)
}
}

58
vendor/futures-util/src/io/copy.rs vendored Normal file
View File

@@ -0,0 +1,58 @@
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;
/// Creates a future which copies all the bytes from one object to another.
///
/// The returned future will copy all the bytes read from this `AsyncRead` into the
/// `writer` specified. This future will only complete once the `reader` has hit
/// EOF and all bytes have been written to and flushed from the `writer`
/// provided.
///
/// On success the number of bytes is returned.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{self, AsyncWriteExt, Cursor};
///
/// let reader = Cursor::new([1, 2, 3, 4]);
/// let mut writer = Cursor::new(vec![0u8; 5]);
///
/// let bytes = io::copy(reader, &mut writer).await?;
/// writer.close().await?;
///
/// assert_eq!(bytes, 4);
/// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]);
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
pub fn copy<R, W>(reader: R, writer: &mut W) -> Copy<'_, R, W>
where
R: AsyncRead,
W: AsyncWrite + Unpin + ?Sized,
{
Copy { inner: copy_buf(BufReader::new(reader), writer) }
}
pin_project! {
/// Future for the [`copy()`] function.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Copy<'a, R, W: ?Sized> {
#[pin]
inner: CopyBuf<'a, BufReader<R>, W>,
}
}
impl<R: AsyncRead, W: AsyncWrite + Unpin + ?Sized> Future for Copy<'_, R, W> {
type Output = io::Result<u64>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
self.project().inner.poll(cx)
}
}

78
vendor/futures-util/src/io/copy_buf.rs vendored Normal file
View File

@@ -0,0 +1,78 @@
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;
/// Creates a future which copies all the bytes from one object to another.
///
/// The returned future will copy all the bytes read from this `AsyncBufRead` into the
/// `writer` specified. This future will only complete once the `reader` has hit
/// EOF and all bytes have been written to and flushed from the `writer`
/// provided.
///
/// On success the number of bytes is returned.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{self, AsyncWriteExt, Cursor};
///
/// let reader = Cursor::new([1, 2, 3, 4]);
/// let mut writer = Cursor::new(vec![0u8; 5]);
///
/// let bytes = io::copy_buf(reader, &mut writer).await?;
/// writer.close().await?;
///
/// assert_eq!(bytes, 4);
/// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]);
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
pub fn copy_buf<R, W>(reader: R, writer: &mut W) -> CopyBuf<'_, R, W>
where
R: AsyncBufRead,
W: AsyncWrite + Unpin + ?Sized,
{
CopyBuf { reader, writer, amt: 0 }
}
pin_project! {
/// Future for the [`copy_buf()`] function.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct CopyBuf<'a, R, W: ?Sized> {
#[pin]
reader: R,
writer: &'a mut W,
amt: u64,
}
}
impl<R, W> Future for CopyBuf<'_, R, W>
where
R: AsyncBufRead,
W: AsyncWrite + Unpin + ?Sized,
{
type Output = io::Result<u64>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut this = self.project();
loop {
let buffer = ready!(this.reader.as_mut().poll_fill_buf(cx))?;
if buffer.is_empty() {
ready!(Pin::new(&mut this.writer).poll_flush(cx))?;
return Poll::Ready(Ok(*this.amt));
}
let i = ready!(Pin::new(&mut this.writer).poll_write(cx, buffer))?;
if i == 0 {
return Poll::Ready(Err(io::ErrorKind::WriteZero.into()));
}
*this.amt += i as u64;
this.reader.as_mut().consume(i);
}
}
}

View File

@@ -0,0 +1,124 @@
use crate::abortable::{AbortHandle, AbortInner, Aborted};
use futures_core::future::Future;
use futures_core::task::{Context, Poll};
use futures_io::{AsyncBufRead, AsyncWrite};
use pin_project_lite::pin_project;
use std::io;
use std::pin::Pin;
use std::sync::atomic::Ordering;
use std::sync::Arc;
/// Creates a future which copies all the bytes from one object to another, with its `AbortHandle`.
///
/// The returned future will copy all the bytes read from this `AsyncBufRead` into the
/// `writer` specified. This future will only complete once abort has been requested or the `reader` has hit
/// EOF and all bytes have been written to and flushed from the `writer`
/// provided.
///
/// On success the number of bytes is returned. If aborted, `Aborted` is returned. Otherwise, the underlying error is returned.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{self, AsyncWriteExt, Cursor};
/// use futures::future::Aborted;
///
/// let reader = Cursor::new([1, 2, 3, 4]);
/// let mut writer = Cursor::new(vec![0u8; 5]);
///
/// let (fut, abort_handle) = io::copy_buf_abortable(reader, &mut writer);
/// let bytes = fut.await;
/// abort_handle.abort();
/// writer.close().await.unwrap();
/// match bytes {
/// Ok(Ok(n)) => {
/// assert_eq!(n, 4);
/// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]);
/// Ok(n)
/// },
/// Ok(Err(a)) => {
/// Err::<u64, Aborted>(a)
/// }
/// Err(e) => panic!("{}", e)
/// }
/// # }).unwrap();
/// ```
pub fn copy_buf_abortable<R, W>(
reader: R,
writer: &mut W,
) -> (CopyBufAbortable<'_, R, W>, AbortHandle)
where
R: AsyncBufRead,
W: AsyncWrite + Unpin + ?Sized,
{
let (handle, reg) = AbortHandle::new_pair();
(CopyBufAbortable { reader, writer, amt: 0, inner: reg.inner }, handle)
}
pin_project! {
/// Future for the [`copy_buf_abortable()`] function.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct CopyBufAbortable<'a, R, W: ?Sized> {
#[pin]
reader: R,
writer: &'a mut W,
amt: u64,
inner: Arc<AbortInner>
}
}
macro_rules! ready_or_break {
($e:expr $(,)?) => {
match $e {
$crate::task::Poll::Ready(t) => t,
$crate::task::Poll::Pending => break,
}
};
}
impl<R, W> Future for CopyBufAbortable<'_, R, W>
where
R: AsyncBufRead,
W: AsyncWrite + Unpin + Sized,
{
type Output = Result<Result<u64, Aborted>, io::Error>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut this = self.project();
loop {
// Check if the task has been aborted
if this.inner.aborted.load(Ordering::Relaxed) {
return Poll::Ready(Ok(Err(Aborted)));
}
// Read some bytes from the reader, and if we have reached EOF, return total bytes read
let buffer = ready_or_break!(this.reader.as_mut().poll_fill_buf(cx))?;
if buffer.is_empty() {
ready_or_break!(Pin::new(&mut this.writer).poll_flush(cx))?;
return Poll::Ready(Ok(Ok(*this.amt)));
}
// Pass the buffer to the writer, and update the amount written
let i = ready_or_break!(Pin::new(&mut this.writer).poll_write(cx, buffer))?;
if i == 0 {
return Poll::Ready(Err(io::ErrorKind::WriteZero.into()));
}
*this.amt += i as u64;
this.reader.as_mut().consume(i);
}
// Schedule the task to be woken up again.
// Never called unless Poll::Pending is returned from io objects.
this.inner.waker.register(cx.waker());
// Check to see if the task was aborted between the first check and
// registration.
// Checking with `Relaxed` is sufficient because
// `register` introduces an `AcqRel` barrier.
if this.inner.aborted.load(Ordering::Relaxed) {
return Poll::Ready(Ok(Err(Aborted)));
}
Poll::Pending
}
}

234
vendor/futures-util/src/io/cursor.rs vendored Normal file
View File

@@ -0,0 +1,234 @@
use futures_core::task::{Context, Poll};
use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, SeekFrom};
use std::boxed::Box;
use std::io;
use std::pin::Pin;
use std::vec::Vec;
/// A `Cursor` wraps an in-memory buffer and provides it with a
/// [`AsyncSeek`] implementation.
///
/// `Cursor`s are used with in-memory buffers, anything implementing
/// `AsRef<[u8]>`, to allow them to implement [`AsyncRead`] and/or [`AsyncWrite`],
/// allowing these buffers to be used anywhere you might use a reader or writer
/// that does actual I/O.
///
/// This library implements some I/O traits on various types which
/// are commonly used as a buffer, like `Cursor<`[`Vec`]`<u8>>` and
/// `Cursor<`[`&[u8]`][bytes]`>`.
///
/// [`AsyncSeek`]: trait.AsyncSeek.html
/// [`AsyncRead`]: trait.AsyncRead.html
/// [`AsyncWrite`]: trait.AsyncWrite.html
/// [bytes]: https://doc.rust-lang.org/std/primitive.slice.html
#[derive(Clone, Debug, Default)]
pub struct Cursor<T> {
inner: io::Cursor<T>,
}
impl<T> Cursor<T> {
/// Creates a new cursor wrapping the provided underlying in-memory buffer.
///
/// Cursor initial position is `0` even if underlying buffer (e.g., `Vec`)
/// is not empty. So writing to cursor starts with overwriting `Vec`
/// content, not with appending to it.
///
/// # Examples
///
/// ```
/// use futures::io::Cursor;
///
/// let buff = Cursor::new(Vec::new());
/// # fn force_inference(_: &Cursor<Vec<u8>>) {}
/// # force_inference(&buff);
/// ```
pub fn new(inner: T) -> Self {
Self { inner: io::Cursor::new(inner) }
}
/// Consumes this cursor, returning the underlying value.
///
/// # Examples
///
/// ```
/// use futures::io::Cursor;
///
/// let buff = Cursor::new(Vec::new());
/// # fn force_inference(_: &Cursor<Vec<u8>>) {}
/// # force_inference(&buff);
///
/// let vec = buff.into_inner();
/// ```
pub fn into_inner(self) -> T {
self.inner.into_inner()
}
/// Gets a reference to the underlying value in this cursor.
///
/// # Examples
///
/// ```
/// use futures::io::Cursor;
///
/// let buff = Cursor::new(Vec::new());
/// # fn force_inference(_: &Cursor<Vec<u8>>) {}
/// # force_inference(&buff);
///
/// let reference = buff.get_ref();
/// ```
pub fn get_ref(&self) -> &T {
self.inner.get_ref()
}
/// Gets a mutable reference to the underlying value in this cursor.
///
/// Care should be taken to avoid modifying the internal I/O state of the
/// underlying value as it may corrupt this cursor's position.
///
/// # Examples
///
/// ```
/// use futures::io::Cursor;
///
/// let mut buff = Cursor::new(Vec::new());
/// # fn force_inference(_: &Cursor<Vec<u8>>) {}
/// # force_inference(&buff);
///
/// let reference = buff.get_mut();
/// ```
pub fn get_mut(&mut self) -> &mut T {
self.inner.get_mut()
}
/// Returns the current position of this cursor.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{AsyncSeekExt, Cursor, SeekFrom};
///
/// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
///
/// assert_eq!(buff.position(), 0);
///
/// buff.seek(SeekFrom::Current(2)).await?;
/// assert_eq!(buff.position(), 2);
///
/// buff.seek(SeekFrom::Current(-1)).await?;
/// assert_eq!(buff.position(), 1);
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
pub fn position(&self) -> u64 {
self.inner.position()
}
/// Sets the position of this cursor.
///
/// # Examples
///
/// ```
/// use futures::io::Cursor;
///
/// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
///
/// assert_eq!(buff.position(), 0);
///
/// buff.set_position(2);
/// assert_eq!(buff.position(), 2);
///
/// buff.set_position(4);
/// assert_eq!(buff.position(), 4);
/// ```
pub fn set_position(&mut self, pos: u64) {
self.inner.set_position(pos)
}
}
impl<T> AsyncSeek for Cursor<T>
where
T: AsRef<[u8]> + Unpin,
{
fn poll_seek(
mut self: Pin<&mut Self>,
_: &mut Context<'_>,
pos: SeekFrom,
) -> Poll<io::Result<u64>> {
Poll::Ready(io::Seek::seek(&mut self.inner, pos))
}
}
impl<T: AsRef<[u8]> + Unpin> AsyncRead for Cursor<T> {
fn poll_read(
mut self: Pin<&mut Self>,
_cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
Poll::Ready(io::Read::read(&mut self.inner, buf))
}
fn poll_read_vectored(
mut self: Pin<&mut Self>,
_: &mut Context<'_>,
bufs: &mut [IoSliceMut<'_>],
) -> Poll<io::Result<usize>> {
Poll::Ready(io::Read::read_vectored(&mut self.inner, bufs))
}
}
impl<T> AsyncBufRead for Cursor<T>
where
T: AsRef<[u8]> + Unpin,
{
fn poll_fill_buf(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
Poll::Ready(io::BufRead::fill_buf(&mut self.get_mut().inner))
}
fn consume(mut self: Pin<&mut Self>, amt: usize) {
io::BufRead::consume(&mut self.inner, amt)
}
}
macro_rules! delegate_async_write_to_stdio {
() => {
fn poll_write(
mut self: Pin<&mut Self>,
_: &mut Context<'_>,
buf: &[u8],
) -> Poll<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>> {
Poll::Ready(io::Write::write_vectored(&mut self.inner, bufs))
}
fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
Poll::Ready(io::Write::flush(&mut self.inner))
}
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.poll_flush(cx)
}
};
}
impl AsyncWrite for Cursor<&mut [u8]> {
delegate_async_write_to_stdio!();
}
impl AsyncWrite for Cursor<&mut Vec<u8>> {
delegate_async_write_to_stdio!();
}
impl AsyncWrite for Cursor<Vec<u8>> {
delegate_async_write_to_stdio!();
}
impl AsyncWrite for Cursor<Box<[u8]>> {
delegate_async_write_to_stdio!();
}

59
vendor/futures-util/src/io/empty.rs vendored Normal file
View File

@@ -0,0 +1,59 @@
use futures_core::task::{Context, Poll};
use futures_io::{AsyncBufRead, AsyncRead};
use std::fmt;
use std::io;
use std::pin::Pin;
/// Reader for the [`empty()`] function.
#[must_use = "readers do nothing unless polled"]
pub struct Empty {
_priv: (),
}
/// Constructs a new handle to an empty reader.
///
/// All reads from the returned reader will return `Poll::Ready(Ok(0))`.
///
/// # Examples
///
/// A slightly sad example of not reading anything into a buffer:
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{self, AsyncReadExt};
///
/// let mut buffer = String::new();
/// let mut reader = io::empty();
/// reader.read_to_string(&mut buffer).await?;
/// assert!(buffer.is_empty());
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
pub fn empty() -> Empty {
Empty { _priv: () }
}
impl AsyncRead for Empty {
#[inline]
fn poll_read(
self: Pin<&mut Self>,
_: &mut Context<'_>,
_: &mut [u8],
) -> Poll<io::Result<usize>> {
Poll::Ready(Ok(0))
}
}
impl AsyncBufRead for Empty {
#[inline]
fn poll_fill_buf(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
Poll::Ready(Ok(&[]))
}
#[inline]
fn consume(self: Pin<&mut Self>, _: usize) {}
}
impl fmt::Debug for Empty {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.pad("Empty { .. }")
}
}

47
vendor/futures-util/src/io/fill_buf.rs vendored Normal file
View File

@@ -0,0 +1,47 @@
use futures_core::future::Future;
use futures_core::task::{Context, Poll};
use futures_io::AsyncBufRead;
use std::io;
use std::pin::Pin;
use std::slice;
/// Future for the [`fill_buf`](super::AsyncBufReadExt::fill_buf) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct FillBuf<'a, R: ?Sized> {
reader: Option<&'a mut R>,
}
impl<R: ?Sized> Unpin for FillBuf<'_, R> {}
impl<'a, R: AsyncBufRead + ?Sized + Unpin> FillBuf<'a, R> {
pub(super) fn new(reader: &'a mut R) -> Self {
Self { reader: Some(reader) }
}
}
impl<'a, R> Future for FillBuf<'a, R>
where
R: AsyncBufRead + ?Sized + Unpin,
{
type Output = io::Result<&'a [u8]>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = &mut *self;
let reader = this.reader.take().expect("Polled FillBuf after completion");
match Pin::new(&mut *reader).poll_fill_buf(cx) {
Poll::Ready(Ok(slice)) => {
// With polonius it is possible to remove this lifetime transmutation and just have
// the correct lifetime of the reference inferred based on which branch is taken
let slice: &'a [u8] = unsafe { slice::from_raw_parts(slice.as_ptr(), slice.len()) };
Poll::Ready(Ok(slice))
}
Poll::Ready(Err(err)) => Poll::Ready(Err(err)),
Poll::Pending => {
this.reader = Some(reader);
Poll::Pending
}
}
}
}

31
vendor/futures-util/src/io/flush.rs vendored Normal file
View File

@@ -0,0 +1,31 @@
use futures_core::future::Future;
use futures_core::task::{Context, Poll};
use futures_io::AsyncWrite;
use std::io;
use std::pin::Pin;
/// Future for the [`flush`](super::AsyncWriteExt::flush) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Flush<'a, W: ?Sized> {
writer: &'a mut W,
}
impl<W: ?Sized + Unpin> Unpin for Flush<'_, W> {}
impl<'a, W: AsyncWrite + ?Sized + Unpin> Flush<'a, W> {
pub(super) fn new(writer: &'a mut W) -> Self {
Self { writer }
}
}
impl<W> Future for Flush<'_, W>
where
W: AsyncWrite + ?Sized + Unpin,
{
type Output = io::Result<()>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Pin::new(&mut *self.writer).poll_flush(cx)
}
}

82
vendor/futures-util/src/io/into_sink.rs vendored Normal file
View File

@@ -0,0 +1,82 @@
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;
#[derive(Debug)]
struct Block<Item> {
offset: usize,
bytes: Item,
}
pin_project! {
/// Sink for the [`into_sink`](super::AsyncWriteExt::into_sink) method.
#[must_use = "sinks do nothing unless polled"]
#[derive(Debug)]
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
pub struct IntoSink<W, Item> {
#[pin]
writer: W,
// An outstanding block for us to push into the underlying writer, along with an offset of how
// far into this block we have written already.
buffer: Option<Block<Item>>,
}
}
impl<W: AsyncWrite, Item: AsRef<[u8]>> IntoSink<W, Item> {
pub(super) fn new(writer: W) -> Self {
Self { writer, buffer: None }
}
/// If we have an outstanding block in `buffer` attempt to push it into the writer, does _not_
/// flush the writer after it succeeds in pushing the block into it.
fn poll_flush_buffer(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<(), io::Error>> {
let mut this = self.project();
if let Some(buffer) = this.buffer {
loop {
let bytes = buffer.bytes.as_ref();
let written = ready!(this.writer.as_mut().poll_write(cx, &bytes[buffer.offset..]))?;
buffer.offset += written;
if buffer.offset == bytes.len() {
break;
}
}
}
*this.buffer = None;
Poll::Ready(Ok(()))
}
}
impl<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>> {
ready!(self.poll_flush_buffer(cx))?;
Poll::Ready(Ok(()))
}
fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
debug_assert!(self.buffer.is_none());
*self.project().buffer = Some(Block { offset: 0, bytes: item });
Ok(())
}
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<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>> {
ready!(self.as_mut().poll_flush_buffer(cx))?;
ready!(self.project().writer.poll_close(cx))?;
Poll::Ready(Ok(()))
}
}

View File

@@ -0,0 +1,155 @@
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) -> Self {
Self::with_capacity(1024, inner)
}
/// Creates a new `LineWriter` with the specified buffer capacity.
pub fn with_capacity(capacity: usize, inner: W) -> Self {
Self { 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)
}
}

50
vendor/futures-util/src/io/lines.rs vendored Normal file
View File

@@ -0,0 +1,50 @@
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 std::string::String;
use std::vec::Vec;
pin_project! {
/// Stream for the [`lines`](super::AsyncBufReadExt::lines) method.
#[derive(Debug)]
#[must_use = "streams do nothing unless polled"]
pub struct Lines<R> {
#[pin]
reader: R,
buf: String,
bytes: Vec<u8>,
read: usize,
}
}
impl<R: AsyncBufRead> Lines<R> {
pub(super) fn new(reader: R) -> Self {
Self { reader, buf: String::new(), bytes: Vec::new(), read: 0 }
}
}
impl<R: AsyncBufRead> Stream for Lines<R> {
type Item = io::Result<String>;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
let this = self.project();
let n = ready!(read_line_internal(this.reader, cx, this.buf, this.bytes, this.read))?;
*this.read = 0;
if n == 0 && this.buf.is_empty() {
return Poll::Ready(None);
}
if this.buf.ends_with('\n') {
this.buf.pop();
if this.buf.ends_with('\r') {
this.buf.pop();
}
}
Poll::Ready(Some(Ok(mem::take(this.buf))))
}
}

833
vendor/futures-util/src/io/mod.rs vendored Normal file
View File

@@ -0,0 +1,833 @@
//! Asynchronous I/O.
//!
//! This module is the asynchronous version of `std::io`. It defines four
//! traits, [`AsyncRead`], [`AsyncWrite`], [`AsyncSeek`], and [`AsyncBufRead`],
//! which mirror the `Read`, `Write`, `Seek`, and `BufRead` traits of the
//! standard library. However, these traits integrate with the asynchronous
//! task system, so that if an I/O object isn't ready for reading (or writing),
//! the thread is not blocked, and instead the current task is queued to be
//! woken when I/O is ready.
//!
//! In addition, the [`AsyncReadExt`], [`AsyncWriteExt`], [`AsyncSeekExt`], and
//! [`AsyncBufReadExt`] extension traits offer a variety of useful combinators
//! for operating with asynchronous I/O objects, including ways to work with
//! them using futures, streams and sinks.
//!
//! This module is only available when the `std` feature of this
//! library is activated, and it is activated by default.
#[cfg(feature = "io-compat")]
#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
use crate::compat::Compat;
use crate::future::assert_future;
use crate::stream::assert_stream;
use std::{pin::Pin, string::String, vec::Vec};
// Re-export some types from `std::io` so that users don't have to deal
// with conflicts when `use`ing `futures::io` and `std::io`.
#[doc(no_inline)]
pub use std::io::{Error, ErrorKind, IoSlice, IoSliceMut, Result, SeekFrom};
pub use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite};
// used by `BufReader` and `BufWriter`
// https://github.com/rust-lang/rust/blob/master/src/libstd/sys_common/io.rs#L1
const DEFAULT_BUF_SIZE: usize = 8 * 1024;
mod allow_std;
pub use self::allow_std::AllowStdIo;
mod buf_reader;
pub use self::buf_reader::{BufReader, SeeKRelative};
mod buf_writer;
pub use self::buf_writer::BufWriter;
mod line_writer;
pub use self::line_writer::LineWriter;
mod chain;
pub use self::chain::Chain;
mod close;
pub use self::close::Close;
mod copy;
pub use self::copy::{copy, Copy};
mod copy_buf;
pub use self::copy_buf::{copy_buf, CopyBuf};
mod copy_buf_abortable;
pub use self::copy_buf_abortable::{copy_buf_abortable, CopyBufAbortable};
mod cursor;
pub use self::cursor::Cursor;
mod empty;
pub use self::empty::{empty, Empty};
mod fill_buf;
pub use self::fill_buf::FillBuf;
mod flush;
pub use self::flush::Flush;
#[cfg(feature = "sink")]
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
mod into_sink;
#[cfg(feature = "sink")]
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
pub use self::into_sink::IntoSink;
mod lines;
pub use self::lines::Lines;
mod read;
pub use self::read::Read;
mod read_vectored;
pub use self::read_vectored::ReadVectored;
mod read_exact;
pub use self::read_exact::ReadExact;
mod read_line;
pub use self::read_line::ReadLine;
mod read_to_end;
pub use self::read_to_end::ReadToEnd;
mod read_to_string;
pub use self::read_to_string::ReadToString;
mod read_until;
pub use self::read_until::ReadUntil;
mod repeat;
pub use self::repeat::{repeat, Repeat};
mod seek;
pub use self::seek::Seek;
mod sink;
pub use self::sink::{sink, Sink};
mod split;
pub use self::split::{ReadHalf, ReuniteError, WriteHalf};
mod take;
pub use self::take::Take;
mod window;
pub use self::window::Window;
mod write;
pub use self::write::Write;
mod write_vectored;
pub use self::write_vectored::WriteVectored;
mod write_all;
pub use self::write_all::WriteAll;
#[cfg(feature = "write-all-vectored")]
mod write_all_vectored;
#[cfg(feature = "write-all-vectored")]
pub use self::write_all_vectored::WriteAllVectored;
/// An extension trait which adds utility methods to `AsyncRead` types.
pub trait AsyncReadExt: AsyncRead {
/// Creates an adaptor which will chain this stream with another.
///
/// The returned `AsyncRead` instance will first read all bytes from this object
/// until EOF is encountered. Afterwards the output is equivalent to the
/// output of `next`.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{AsyncReadExt, Cursor};
///
/// let reader1 = Cursor::new([1, 2, 3, 4]);
/// let reader2 = Cursor::new([5, 6, 7, 8]);
///
/// let mut reader = reader1.chain(reader2);
/// let mut buffer = Vec::new();
///
/// // read the value into a Vec.
/// reader.read_to_end(&mut buffer).await?;
/// assert_eq!(buffer, [1, 2, 3, 4, 5, 6, 7, 8]);
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn chain<R>(self, next: R) -> Chain<Self, R>
where
Self: Sized,
R: AsyncRead,
{
assert_read(Chain::new(self, next))
}
/// Tries to read some bytes directly into the given `buf` in asynchronous
/// manner, returning a future type.
///
/// The returned future will resolve to the number of bytes read once the read
/// operation is completed.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{AsyncReadExt, Cursor};
///
/// let mut reader = Cursor::new([1, 2, 3, 4]);
/// let mut output = [0u8; 5];
///
/// let bytes = reader.read(&mut output[..]).await?;
///
/// // This is only guaranteed to be 4 because `&[u8]` is a synchronous
/// // reader. In a real system you could get anywhere from 1 to
/// // `output.len()` bytes in a single read.
/// assert_eq!(bytes, 4);
/// assert_eq!(output, [1, 2, 3, 4, 0]);
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>
where
Self: Unpin,
{
assert_future::<Result<usize>, _>(Read::new(self, buf))
}
/// Creates a future which will read from the `AsyncRead` into `bufs` using vectored
/// IO operations.
///
/// The returned future will resolve to the number of bytes read once the read
/// operation is completed.
fn read_vectored<'a>(&'a mut self, bufs: &'a mut [IoSliceMut<'a>]) -> ReadVectored<'a, Self>
where
Self: Unpin,
{
assert_future::<Result<usize>, _>(ReadVectored::new(self, bufs))
}
/// Creates a future which will read exactly enough bytes to fill `buf`,
/// returning an error if end of file (EOF) is hit sooner.
///
/// The returned future will resolve once the read operation is completed.
///
/// In the case of an error the buffer and the object will be discarded, with
/// the error yielded.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{AsyncReadExt, Cursor};
///
/// let mut reader = Cursor::new([1, 2, 3, 4]);
/// let mut output = [0u8; 4];
///
/// reader.read_exact(&mut output).await?;
///
/// assert_eq!(output, [1, 2, 3, 4]);
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
///
/// ## EOF is hit before `buf` is filled
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{self, AsyncReadExt, Cursor};
///
/// let mut reader = Cursor::new([1, 2, 3, 4]);
/// let mut output = [0u8; 5];
///
/// let result = reader.read_exact(&mut output).await;
///
/// assert_eq!(result.unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
/// # });
/// ```
fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self>
where
Self: Unpin,
{
assert_future::<Result<()>, _>(ReadExact::new(self, buf))
}
/// Creates a future which will read all the bytes from this `AsyncRead`.
///
/// On success the total number of bytes read is returned.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{AsyncReadExt, Cursor};
///
/// let mut reader = Cursor::new([1, 2, 3, 4]);
/// let mut output = Vec::with_capacity(4);
///
/// let bytes = reader.read_to_end(&mut output).await?;
///
/// assert_eq!(bytes, 4);
/// assert_eq!(output, vec![1, 2, 3, 4]);
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
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))
}
/// Creates a future which will read all the bytes from this `AsyncRead`.
///
/// On success the total number of bytes read is returned.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{AsyncReadExt, Cursor};
///
/// let mut reader = Cursor::new(&b"1234"[..]);
/// let mut buffer = String::with_capacity(4);
///
/// let bytes = reader.read_to_string(&mut buffer).await?;
///
/// assert_eq!(bytes, 4);
/// assert_eq!(buffer, String::from("1234"));
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
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))
}
/// Helper method for splitting this read/write object into two halves.
///
/// The two halves returned implement the `AsyncRead` and `AsyncWrite`
/// traits, respectively.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{self, AsyncReadExt, Cursor};
///
/// // Note that for `Cursor` the read and write halves share a single
/// // seek position. This may or may not be true for other types that
/// // implement both `AsyncRead` and `AsyncWrite`.
///
/// let reader = Cursor::new([1, 2, 3, 4]);
/// let mut buffer = Cursor::new(vec![0, 0, 0, 0, 5, 6, 7, 8]);
/// let mut writer = Cursor::new(vec![0u8; 5]);
///
/// {
/// let (buffer_reader, mut buffer_writer) = (&mut buffer).split();
/// io::copy(reader, &mut buffer_writer).await?;
/// io::copy(buffer_reader, &mut writer).await?;
/// }
///
/// assert_eq!(buffer.into_inner(), [1, 2, 3, 4, 5, 6, 7, 8]);
/// assert_eq!(writer.into_inner(), [5, 6, 7, 8, 0]);
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn split(self) -> (ReadHalf<Self>, WriteHalf<Self>)
where
Self: AsyncWrite + Sized,
{
let (r, w) = split::split(self);
(assert_read(r), assert_write(w))
}
/// Creates an AsyncRead adapter which will read at most `limit` bytes
/// from the underlying reader.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{AsyncReadExt, Cursor};
///
/// let reader = Cursor::new(&b"12345678"[..]);
/// let mut buffer = [0; 5];
///
/// let mut take = reader.take(4);
/// let n = take.read(&mut buffer).await?;
///
/// assert_eq!(n, 4);
/// assert_eq!(&buffer, b"1234\0");
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn take(self, limit: u64) -> Take<Self>
where
Self: Sized,
{
assert_read(Take::new(self, limit))
}
/// Wraps an [`AsyncRead`] in a compatibility wrapper that allows it to be
/// used as a futures 0.1 / tokio-io 0.1 `AsyncRead`. If the wrapped type
/// implements [`AsyncWrite`] as well, the result will also implement the
/// futures 0.1 / tokio 0.1 `AsyncWrite` trait.
///
/// Requires the `io-compat` feature to enable.
#[cfg(feature = "io-compat")]
#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
fn compat(self) -> Compat<Self>
where
Self: Sized + Unpin,
{
Compat::new(self)
}
}
impl<R: AsyncRead + ?Sized> AsyncReadExt for R {}
/// An extension trait which adds utility methods to `AsyncWrite` types.
pub trait AsyncWriteExt: AsyncWrite {
/// Creates a future which will entirely flush this `AsyncWrite`.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{AllowStdIo, AsyncWriteExt};
/// use std::io::{BufWriter, Cursor};
///
/// let mut output = vec![0u8; 5];
///
/// {
/// let writer = Cursor::new(&mut output);
/// let mut buffered = AllowStdIo::new(BufWriter::new(writer));
/// buffered.write_all(&[1, 2]).await?;
/// buffered.write_all(&[3, 4]).await?;
/// buffered.flush().await?;
/// }
///
/// assert_eq!(output, [1, 2, 3, 4, 0]);
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn flush(&mut self) -> Flush<'_, Self>
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,
{
assert_future::<Result<()>, _>(Close::new(self))
}
/// Creates a future which will write bytes from `buf` into the object.
///
/// The returned future will resolve to the number of bytes written once the write
/// operation is completed.
fn write<'a>(&'a mut self, buf: &'a [u8]) -> Write<'a, Self>
where
Self: Unpin,
{
assert_future::<Result<usize>, _>(Write::new(self, buf))
}
/// Creates a future which will write bytes from `bufs` into the object using vectored
/// IO operations.
///
/// The returned future will resolve to the number of bytes written once the write
/// operation is completed.
fn write_vectored<'a>(&'a mut self, bufs: &'a [IoSlice<'a>]) -> WriteVectored<'a, Self>
where
Self: Unpin,
{
assert_future::<Result<usize>, _>(WriteVectored::new(self, bufs))
}
/// Write data into this object.
///
/// Creates a future that will write the entire contents of the buffer `buf` into
/// this `AsyncWrite`.
///
/// The returned future will not complete until all the data has been written.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{AsyncWriteExt, Cursor};
///
/// let mut writer = Cursor::new(vec![0u8; 5]);
///
/// writer.write_all(&[1, 2, 3, 4]).await?;
///
/// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]);
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> WriteAll<'a, Self>
where
Self: Unpin,
{
assert_future::<Result<()>, _>(WriteAll::new(self, buf))
}
/// Attempts to write multiple buffers into this writer.
///
/// Creates a future that will write the entire contents of `bufs` into this
/// `AsyncWrite` using [vectored writes].
///
/// The returned future will not complete until all the data has been
/// written.
///
/// [vectored writes]: std::io::Write::write_vectored
///
/// # Notes
///
/// Unlike `io::Write::write_vectored`, this takes a *mutable* reference to
/// a slice of `IoSlice`s, not an immutable one. That's because we need to
/// modify the slice to keep track of the bytes already written.
///
/// Once this futures returns, the contents of `bufs` are unspecified, as
/// this depends on how many calls to `write_vectored` were necessary. It is
/// best to understand this function as taking ownership of `bufs` and to
/// not use `bufs` afterwards. The underlying buffers, to which the
/// `IoSlice`s point (but not the `IoSlice`s themselves), are unchanged and
/// can be reused.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::AsyncWriteExt;
/// use futures_util::io::Cursor;
/// use std::io::IoSlice;
///
/// let mut writer = Cursor::new(Vec::new());
/// let bufs = &mut [
/// IoSlice::new(&[1]),
/// IoSlice::new(&[2, 3]),
/// IoSlice::new(&[4, 5, 6]),
/// ];
///
/// writer.write_all_vectored(bufs).await?;
/// // Note: the contents of `bufs` is now unspecified, see the Notes section.
///
/// assert_eq!(writer.into_inner(), &[1, 2, 3, 4, 5, 6]);
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
#[cfg(feature = "write-all-vectored")]
fn write_all_vectored<'a>(
&'a mut self,
bufs: &'a mut [IoSlice<'a>],
) -> WriteAllVectored<'a, Self>
where
Self: Unpin,
{
assert_future::<Result<()>, _>(WriteAllVectored::new(self, bufs))
}
/// Wraps an [`AsyncWrite`] in a compatibility wrapper that allows it to be
/// used as a futures 0.1 / tokio-io 0.1 `AsyncWrite`.
/// Requires the `io-compat` feature to enable.
#[cfg(feature = "io-compat")]
#[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))]
fn compat_write(self) -> Compat<Self>
where
Self: Sized + Unpin,
{
Compat::new(self)
}
/// Allow using an [`AsyncWrite`] as a [`Sink`](futures_sink::Sink)`<Item: AsRef<[u8]>>`.
///
/// This adapter produces a sink that will write each value passed to it
/// into the underlying writer.
///
/// Note that this function consumes the given writer, returning a wrapped
/// version.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::AsyncWriteExt;
/// use futures::stream::{self, StreamExt};
///
/// let stream = stream::iter(vec![Ok([1, 2, 3]), Ok([4, 5, 6])]);
///
/// let mut writer = vec![];
///
/// stream.forward((&mut writer).into_sink()).await?;
///
/// assert_eq!(writer, vec![1, 2, 3, 4, 5, 6]);
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// # })?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
#[cfg(feature = "sink")]
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
fn into_sink<Item: AsRef<[u8]>>(self) -> IntoSink<Self, Item>
where
Self: Sized,
{
crate::sink::assert_sink::<Item, Error, _>(IntoSink::new(self))
}
}
impl<W: AsyncWrite + ?Sized> AsyncWriteExt for W {}
/// An extension trait which adds utility methods to `AsyncSeek` types.
pub trait AsyncSeekExt: AsyncSeek {
/// Creates a future which will seek an IO object, and then yield the
/// new position in the object and the object itself.
///
/// In the case of an error the buffer and the object will be discarded, with
/// the error yielded.
fn seek(&mut self, pos: SeekFrom) -> Seek<'_, Self>
where
Self: Unpin,
{
assert_future::<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 {}
/// An extension trait which adds utility methods to `AsyncBufRead` types.
pub trait AsyncBufReadExt: AsyncBufRead {
/// Creates a future which will wait for a non-empty buffer to be available from this I/O
/// object or EOF to be reached.
///
/// This method is the async equivalent to [`BufRead::fill_buf`](std::io::BufRead::fill_buf).
///
/// ```rust
/// # futures::executor::block_on(async {
/// use futures::{io::AsyncBufReadExt as _, stream::{iter, TryStreamExt as _}};
///
/// let mut stream = iter(vec![Ok(vec![1, 2, 3]), Ok(vec![4, 5, 6])]).into_async_read();
///
/// assert_eq!(stream.fill_buf().await?, vec![1, 2, 3]);
/// stream.consume_unpin(2);
///
/// assert_eq!(stream.fill_buf().await?, vec![3]);
/// stream.consume_unpin(1);
///
/// assert_eq!(stream.fill_buf().await?, vec![4, 5, 6]);
/// stream.consume_unpin(3);
///
/// assert_eq!(stream.fill_buf().await?, vec![]);
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn fill_buf(&mut self) -> FillBuf<'_, Self>
where
Self: Unpin,
{
assert_future::<Result<&[u8]>, _>(FillBuf::new(self))
}
/// A convenience for calling [`AsyncBufRead::consume`] on [`Unpin`] IO types.
///
/// ```rust
/// # futures::executor::block_on(async {
/// use futures::{io::AsyncBufReadExt as _, stream::{iter, TryStreamExt as _}};
///
/// let mut stream = iter(vec![Ok(vec![1, 2, 3])]).into_async_read();
///
/// assert_eq!(stream.fill_buf().await?, vec![1, 2, 3]);
/// stream.consume_unpin(2);
///
/// assert_eq!(stream.fill_buf().await?, vec![3]);
/// stream.consume_unpin(1);
///
/// assert_eq!(stream.fill_buf().await?, vec![]);
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn consume_unpin(&mut self, amt: usize)
where
Self: Unpin,
{
Pin::new(self).consume(amt)
}
/// Creates a future which will read all the bytes associated with this I/O
/// object into `buf` until the delimiter `byte` or EOF is reached.
/// This method is the async equivalent to [`BufRead::read_until`](std::io::BufRead::read_until).
///
/// This function will read bytes from the underlying stream until the
/// delimiter or EOF is found. Once found, all bytes up to, and including,
/// the delimiter (if found) will be appended to `buf`.
///
/// The returned future will resolve to the number of bytes read once the read
/// operation is completed.
///
/// In the case of an error the buffer and the object will be discarded, with
/// the error yielded.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{AsyncBufReadExt, Cursor};
///
/// let mut cursor = Cursor::new(b"lorem-ipsum");
/// let mut buf = vec![];
///
/// // cursor is at 'l'
/// let num_bytes = cursor.read_until(b'-', &mut buf).await?;
/// assert_eq!(num_bytes, 6);
/// assert_eq!(buf, b"lorem-");
/// buf.clear();
///
/// // cursor is at 'i'
/// let num_bytes = cursor.read_until(b'-', &mut buf).await?;
/// assert_eq!(num_bytes, 5);
/// assert_eq!(buf, b"ipsum");
/// buf.clear();
///
/// // cursor is at EOF
/// let num_bytes = cursor.read_until(b'-', &mut buf).await?;
/// assert_eq!(num_bytes, 0);
/// assert_eq!(buf, b"");
/// # Ok::<(), Box<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,
{
assert_future::<Result<usize>, _>(ReadUntil::new(self, byte, buf))
}
/// Creates a future which will read all the bytes associated with this I/O
/// object into `buf` until a newline (the 0xA byte) or EOF is reached,
/// This method is the async equivalent to [`BufRead::read_line`](std::io::BufRead::read_line).
///
/// This function will read bytes from the underlying stream until the
/// newline delimiter (the 0xA byte) or EOF is found. Once found, all bytes
/// up to, and including, the delimiter (if found) will be appended to
/// `buf`.
///
/// The returned future will resolve to the number of bytes read once the read
/// operation is completed.
///
/// In the case of an error the buffer and the object will be discarded, with
/// the error yielded.
///
/// # Errors
///
/// This function has the same error semantics as [`read_until`] and will
/// also return an error if the read bytes are not valid UTF-8. If an I/O
/// error is encountered then `buf` may contain some bytes already read in
/// the event that all data read so far was valid UTF-8.
///
/// [`read_until`]: AsyncBufReadExt::read_until
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{AsyncBufReadExt, Cursor};
///
/// let mut cursor = Cursor::new(b"foo\nbar");
/// let mut buf = String::new();
///
/// // cursor is at 'f'
/// let num_bytes = cursor.read_line(&mut buf).await?;
/// assert_eq!(num_bytes, 4);
/// assert_eq!(buf, "foo\n");
/// buf.clear();
///
/// // cursor is at 'b'
/// let num_bytes = cursor.read_line(&mut buf).await?;
/// assert_eq!(num_bytes, 3);
/// assert_eq!(buf, "bar");
/// buf.clear();
///
/// // cursor is at EOF
/// let num_bytes = cursor.read_line(&mut buf).await?;
/// assert_eq!(num_bytes, 0);
/// assert_eq!(buf, "");
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn read_line<'a>(&'a mut self, buf: &'a mut String) -> ReadLine<'a, Self>
where
Self: Unpin,
{
assert_future::<Result<usize>, _>(ReadLine::new(self, buf))
}
/// Returns a stream over the lines of this reader.
/// This method is the async equivalent to [`BufRead::lines`](std::io::BufRead::lines).
///
/// The stream returned from this function will yield instances of
/// [`io::Result`]`<`[`String`]`>`. Each string returned will *not* have a newline
/// byte (the 0xA byte) or CRLF (0xD, 0xA bytes) at the end.
///
/// [`io::Result`]: std::io::Result
/// [`String`]: String
///
/// # Errors
///
/// Each line of the stream has the same error semantics as [`AsyncBufReadExt::read_line`].
///
/// [`AsyncBufReadExt::read_line`]: AsyncBufReadExt::read_line
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{AsyncBufReadExt, Cursor};
/// use futures::stream::StreamExt;
///
/// let cursor = Cursor::new(b"lorem\nipsum\xc2\r\ndolor");
///
/// let mut lines_stream = cursor.lines().map(|l| l.unwrap_or(String::from("invalid UTF_8")));
/// assert_eq!(lines_stream.next().await, Some(String::from("lorem")));
/// assert_eq!(lines_stream.next().await, Some(String::from("invalid UTF_8")));
/// assert_eq!(lines_stream.next().await, Some(String::from("dolor")));
/// assert_eq!(lines_stream.next().await, None);
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
fn lines(self) -> Lines<Self>
where
Self: Sized,
{
assert_stream::<Result<String>, _>(Lines::new(self))
}
}
impl<R: AsyncBufRead + ?Sized> AsyncBufReadExt for R {}
// Just a helper function to ensure the reader we're returning all have the
// right implementations.
pub(crate) fn assert_read<R>(reader: R) -> R
where
R: AsyncRead,
{
reader
}
// Just a helper function to ensure the writer we're returning all have the
// right implementations.
pub(crate) fn assert_write<W>(writer: W) -> W
where
W: AsyncWrite,
{
writer
}

30
vendor/futures-util/src/io/read.rs vendored Normal file
View File

@@ -0,0 +1,30 @@
use crate::io::AsyncRead;
use futures_core::future::Future;
use futures_core::task::{Context, Poll};
use std::io;
use std::pin::Pin;
/// Future for the [`read`](super::AsyncReadExt::read) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Read<'a, R: ?Sized> {
reader: &'a mut R,
buf: &'a mut [u8],
}
impl<R: ?Sized + Unpin> Unpin for Read<'_, R> {}
impl<'a, R: AsyncRead + ?Sized + Unpin> Read<'a, R> {
pub(super) fn new(reader: &'a mut R, buf: &'a mut [u8]) -> Self {
Self { reader, buf }
}
}
impl<R: AsyncRead + ?Sized + Unpin> Future for Read<'_, R> {
type Output = io::Result<usize>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = &mut *self;
Pin::new(&mut this.reader).poll_read(cx, this.buf)
}
}

View File

@@ -0,0 +1,42 @@
use crate::io::AsyncRead;
use futures_core::future::Future;
use futures_core::ready;
use futures_core::task::{Context, Poll};
use std::io;
use std::mem;
use std::pin::Pin;
/// Future for the [`read_exact`](super::AsyncReadExt::read_exact) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct ReadExact<'a, R: ?Sized> {
reader: &'a mut R,
buf: &'a mut [u8],
}
impl<R: ?Sized + Unpin> Unpin for ReadExact<'_, R> {}
impl<'a, R: AsyncRead + ?Sized + Unpin> ReadExact<'a, R> {
pub(super) fn new(reader: &'a mut R, buf: &'a mut [u8]) -> Self {
Self { reader, buf }
}
}
impl<R: AsyncRead + ?Sized + Unpin> Future for ReadExact<'_, R> {
type Output = io::Result<()>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = &mut *self;
while !this.buf.is_empty() {
let n = ready!(Pin::new(&mut this.reader).poll_read(cx, this.buf))?;
{
let (_, rest) = mem::take(&mut this.buf).split_at_mut(n);
this.buf = rest;
}
if n == 0 {
return Poll::Ready(Err(io::ErrorKind::UnexpectedEof.into()));
}
}
Poll::Ready(Ok(()))
}
}

77
vendor/futures-util/src/io/read_line.rs vendored Normal file
View File

@@ -0,0 +1,77 @@
use super::read_until::read_until_internal;
use futures_core::future::Future;
use futures_core::ready;
use futures_core::task::{Context, Poll};
use futures_io::AsyncBufRead;
use std::io;
use std::mem;
use std::pin::Pin;
use std::str;
use std::string::String;
use std::vec::Vec;
/// Future for the [`read_line`](super::AsyncBufReadExt::read_line) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct ReadLine<'a, R: ?Sized> {
reader: &'a mut R,
buf: &'a mut String,
bytes: Vec<u8>,
read: usize,
finished: bool,
}
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::take(buf).into_bytes(), buf, read: 0, finished: false }
}
}
pub(super) fn read_line_internal<R: AsyncBufRead + ?Sized>(
reader: Pin<&mut R>,
cx: &mut Context<'_>,
buf: &mut String,
bytes: &mut Vec<u8>,
read: &mut usize,
) -> Poll<io::Result<usize>> {
let mut ret = ready!(read_until_internal(reader, cx, b'\n', bytes, read));
if str::from_utf8(&bytes[bytes.len() - *read..bytes.len()]).is_err() {
bytes.truncate(bytes.len() - *read);
if ret.is_ok() {
ret = Err(io::Error::new(
io::ErrorKind::InvalidData,
"stream did not contain valid UTF-8",
));
}
}
*read = 0;
// Safety: `bytes` is valid UTF-8 because it was taken from a String
// and the newly read bytes are either valid UTF-8 or have been removed.
mem::swap(unsafe { buf.as_mut_vec() }, bytes);
Poll::Ready(ret)
}
impl<R: AsyncBufRead + ?Sized + Unpin> Future for ReadLine<'_, R> {
type Output = io::Result<usize>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let Self { reader, buf, bytes, read, finished: _ } = &mut *self;
let ret = ready!(read_line_internal(Pin::new(reader), cx, buf, bytes, read));
self.finished = true;
Poll::Ready(ret)
}
}
impl<R: ?Sized> Drop for ReadLine<'_, R> {
fn drop(&mut self) {
// restore old string contents
if !self.finished {
self.bytes.truncate(self.bytes.len() - self.read);
// Safety: `bytes` is valid UTF-8 because it was taken from a String
// and the newly read bytes have been removed.
mem::swap(unsafe { self.buf.as_mut_vec() }, &mut self.bytes);
}
}
}

View File

@@ -0,0 +1,90 @@
use futures_core::future::Future;
use futures_core::ready;
use futures_core::task::{Context, Poll};
use futures_io::AsyncRead;
use std::io;
use std::iter;
use std::pin::Pin;
use std::vec::Vec;
/// Future for the [`read_to_end`](super::AsyncReadExt::read_to_end) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct ReadToEnd<'a, R: ?Sized> {
reader: &'a mut R,
buf: &'a mut Vec<u8>,
start_len: usize,
}
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 }
}
}
struct Guard<'a> {
buf: &'a mut Vec<u8>,
len: usize,
}
impl Drop for Guard<'_> {
fn drop(&mut self) {
unsafe {
self.buf.set_len(self.len);
}
}
}
// This uses an adaptive system to extend the vector when it fills. We want to
// avoid paying to allocate and zero a huge chunk of memory if the reader only
// has 4 bytes while still making large reads if the reader does have a ton
// of data to return. Simply tacking on an extra DEFAULT_BUF_SIZE space every
// time is 4,500 times (!) slower than this if the reader has a very small
// amount of data to return.
//
// Because we're extending the buffer with uninitialized data for trusted
// readers, we need to make sure to truncate that if any of this panics.
pub(super) fn read_to_end_internal<R: AsyncRead + ?Sized>(
mut rd: Pin<&mut R>,
cx: &mut Context<'_>,
buf: &mut Vec<u8>,
start_len: usize,
) -> Poll<io::Result<usize>> {
let mut g = Guard { len: buf.len(), buf };
loop {
if g.len == g.buf.len() {
g.buf.reserve(32);
let spare_capacity = g.buf.capacity() - g.buf.len();
// FIXME: switch to `Vec::resize` once rust-lang/rust#120050 is fixed
g.buf.extend(iter::repeat(0).take(spare_capacity));
}
let buf = &mut g.buf[g.len..];
match ready!(rd.as_mut().poll_read(cx, buf)) {
Ok(0) => return Poll::Ready(Ok(g.len - start_len)),
Ok(n) => {
// We can't allow bogus values from read. If it is too large, the returned vec could have its length
// set past its capacity, or if it overflows the vec could be shortened which could create an invalid
// string if this is called via read_to_string.
assert!(n <= buf.len());
g.len += n;
}
Err(e) => return Poll::Ready(Err(e)),
}
}
}
impl<A> Future for ReadToEnd<'_, A>
where
A: AsyncRead + ?Sized + Unpin,
{
type Output = io::Result<usize>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = &mut *self;
read_to_end_internal(Pin::new(&mut this.reader), cx, this.buf, this.start_len)
}
}

View File

@@ -0,0 +1,60 @@
use super::read_to_end::read_to_end_internal;
use futures_core::future::Future;
use futures_core::ready;
use futures_core::task::{Context, Poll};
use futures_io::AsyncRead;
use std::pin::Pin;
use std::string::String;
use std::vec::Vec;
use std::{io, mem, str};
/// Future for the [`read_to_string`](super::AsyncReadExt::read_to_string) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct ReadToString<'a, R: ?Sized> {
reader: &'a mut R,
buf: &'a mut String,
bytes: Vec<u8>,
start_len: usize,
}
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::take(buf).into_bytes(), buf, start_len }
}
}
fn read_to_string_internal<R: AsyncRead + ?Sized>(
reader: Pin<&mut R>,
cx: &mut Context<'_>,
buf: &mut String,
bytes: &mut Vec<u8>,
start_len: usize,
) -> Poll<io::Result<usize>> {
let ret = ready!(read_to_end_internal(reader, cx, bytes, start_len));
if str::from_utf8(bytes).is_err() {
Poll::Ready(ret.and_then(|_| {
Err(io::Error::new(io::ErrorKind::InvalidData, "stream did not contain valid UTF-8"))
}))
} else {
debug_assert!(buf.is_empty());
// Safety: `bytes` is a valid UTF-8 because `str::from_utf8` returned `Ok`.
mem::swap(unsafe { buf.as_mut_vec() }, bytes);
Poll::Ready(ret)
}
}
impl<A> Future for ReadToString<'_, A>
where
A: AsyncRead + ?Sized + Unpin,
{
type Output = io::Result<usize>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let Self { reader, buf, bytes, start_len } = &mut *self;
read_to_string_internal(Pin::new(reader), cx, buf, bytes, *start_len)
}
}

View File

@@ -0,0 +1,60 @@
use futures_core::future::Future;
use futures_core::ready;
use futures_core::task::{Context, Poll};
use futures_io::AsyncBufRead;
use std::io;
use std::pin::Pin;
use std::vec::Vec;
/// Future for the [`read_until`](super::AsyncBufReadExt::read_until) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct ReadUntil<'a, R: ?Sized> {
reader: &'a mut R,
byte: u8,
buf: &'a mut Vec<u8>,
read: usize,
}
impl<R: ?Sized + Unpin> Unpin for ReadUntil<'_, R> {}
impl<'a, R: AsyncBufRead + ?Sized + Unpin> ReadUntil<'a, R> {
pub(super) fn new(reader: &'a mut R, byte: u8, buf: &'a mut Vec<u8>) -> Self {
Self { reader, byte, buf, read: 0 }
}
}
pub(super) fn read_until_internal<R: AsyncBufRead + ?Sized>(
mut reader: Pin<&mut R>,
cx: &mut Context<'_>,
byte: u8,
buf: &mut Vec<u8>,
read: &mut usize,
) -> Poll<io::Result<usize>> {
loop {
let (done, used) = {
let available = ready!(reader.as_mut().poll_fill_buf(cx))?;
if let Some(i) = memchr::memchr(byte, available) {
buf.extend_from_slice(&available[..=i]);
(true, i + 1)
} else {
buf.extend_from_slice(available);
(false, available.len())
}
};
reader.as_mut().consume(used);
*read += used;
if done || used == 0 {
return Poll::Ready(Ok(*read));
}
}
}
impl<R: AsyncBufRead + ?Sized + Unpin> Future for ReadUntil<'_, R> {
type Output = io::Result<usize>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let Self { reader, byte, buf, read } = &mut *self;
read_until_internal(Pin::new(reader), cx, *byte, buf, read)
}
}

View File

@@ -0,0 +1,30 @@
use crate::io::AsyncRead;
use futures_core::future::Future;
use futures_core::task::{Context, Poll};
use std::io::{self, IoSliceMut};
use std::pin::Pin;
/// Future for the [`read_vectored`](super::AsyncReadExt::read_vectored) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct ReadVectored<'a, R: ?Sized> {
reader: &'a mut R,
bufs: &'a mut [IoSliceMut<'a>],
}
impl<R: ?Sized + Unpin> Unpin for ReadVectored<'_, R> {}
impl<'a, R: AsyncRead + ?Sized + Unpin> ReadVectored<'a, R> {
pub(super) fn new(reader: &'a mut R, bufs: &'a mut [IoSliceMut<'a>]) -> Self {
Self { reader, bufs }
}
}
impl<R: AsyncRead + ?Sized + Unpin> Future for ReadVectored<'_, R> {
type Output = io::Result<usize>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = &mut *self;
Pin::new(&mut this.reader).poll_read_vectored(cx, this.bufs)
}
}

66
vendor/futures-util/src/io/repeat.rs vendored Normal file
View File

@@ -0,0 +1,66 @@
use futures_core::ready;
use futures_core::task::{Context, Poll};
use futures_io::{AsyncRead, IoSliceMut};
use std::fmt;
use std::io;
use std::pin::Pin;
/// Reader for the [`repeat()`] function.
#[must_use = "readers do nothing unless polled"]
pub struct Repeat {
byte: u8,
}
/// Creates an instance of a reader that infinitely repeats one byte.
///
/// All reads from this reader will succeed by filling the specified buffer with
/// the given byte.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{self, AsyncReadExt};
///
/// let mut buffer = [0; 3];
/// let mut reader = io::repeat(0b101);
/// reader.read_exact(&mut buffer).await.unwrap();
/// assert_eq!(buffer, [0b101, 0b101, 0b101]);
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
pub fn repeat(byte: u8) -> Repeat {
Repeat { byte }
}
impl AsyncRead for Repeat {
#[inline]
fn poll_read(
self: Pin<&mut Self>,
_: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
for slot in &mut *buf {
*slot = self.byte;
}
Poll::Ready(Ok(buf.len()))
}
#[inline]
fn poll_read_vectored(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &mut [IoSliceMut<'_>],
) -> Poll<io::Result<usize>> {
let mut nwritten = 0;
for buf in bufs {
nwritten += ready!(self.as_mut().poll_read(cx, buf))?;
}
Poll::Ready(Ok(nwritten))
}
}
impl fmt::Debug for Repeat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.pad("Repeat { .. }")
}
}

30
vendor/futures-util/src/io/seek.rs vendored Normal file
View File

@@ -0,0 +1,30 @@
use crate::io::{AsyncSeek, SeekFrom};
use futures_core::future::Future;
use futures_core::task::{Context, Poll};
use std::io;
use std::pin::Pin;
/// Future for the [`seek`](crate::io::AsyncSeekExt::seek) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Seek<'a, S: ?Sized> {
seek: &'a mut S,
pos: SeekFrom,
}
impl<S: ?Sized + Unpin> Unpin for Seek<'_, S> {}
impl<'a, S: AsyncSeek + ?Sized + Unpin> Seek<'a, S> {
pub(super) fn new(seek: &'a mut S, pos: SeekFrom) -> Self {
Self { seek, pos }
}
}
impl<S: AsyncSeek + ?Sized + Unpin> Future for Seek<'_, S> {
type Output = io::Result<u64>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = &mut *self;
Pin::new(&mut this.seek).poll_seek(cx, this.pos)
}
}

67
vendor/futures-util/src/io/sink.rs vendored Normal file
View File

@@ -0,0 +1,67 @@
use futures_core::task::{Context, Poll};
use futures_io::{AsyncWrite, IoSlice};
use std::fmt;
use std::io;
use std::pin::Pin;
/// Writer for the [`sink()`] function.
#[must_use = "writers do nothing unless polled"]
pub struct Sink {
_priv: (),
}
/// Creates an instance of a writer which will successfully consume all data.
///
/// All calls to `poll_write` on the returned instance will return `Poll::Ready(Ok(buf.len()))`
/// and the contents of the buffer will not be inspected.
///
/// # Examples
///
/// ```rust
/// # futures::executor::block_on(async {
/// use futures::io::{self, AsyncWriteExt};
///
/// let buffer = vec![1, 2, 3, 5, 8];
/// let mut writer = io::sink();
/// let num_bytes = writer.write(&buffer).await?;
/// assert_eq!(num_bytes, 5);
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
pub fn sink() -> Sink {
Sink { _priv: () }
}
impl AsyncWrite for Sink {
#[inline]
fn poll_write(
self: Pin<&mut Self>,
_: &mut Context<'_>,
buf: &[u8],
) -> Poll<io::Result<usize>> {
Poll::Ready(Ok(buf.len()))
}
#[inline]
fn poll_write_vectored(
self: Pin<&mut Self>,
_: &mut Context<'_>,
bufs: &[IoSlice<'_>],
) -> Poll<io::Result<usize>> {
Poll::Ready(Ok(bufs.iter().map(|b| b.len()).sum()))
}
#[inline]
fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
Poll::Ready(Ok(()))
}
#[inline]
fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
Poll::Ready(Ok(()))
}
}
impl fmt::Debug for Sink {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.pad("Sink { .. }")
}
}

129
vendor/futures-util/src/io/split.rs vendored Normal file
View File

@@ -0,0 +1,129 @@
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 std::io;
use std::pin::Pin;
/// The readable half of an object returned from `AsyncRead::split`.
#[derive(Debug)]
pub struct ReadHalf<T> {
handle: BiLock<T>,
}
/// The writable half of an object returned from `AsyncRead::split`.
#[derive(Debug)]
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>>,
{
let mut l = ready!(lock.poll_lock(cx));
f(l.as_pin_mut(), cx)
}
pub(super) fn split<T: AsyncRead + AsyncWrite>(t: T) -> (ReadHalf<T>, WriteHalf<T>) {
let (a, b) = BiLock::new(t);
(ReadHalf { handle: a }, WriteHalf { handle: b })
}
impl<T> ReadHalf<T> {
/// Checks if this `ReadHalf` and some `WriteHalf` were split from the same stream.
pub fn is_pair_of(&self, other: &WriteHalf<T>) -> bool {
self.handle.is_pair_of(&other.handle)
}
}
impl<T: Unpin> ReadHalf<T> {
/// Attempts to put the two "halves" of a split `AsyncRead + AsyncWrite` back
/// 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(Self { handle: err.0 }, WriteHalf { handle: err.1 }))
}
}
impl<T> WriteHalf<T> {
/// Checks if this `WriteHalf` and some `ReadHalf` were split from the same stream.
pub fn is_pair_of(&self, other: &ReadHalf<T>) -> bool {
self.handle.is_pair_of(&other.handle)
}
}
impl<T: Unpin> WriteHalf<T> {
/// Attempts to put the two "halves" of a split `AsyncRead + AsyncWrite` back
/// 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: ReadHalf<T>) -> Result<T, ReuniteError<T>> {
other.reunite(self)
}
}
impl<R: AsyncRead> AsyncRead for ReadHalf<R> {
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>> {
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>> {
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>> {
lock_and_then(&self.handle, cx, |l, cx| l.poll_write_vectored(cx, bufs))
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
lock_and_then(&self.handle, cx, |l, cx| l.poll_flush(cx))
}
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
lock_and_then(&self.handle, cx, |l, cx| l.poll_close(cx))
}
}
/// Error indicating a `ReadHalf<T>` and `WriteHalf<T>` were not two halves
/// of a `AsyncRead + AsyncWrite`, and thus could not be `reunite`d.
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()
}
}
impl<T> fmt::Display for ReuniteError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "tried to reunite a ReadHalf and WriteHalf that don't form a pair")
}
}
#[cfg(feature = "std")]
impl<T: core::any::Any> std::error::Error for ReuniteError<T> {}

125
vendor/futures-util/src/io/take.rs vendored Normal file
View File

@@ -0,0 +1,125 @@
use futures_core::ready;
use futures_core::task::{Context, Poll};
use futures_io::{AsyncBufRead, AsyncRead};
use pin_project_lite::pin_project;
use std::pin::Pin;
use std::{cmp, io};
pin_project! {
/// Reader for the [`take`](super::AsyncReadExt::take) method.
#[derive(Debug)]
#[must_use = "readers do nothing unless you `.await` or poll them"]
pub struct Take<R> {
#[pin]
inner: R,
limit: u64,
}
}
impl<R: AsyncRead> Take<R> {
pub(super) fn new(inner: R, limit: u64) -> Self {
Self { inner, limit }
}
/// Returns the remaining number of bytes that can be
/// read before this instance will return EOF.
///
/// # Note
///
/// This instance may reach `EOF` after reading fewer bytes than indicated by
/// this method if the underlying [`AsyncRead`] instance reaches EOF.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{AsyncReadExt, Cursor};
///
/// let reader = Cursor::new(&b"12345678"[..]);
/// let mut buffer = [0; 2];
///
/// let mut take = reader.take(4);
/// let n = take.read(&mut buffer).await?;
///
/// assert_eq!(take.limit(), 2);
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
pub fn limit(&self) -> u64 {
self.limit
}
/// Sets the number of bytes that can be read before this instance will
/// return EOF. This is the same as constructing a new `Take` instance, so
/// the amount of bytes read and the previous limit value don't matter when
/// calling this method.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::io::{AsyncReadExt, Cursor};
///
/// let reader = Cursor::new(&b"12345678"[..]);
/// let mut buffer = [0; 4];
///
/// let mut take = reader.take(4);
/// let n = take.read(&mut buffer).await?;
///
/// assert_eq!(n, 4);
/// assert_eq!(take.limit(), 0);
///
/// take.set_limit(10);
/// let n = take.read(&mut buffer).await?;
/// assert_eq!(n, 4);
///
/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
/// ```
pub fn set_limit(&mut self, limit: u64) {
self.limit = limit
}
delegate_access_inner!(inner, R, ());
}
impl<R: AsyncRead> AsyncRead for Take<R> {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<Result<usize, io::Error>> {
let this = self.project();
if *this.limit == 0 {
return Poll::Ready(Ok(0));
}
let max = cmp::min(buf.len() as u64, *this.limit) as usize;
let n = ready!(this.inner.poll_read(cx, &mut buf[..max]))?;
*this.limit -= n as u64;
Poll::Ready(Ok(n))
}
}
impl<R: AsyncBufRead> AsyncBufRead for Take<R> {
fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
let this = self.project();
// Don't call into inner reader at all at EOF because it may still block
if *this.limit == 0 {
return Poll::Ready(Ok(&[]));
}
let buf = ready!(this.inner.poll_fill_buf(cx)?);
let cap = cmp::min(buf.len() as u64, *this.limit) as usize;
Poll::Ready(Ok(&buf[..cap]))
}
fn consume(self: Pin<&mut Self>, amt: usize) {
let this = self.project();
// Don't let callers reset the limit by passing an overlarge value
let amt = cmp::min(amt as u64, *this.limit) as usize;
*this.limit -= amt as u64;
this.inner.consume(amt);
}
}

104
vendor/futures-util/src/io/window.rs vendored Normal file
View File

@@ -0,0 +1,104 @@
use std::ops::{Bound, Range, RangeBounds};
/// An owned window around an underlying buffer.
///
/// Normally slices work great for considering sub-portions of a buffer, but
/// unfortunately a slice is a *borrowed* type in Rust which has an associated
/// lifetime. When working with future and async I/O these lifetimes are not
/// always appropriate, and are sometimes difficult to store in tasks. This
/// type strives to fill this gap by providing an "owned slice" around an
/// underlying buffer of bytes.
///
/// A `Window<T>` wraps an underlying buffer, `T`, and has configurable
/// start/end indexes to alter the behavior of the `AsRef<[u8]>` implementation
/// that this type carries.
///
/// This type can be particularly useful when working with the `write_all`
/// combinator in this crate. Data can be sliced via `Window`, consumed by
/// `write_all`, and then earned back once the write operation finishes through
/// the `into_inner` method on this type.
#[derive(Debug)]
pub struct Window<T> {
inner: T,
range: Range<usize>,
}
impl<T: AsRef<[u8]>> Window<T> {
/// Creates a new window around the buffer `t` defaulting to the entire
/// slice.
///
/// 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 }
}
/// Gets a shared reference to the underlying buffer inside of this
/// `Window`.
pub fn get_ref(&self) -> &T {
&self.inner
}
/// Gets a mutable reference to the underlying buffer inside of this
/// `Window`.
pub fn get_mut(&mut self) -> &mut T {
&mut self.inner
}
/// Consumes this `Window`, returning the underlying buffer.
pub fn into_inner(self) -> T {
self.inner
}
/// Returns the starting index of this window into the underlying buffer
/// `T`.
pub fn start(&self) -> usize {
self.range.start
}
/// Returns the end index of this window into the underlying buffer
/// `T`.
pub fn end(&self) -> usize {
self.range.end
}
/// Changes the range of this window to the range specified.
///
/// # Panics
///
/// This method will panic if `range` is out of bounds for the underlying
/// slice or if [`start_bound()`] of `range` comes after the [`end_bound()`].
///
/// [`start_bound()`]: std::ops::RangeBounds::start_bound
/// [`end_bound()`]: std::ops::RangeBounds::end_bound
pub fn set<R: RangeBounds<usize>>(&mut self, range: R) {
let start = match range.start_bound() {
Bound::Included(n) => *n,
Bound::Excluded(n) => *n + 1,
Bound::Unbounded => 0,
};
let end = match range.end_bound() {
Bound::Included(n) => *n + 1,
Bound::Excluded(n) => *n,
Bound::Unbounded => self.inner.as_ref().len(),
};
assert!(end <= self.inner.as_ref().len());
assert!(start <= end);
self.range.start = start;
self.range.end = end;
}
}
impl<T: AsRef<[u8]>> AsRef<[u8]> for Window<T> {
fn as_ref(&self) -> &[u8] {
&self.inner.as_ref()[self.range.start..self.range.end]
}
}
impl<T: AsMut<[u8]>> AsMut<[u8]> for Window<T> {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.inner.as_mut()[self.range.start..self.range.end]
}
}

30
vendor/futures-util/src/io/write.rs vendored Normal file
View File

@@ -0,0 +1,30 @@
use crate::io::AsyncWrite;
use futures_core::future::Future;
use futures_core::task::{Context, Poll};
use std::io;
use std::pin::Pin;
/// Future for the [`write`](super::AsyncWriteExt::write) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Write<'a, W: ?Sized> {
writer: &'a mut W,
buf: &'a [u8],
}
impl<W: ?Sized + Unpin> Unpin for Write<'_, W> {}
impl<'a, W: AsyncWrite + ?Sized + Unpin> Write<'a, W> {
pub(super) fn new(writer: &'a mut W, buf: &'a [u8]) -> Self {
Self { writer, buf }
}
}
impl<W: AsyncWrite + ?Sized + Unpin> Future for Write<'_, W> {
type Output = io::Result<usize>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = &mut *self;
Pin::new(&mut this.writer).poll_write(cx, this.buf)
}
}

43
vendor/futures-util/src/io/write_all.rs vendored Normal file
View File

@@ -0,0 +1,43 @@
use futures_core::future::Future;
use futures_core::ready;
use futures_core::task::{Context, Poll};
use futures_io::AsyncWrite;
use std::io;
use std::mem;
use std::pin::Pin;
/// Future for the [`write_all`](super::AsyncWriteExt::write_all) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct WriteAll<'a, W: ?Sized> {
writer: &'a mut W,
buf: &'a [u8],
}
impl<W: ?Sized + Unpin> Unpin for WriteAll<'_, W> {}
impl<'a, W: AsyncWrite + ?Sized + Unpin> WriteAll<'a, W> {
pub(super) fn new(writer: &'a mut W, buf: &'a [u8]) -> Self {
Self { writer, buf }
}
}
impl<W: AsyncWrite + ?Sized + Unpin> Future for WriteAll<'_, W> {
type Output = io::Result<()>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
let this = &mut *self;
while !this.buf.is_empty() {
let n = ready!(Pin::new(&mut this.writer).poll_write(cx, this.buf))?;
{
let (_, rest) = mem::take(&mut this.buf).split_at(n);
this.buf = rest;
}
if n == 0 {
return Poll::Ready(Err(io::ErrorKind::WriteZero.into()));
}
}
Poll::Ready(Ok(()))
}
}

View File

@@ -0,0 +1,195 @@
use futures_core::future::Future;
use futures_core::ready;
use futures_core::task::{Context, Poll};
use futures_io::AsyncWrite;
use futures_io::IoSlice;
use std::io;
use std::pin::Pin;
/// Future for the
/// [`write_all_vectored`](super::AsyncWriteExt::write_all_vectored) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct WriteAllVectored<'a, W: ?Sized + Unpin> {
writer: &'a mut W,
bufs: &'a mut [IoSlice<'a>],
}
impl<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 }
}
}
impl<W: AsyncWrite + ?Sized + Unpin> Future for WriteAllVectored<'_, W> {
type Output = io::Result<()>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
let this = &mut *self;
while !this.bufs.is_empty() {
let n = ready!(Pin::new(&mut this.writer).poll_write_vectored(cx, this.bufs))?;
if n == 0 {
return Poll::Ready(Err(io::ErrorKind::WriteZero.into()));
} else {
IoSlice::advance_slices(&mut this.bufs, n);
}
}
Poll::Ready(Ok(()))
}
}
#[cfg(test)]
mod tests {
use std::cmp::min;
use std::future::Future;
use std::io;
use std::pin::Pin;
use std::task::{Context, Poll};
use std::vec;
use std::vec::Vec;
use crate::io::{AsyncWrite, AsyncWriteExt, IoSlice};
use crate::task::noop_waker;
/// Create a new writer that reads from at most `n_bufs` and reads
/// `per_call` bytes (in total) per call to write.
fn test_writer(n_bufs: usize, per_call: usize) -> TestWriter {
TestWriter { n_bufs, per_call, written: Vec::new() }
}
// TODO: maybe move this the future-test crate?
struct TestWriter {
n_bufs: usize,
per_call: usize,
written: Vec<u8>,
}
impl AsyncWrite for TestWriter {
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<io::Result<usize>> {
self.poll_write_vectored(cx, &[IoSlice::new(buf)])
}
fn poll_write_vectored(
mut self: Pin<&mut Self>,
_cx: &mut Context<'_>,
bufs: &[IoSlice<'_>],
) -> Poll<io::Result<usize>> {
let mut left = self.per_call;
let mut written = 0;
for buf in bufs.iter().take(self.n_bufs) {
let n = min(left, buf.len());
self.written.extend_from_slice(&buf[0..n]);
left -= n;
written += n;
}
Poll::Ready(Ok(written))
}
fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
Poll::Ready(Ok(()))
}
fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
Poll::Ready(Ok(()))
}
}
// TODO: maybe move this the future-test crate?
macro_rules! assert_poll_ok {
($e:expr, $expected:expr) => {
let expected = $expected;
match $e {
Poll::Ready(Ok(ok)) if ok == expected => {}
got => {
panic!("unexpected result, got: {:?}, wanted: Ready(Ok({:?}))", got, expected)
}
}
};
}
#[test]
fn test_writer_read_from_one_buf() {
let waker = noop_waker();
let mut cx = Context::from_waker(&waker);
let mut dst = test_writer(1, 2);
let mut dst = Pin::new(&mut dst);
assert_poll_ok!(dst.as_mut().poll_write(&mut cx, &[]), 0);
assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, &[]), 0);
// Read at most 2 bytes.
assert_poll_ok!(dst.as_mut().poll_write(&mut cx, &[1, 1, 1]), 2);
let bufs = &[IoSlice::new(&[2, 2, 2])];
assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, bufs), 2);
// Only read from first buf.
let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4, 4])];
assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, bufs), 1);
assert_eq!(dst.written, &[1, 1, 2, 2, 3]);
}
#[test]
fn test_writer_read_from_multiple_bufs() {
let waker = noop_waker();
let mut cx = Context::from_waker(&waker);
let mut dst = test_writer(3, 3);
let mut dst = Pin::new(&mut dst);
// Read at most 3 bytes from two buffers.
let bufs = &[IoSlice::new(&[1]), IoSlice::new(&[2, 2, 2])];
assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, bufs), 3);
// Read at most 3 bytes from three buffers.
let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4]), IoSlice::new(&[5, 5])];
assert_poll_ok!(dst.as_mut().poll_write_vectored(&mut cx, bufs), 3);
assert_eq!(dst.written, &[1, 2, 2, 3, 4, 5]);
}
#[test]
fn test_write_all_vectored() {
let waker = noop_waker();
let mut cx = Context::from_waker(&waker);
#[rustfmt::skip] // Becomes unreadable otherwise.
let tests: Vec<(_, &'static [u8])> = vec![
(vec![], &[]),
(vec![IoSlice::new(&[]), IoSlice::new(&[])], &[]),
(vec![IoSlice::new(&[1])], &[1]),
(vec![IoSlice::new(&[1, 2])], &[1, 2]),
(vec![IoSlice::new(&[1, 2, 3])], &[1, 2, 3]),
(vec![IoSlice::new(&[1, 2, 3, 4])], &[1, 2, 3, 4]),
(vec![IoSlice::new(&[1, 2, 3, 4, 5])], &[1, 2, 3, 4, 5]),
(vec![IoSlice::new(&[1]), IoSlice::new(&[2])], &[1, 2]),
(vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2])], &[1, 1, 2, 2]),
(vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 1, 2, 2, 2]),
(vec![IoSlice::new(&[1, 1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 1, 2, 2, 2, 2]),
(vec![IoSlice::new(&[1]), IoSlice::new(&[2]), IoSlice::new(&[3])], &[1, 2, 3]),
(vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3])], &[1, 1, 2, 2, 3, 3]),
(vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 1, 1, 2, 2, 2, 3, 3, 3]),
];
for (mut input, wanted) in tests {
let mut dst = test_writer(2, 2);
{
let mut future = dst.write_all_vectored(&mut *input);
match Pin::new(&mut future).poll(&mut cx) {
Poll::Ready(Ok(())) => {}
other => panic!("unexpected result polling future: {:?}", other),
}
}
assert_eq!(&*dst.written, &*wanted);
}
}
}

View File

@@ -0,0 +1,30 @@
use crate::io::AsyncWrite;
use futures_core::future::Future;
use futures_core::task::{Context, Poll};
use std::io::{self, IoSlice};
use std::pin::Pin;
/// Future for the [`write_vectored`](super::AsyncWriteExt::write_vectored) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct WriteVectored<'a, W: ?Sized> {
writer: &'a mut W,
bufs: &'a [IoSlice<'a>],
}
impl<W: ?Sized + Unpin> Unpin for WriteVectored<'_, W> {}
impl<'a, W: AsyncWrite + ?Sized + Unpin> WriteVectored<'a, W> {
pub(super) fn new(writer: &'a mut W, bufs: &'a [IoSlice<'a>]) -> Self {
Self { writer, bufs }
}
}
impl<W: AsyncWrite + ?Sized + Unpin> Future for WriteVectored<'_, W> {
type Output = io::Result<usize>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = &mut *self;
Pin::new(&mut this.writer).poll_write_vectored(cx, this.bufs)
}
}

332
vendor/futures-util/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,332 @@
//! Combinators and utilities for working with `Future`s, `Stream`s, `Sink`s,
//! and the `AsyncRead` and `AsyncWrite` traits.
#![no_std]
#![doc(test(
no_crate_inject,
attr(
deny(warnings, rust_2018_idioms, single_use_lifetimes),
allow(dead_code, unused_assignments, unused_variables)
)
))]
#![warn(missing_docs, unsafe_op_in_unsafe_fn)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#[cfg(all(feature = "bilock", not(feature = "unstable")))]
compile_error!("The `bilock` feature requires the `unstable` feature as an explicit opt-in to unstable features");
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
// Macro re-exports
pub use futures_core::ready;
#[cfg(feature = "async-await")]
#[macro_use]
mod async_await;
#[cfg(feature = "async-await")]
#[doc(hidden)]
pub use self::async_await::*;
// Not public API.
#[doc(hidden)]
pub mod __private {
pub use crate::*;
pub use core::{
option::Option::{self, None, Some},
pin::Pin,
result::Result::{Err, Ok},
};
#[cfg(feature = "async-await")]
pub mod async_await {
pub use crate::async_await::*;
}
}
#[cfg(feature = "sink")]
macro_rules! delegate_sink {
($field:ident, $item:ty) => {
fn poll_ready(
self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
) -> core::task::Poll<Result<(), Self::Error>> {
self.project().$field.poll_ready(cx)
}
fn start_send(self: core::pin::Pin<&mut Self>, item: $item) -> Result<(), Self::Error> {
self.project().$field.start_send(item)
}
fn poll_flush(
self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
) -> core::task::Poll<Result<(), Self::Error>> {
self.project().$field.poll_flush(cx)
}
fn poll_close(
self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
) -> core::task::Poll<Result<(), Self::Error>> {
self.project().$field.poll_close(cx)
}
};
}
macro_rules! delegate_future {
($field:ident) => {
fn poll(
self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
) -> core::task::Poll<Self::Output> {
self.project().$field.poll(cx)
}
};
}
macro_rules! delegate_stream {
($field:ident) => {
fn poll_next(
self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
) -> core::task::Poll<Option<Self::Item>> {
self.project().$field.poll_next(cx)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.$field.size_hint()
}
};
}
#[cfg(feature = "io")]
#[cfg(feature = "std")]
macro_rules! delegate_async_write {
($field:ident) => {
fn poll_write(
self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
buf: &[u8],
) -> core::task::Poll<std::io::Result<usize>> {
self.project().$field.poll_write(cx, buf)
}
fn poll_write_vectored(
self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
bufs: &[std::io::IoSlice<'_>],
) -> core::task::Poll<std::io::Result<usize>> {
self.project().$field.poll_write_vectored(cx, bufs)
}
fn poll_flush(
self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
) -> core::task::Poll<std::io::Result<()>> {
self.project().$field.poll_flush(cx)
}
fn poll_close(
self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
) -> core::task::Poll<std::io::Result<()>> {
self.project().$field.poll_close(cx)
}
};
}
#[cfg(feature = "io")]
#[cfg(feature = "std")]
macro_rules! delegate_async_read {
($field:ident) => {
fn poll_read(
self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
buf: &mut [u8],
) -> core::task::Poll<std::io::Result<usize>> {
self.project().$field.poll_read(cx, buf)
}
fn poll_read_vectored(
self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
bufs: &mut [std::io::IoSliceMut<'_>],
) -> core::task::Poll<std::io::Result<usize>> {
self.project().$field.poll_read_vectored(cx, bufs)
}
};
}
#[cfg(feature = "io")]
#[cfg(feature = "std")]
macro_rules! delegate_async_buf_read {
($field:ident) => {
fn poll_fill_buf(
self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
) -> core::task::Poll<std::io::Result<&[u8]>> {
self.project().$field.poll_fill_buf(cx)
}
fn consume(self: core::pin::Pin<&mut Self>, amt: usize) {
self.project().$field.consume(amt)
}
};
}
macro_rules! delegate_access_inner {
($field:ident, $inner:ty, ($($ind:tt)*)) => {
/// Acquires a reference to the underlying sink or stream that this combinator is
/// pulling from.
pub fn get_ref(&self) -> &$inner {
(&self.$field) $($ind get_ref())*
}
/// Acquires a mutable reference to the underlying sink or stream that this
/// combinator is pulling from.
///
/// Note that care must be taken to avoid tampering with the state of the
/// sink or stream which may otherwise confuse this combinator.
pub fn get_mut(&mut self) -> &mut $inner {
(&mut self.$field) $($ind get_mut())*
}
/// Acquires a pinned mutable reference to the underlying sink or stream that this
/// combinator is pulling from.
///
/// Note that care must be taken to avoid tampering with the state of the
/// sink or stream which may otherwise confuse this combinator.
pub fn get_pin_mut(self: core::pin::Pin<&mut Self>) -> core::pin::Pin<&mut $inner> {
self.project().$field $($ind get_pin_mut())*
}
/// Consumes this combinator, returning the underlying sink or stream.
///
/// Note that this may discard intermediate state of this combinator, so
/// care should be taken to avoid losing resources when this is called.
pub fn into_inner(self) -> $inner {
self.$field $($ind into_inner())*
}
}
}
macro_rules! delegate_all {
(@trait Future $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => {
impl<$($arg),*> futures_core::future::Future for $name<$($arg),*> where $t: futures_core::future::Future $(, $($bound)*)* {
type Output = <$t as futures_core::future::Future>::Output;
delegate_future!(inner);
}
};
(@trait FusedFuture $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => {
impl<$($arg),*> futures_core::future::FusedFuture for $name<$($arg),*> where $t: futures_core::future::FusedFuture $(, $($bound)*)* {
fn is_terminated(&self) -> bool {
self.inner.is_terminated()
}
}
};
(@trait Stream $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => {
impl<$($arg),*> futures_core::stream::Stream for $name<$($arg),*> where $t: futures_core::stream::Stream $(, $($bound)*)* {
type Item = <$t as futures_core::stream::Stream>::Item;
delegate_stream!(inner);
}
};
(@trait FusedStream $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => {
impl<$($arg),*> futures_core::stream::FusedStream for $name<$($arg),*> where $t: futures_core::stream::FusedStream $(, $($bound)*)* {
fn is_terminated(&self) -> bool {
self.inner.is_terminated()
}
}
};
(@trait Sink $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => {
#[cfg(feature = "sink")]
impl<_Item, $($arg),*> futures_sink::Sink<_Item> for $name<$($arg),*> where $t: futures_sink::Sink<_Item> $(, $($bound)*)* {
type Error = <$t as futures_sink::Sink<_Item>>::Error;
delegate_sink!(inner, _Item);
}
};
(@trait Debug $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => {
impl<$($arg),*> core::fmt::Debug for $name<$($arg),*> where $t: core::fmt::Debug $(, $($bound)*)* {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
core::fmt::Debug::fmt(&self.inner, f)
}
}
};
(@trait AccessInner[$inner:ty, ($($ind:tt)*)] $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => {
impl<$($arg),*> $name<$($arg),*> $(where $($bound)*)* {
delegate_access_inner!(inner, $inner, ($($ind)*));
}
};
(@trait New[|$($param:ident: $paramt:ty),*| $cons:expr] $name:ident < $($arg:ident),* > ($t:ty) $(where $($bound:tt)*)*) => {
impl<$($arg),*> $name<$($arg),*> $(where $($bound)*)* {
pub(crate) fn new($($param: $paramt),*) -> Self {
Self { inner: $cons }
}
}
};
($(#[$attr:meta])* $name:ident<$($arg:ident),*>($t:ty) : $ftrait:ident $([$($targs:tt)*])* $({$($item:tt)*})* $(where $($bound:tt)*)*) => {
pin_project_lite::pin_project! {
#[must_use = "futures/streams/sinks do nothing unless you `.await` or poll them"]
$(#[$attr])*
pub struct $name< $($arg),* > $(where $($bound)*)* { #[pin] inner: $t }
}
impl<$($arg),*> $name< $($arg),* > $(where $($bound)*)* {
$($($item)*)*
}
delegate_all!(@trait $ftrait $([$($targs)*])* $name<$($arg),*>($t) $(where $($bound)*)*);
};
($(#[$attr:meta])* $name:ident<$($arg:ident),*>($t:ty) : $ftrait:ident $([$($ftargs:tt)*])* + $strait:ident $([$($stargs:tt)*])* $(+ $trait:ident $([$($targs:tt)*])*)* $({$($item:tt)*})* $(where $($bound:tt)*)*) => {
delegate_all!($(#[$attr])* $name<$($arg),*>($t) : $strait $([$($stargs)*])* $(+ $trait $([$($targs)*])*)* $({$($item)*})* $(where $($bound)*)*);
delegate_all!(@trait $ftrait $([$($ftargs)*])* $name<$($arg),*>($t) $(where $($bound)*)*);
};
}
pub mod future;
#[doc(no_inline)]
pub use crate::future::{Future, FutureExt, TryFuture, TryFutureExt};
pub mod stream;
#[doc(no_inline)]
pub use crate::stream::{Stream, StreamExt, TryStream, TryStreamExt};
#[cfg(feature = "sink")]
#[cfg_attr(docsrs, doc(cfg(feature = "sink")))]
pub mod sink;
#[cfg(feature = "sink")]
#[doc(no_inline)]
pub use crate::sink::{Sink, SinkExt};
pub mod task;
pub mod never;
#[cfg(feature = "compat")]
#[cfg_attr(docsrs, doc(cfg(feature = "compat")))]
pub mod compat;
#[cfg(feature = "io")]
#[cfg_attr(docsrs, doc(cfg(feature = "io")))]
#[cfg(feature = "std")]
pub mod io;
#[cfg(feature = "io")]
#[cfg(feature = "std")]
#[doc(no_inline)]
pub use crate::io::{
AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, AsyncWrite,
AsyncWriteExt,
};
#[cfg(feature = "alloc")]
pub mod lock;
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
#[cfg(feature = "alloc")]
mod abortable;
mod fns;
mod macros;
mod unfold_state;

297
vendor/futures-util/src/lock/bilock.rs vendored Normal file
View File

@@ -0,0 +1,297 @@
//! Futures-powered synchronization primitives.
use alloc::boxed::Box;
use alloc::sync::Arc;
use core::cell::UnsafeCell;
use core::ops::{Deref, DerefMut};
use core::pin::Pin;
use core::sync::atomic::AtomicPtr;
use core::sync::atomic::Ordering::SeqCst;
use core::{fmt, ptr};
#[cfg(feature = "bilock")]
use futures_core::future::Future;
use futures_core::task::{Context, Poll, Waker};
/// A type of futures-powered synchronization primitive which is a mutex between
/// two possible owners.
///
/// This primitive is not as generic as a full-blown mutex but is sufficient for
/// many use cases where there are only two possible owners of a resource. The
/// implementation of `BiLock` can be more optimized for just the two possible
/// owners.
///
/// Note that it's possible to use this lock through a poll-style interface with
/// the `poll_lock` method but you can also use it as a future with the `lock`
/// method that consumes a `BiLock` and returns a future that will resolve when
/// it's locked.
///
/// A `BiLock` is typically used for "split" operations where data which serves
/// two purposes wants to be split into two to be worked with separately. For
/// example a TCP stream could be both a reader and a writer or a framing layer
/// could be both a stream and a sink for messages. A `BiLock` enables splitting
/// these two and then using each independently in a futures-powered fashion.
///
/// This type is only available when the `bilock` feature of this
/// library is activated.
#[derive(Debug)]
#[cfg_attr(docsrs, doc(cfg(feature = "bilock")))]
pub struct BiLock<T> {
arc: Arc<Inner<T>>,
}
#[derive(Debug)]
struct Inner<T> {
state: AtomicPtr<Waker>,
value: Option<UnsafeCell<T>>,
}
unsafe impl<T: Send> Send for Inner<T> {}
unsafe impl<T: Send> Sync for Inner<T> {}
impl<T> BiLock<T> {
/// Creates a new `BiLock` protecting the provided data.
///
/// Two handles to the lock are returned, and these are the only two handles
/// that will ever be available to the lock. These can then be sent to separate
/// tasks to be managed there.
///
/// The data behind the bilock is considered to be pinned, which allows `Pin`
/// references to locked data. However, this means that the locked value
/// will only be available through `Pin<&mut T>` (not `&mut T`) unless `T` is `Unpin`.
/// Similarly, reuniting the lock and extracting the inner value is only
/// possible when `T` is `Unpin`.
pub fn new(t: T) -> (Self, Self) {
let arc = Arc::new(Inner {
state: AtomicPtr::new(ptr::null_mut()),
value: Some(UnsafeCell::new(t)),
});
(Self { arc: arc.clone() }, Self { arc })
}
/// Attempt to acquire this lock, returning `Pending` if it can't be
/// acquired.
///
/// This function will acquire the lock in a nonblocking fashion, returning
/// immediately if the lock is already held. If the lock is successfully
/// acquired then `Poll::Ready` is returned with a value that represents
/// the locked value (and can be used to access the protected data). The
/// lock is unlocked when the returned `BiLockGuard` is dropped.
///
/// If the lock is already held then this function will return
/// `Poll::Pending`. In this case the current task will also be scheduled
/// to receive a notification when the lock would otherwise become
/// available.
///
/// # Panics
///
/// This function will panic if called outside the context of a future's
/// task.
pub fn poll_lock(&self, cx: &mut Context<'_>) -> Poll<BiLockGuard<'_, T>> {
let mut waker = None;
loop {
let n = self.arc.state.swap(invalid_ptr(1), SeqCst);
match n as usize {
// Woohoo, we grabbed the lock!
0 => return Poll::Ready(BiLockGuard { bilock: self }),
// Oops, someone else has locked the lock
1 => {}
// A task was previously blocked on this lock, likely our task,
// so we need to update that task.
_ => unsafe {
let mut prev = Box::from_raw(n);
*prev = cx.waker().clone();
waker = Some(prev);
},
}
// type ascription for safety's sake!
let me: Box<Waker> = waker.take().unwrap_or_else(|| Box::new(cx.waker().clone()));
let me = Box::into_raw(me);
match self.arc.state.compare_exchange(invalid_ptr(1), me, SeqCst, SeqCst) {
// The lock is still locked, but we've now parked ourselves, so
// just report that we're scheduled to receive a notification.
Ok(_) => return Poll::Pending,
// Oops, looks like the lock was unlocked after our swap above
// and before the compare_exchange. Deallocate what we just
// allocated and go through the loop again.
Err(n) if n.is_null() => unsafe {
waker = Some(Box::from_raw(me));
},
// The top of this loop set the previous state to 1, so if we
// failed the CAS above then it's because the previous value was
// *not* zero or one. This indicates that a task was blocked,
// but we're trying to acquire the lock and there's only one
// other reference of the lock, so it should be impossible for
// that task to ever block itself.
Err(n) => panic!("invalid state: {}", n as usize),
}
}
}
/// Perform a "blocking lock" of this lock, consuming this lock handle and
/// returning a future to the acquired lock.
///
/// This function consumes the `BiLock<T>` and returns a sentinel future,
/// `BiLockAcquire<T>`. The returned future will resolve to
/// `BiLockGuard<T>`.
///
/// Note that the returned future will never resolve to an error.
#[cfg(feature = "bilock")]
#[cfg_attr(docsrs, doc(cfg(feature = "bilock")))]
pub fn lock(&self) -> BiLockAcquire<'_, T> {
BiLockAcquire { bilock: self }
}
/// Returns `true` only if the other `BiLock<T>` originated from the same call to `BiLock::new`.
pub fn is_pair_of(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.arc, &other.arc)
}
/// Attempts to put the two "halves" of a `BiLock<T>` back together and
/// recover the original value. Succeeds only if the two `BiLock<T>`s
/// originated from the same call to `BiLock::new`.
pub fn reunite(self, other: Self) -> Result<T, ReuniteError<T>>
where
T: Unpin,
{
if self.is_pair_of(&other) {
drop(other);
let inner = Arc::try_unwrap(self.arc)
.ok()
.expect("futures: try_unwrap failed in BiLock<T>::reunite");
Ok(unsafe { inner.into_value() })
} else {
Err(ReuniteError(self, other))
}
}
fn unlock(&self) {
let n = self.arc.state.swap(ptr::null_mut(), SeqCst);
match n as usize {
// we've locked the lock, shouldn't be possible for us to see an
// unlocked lock.
0 => panic!("invalid unlocked state"),
// Ok, no one else tried to get the lock, we're done.
1 => {}
// Another task has parked themselves on this lock, let's wake them
// up as its now their turn.
_ => unsafe {
Box::from_raw(n).wake();
},
}
}
}
impl<T: Unpin> Inner<T> {
unsafe fn into_value(mut self) -> T {
self.value.take().unwrap().into_inner()
}
}
impl<T> Drop for Inner<T> {
fn drop(&mut self) {
assert!(self.state.load(SeqCst).is_null());
}
}
/// Error indicating two `BiLock<T>`s were not two halves of a whole, and
/// thus could not be `reunite`d.
#[cfg_attr(docsrs, doc(cfg(feature = "bilock")))]
pub struct ReuniteError<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()
}
}
impl<T> fmt::Display for ReuniteError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "tried to reunite two BiLocks that don't form a pair")
}
}
#[cfg(feature = "std")]
impl<T: core::any::Any> std::error::Error for ReuniteError<T> {}
/// Returned RAII guard from the `poll_lock` method.
///
/// This structure acts as a sentinel to the data in the `BiLock<T>` itself,
/// implementing `Deref` and `DerefMut` to `T`. When dropped, the lock will be
/// unlocked.
#[derive(Debug)]
#[cfg_attr(docsrs, doc(cfg(feature = "bilock")))]
pub struct BiLockGuard<'a, T> {
bilock: &'a BiLock<T>,
}
// We allow parallel access to T via Deref, so Sync bound is also needed here.
unsafe impl<T: Send + Sync> Sync for BiLockGuard<'_, T> {}
impl<T> Deref for BiLockGuard<'_, T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.bilock.arc.value.as_ref().unwrap().get() }
}
}
impl<T: Unpin> DerefMut for BiLockGuard<'_, T> {
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *self.bilock.arc.value.as_ref().unwrap().get() }
}
}
impl<T> BiLockGuard<'_, T> {
/// Get a mutable pinned reference to the locked value.
pub fn as_pin_mut(&mut self) -> Pin<&mut T> {
// Safety: we never allow moving a !Unpin value out of a bilock, nor
// allow mutable access to it
unsafe { Pin::new_unchecked(&mut *self.bilock.arc.value.as_ref().unwrap().get()) }
}
}
impl<T> Drop for BiLockGuard<'_, T> {
fn drop(&mut self) {
self.bilock.unlock();
}
}
/// Future returned by `BiLock::lock` which will resolve when the lock is
/// acquired.
#[cfg(feature = "bilock")]
#[cfg_attr(docsrs, doc(cfg(feature = "bilock")))]
#[must_use = "futures do nothing unless you `.await` or poll them"]
#[derive(Debug)]
pub struct BiLockAcquire<'a, T> {
bilock: &'a BiLock<T>,
}
// Pinning is never projected to fields
#[cfg(feature = "bilock")]
impl<T> Unpin for BiLockAcquire<'_, T> {}
#[cfg(feature = "bilock")]
impl<'a, T> Future for BiLockAcquire<'a, T> {
type Output = BiLockGuard<'a, T>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
self.bilock.poll_lock(cx)
}
}
// Based on core::ptr::invalid_mut. Equivalent to `addr as *mut T`, but is strict-provenance compatible.
#[allow(clippy::useless_transmute)]
#[inline]
fn invalid_ptr<T>(addr: usize) -> *mut T {
// SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that
// pointer).
unsafe { core::mem::transmute(addr) }
}

27
vendor/futures-util/src/lock/mod.rs vendored Normal file
View File

@@ -0,0 +1,27 @@
//! Futures-powered synchronization primitives.
//!
//! This module is only available when the `std` or `alloc` feature of this
//! library is activated, and it is activated by default.
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
#[cfg(any(feature = "sink", feature = "io"))]
#[cfg(not(feature = "bilock"))]
pub(crate) use self::bilock::BiLock;
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
#[cfg(feature = "bilock")]
#[cfg_attr(docsrs, doc(cfg(feature = "bilock")))]
pub use self::bilock::{BiLock, BiLockAcquire, BiLockGuard, ReuniteError};
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
#[cfg(feature = "std")]
pub use self::mutex::{
MappedMutexGuard, Mutex, MutexGuard, MutexLockFuture, OwnedMutexGuard, OwnedMutexLockFuture,
};
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
#[cfg(any(feature = "bilock", feature = "sink", feature = "io"))]
#[cfg_attr(docsrs, doc(cfg(feature = "bilock")))]
#[cfg_attr(not(feature = "bilock"), allow(unreachable_pub))]
mod bilock;
#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))]
#[cfg(feature = "std")]
mod mutex;

560
vendor/futures-util/src/lock/mutex.rs vendored Normal file
View File

@@ -0,0 +1,560 @@
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::{Arc, Mutex as StdMutex};
use std::{fmt, mem};
use slab::Slab;
use futures_core::future::{FusedFuture, Future};
use futures_core::task::{Context, Poll, Waker};
/// A futures-aware mutex.
///
/// # Fairness
///
/// This mutex provides no fairness guarantees. Tasks may not acquire the mutex
/// in the order that they requested the lock, and it's possible for a single task
/// which repeatedly takes the lock to starve other tasks, which may be left waiting
/// indefinitely.
pub struct Mutex<T: ?Sized> {
state: AtomicUsize,
waiters: StdMutex<Slab<Waiter>>,
value: UnsafeCell<T>,
}
impl<T: ?Sized> fmt::Debug for Mutex<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let state = self.state.load(Ordering::SeqCst);
f.debug_struct("Mutex")
.field("is_locked", &((state & IS_LOCKED) != 0))
.field("has_waiters", &((state & HAS_WAITERS) != 0))
.finish()
}
}
impl<T> From<T> for Mutex<T> {
fn from(t: T) -> Self {
Self::new(t)
}
}
impl<T: Default> Default for Mutex<T> {
fn default() -> Self {
Self::new(Default::default())
}
}
enum Waiter {
Waiting(Waker),
Woken,
}
impl Waiter {
fn register(&mut self, waker: &Waker) {
match self {
Self::Waiting(w) if waker.will_wake(w) => {}
_ => *self = Self::Waiting(waker.clone()),
}
}
fn wake(&mut self) {
match mem::replace(self, Self::Woken) {
Self::Waiting(waker) => waker.wake(),
Self::Woken => {}
}
}
}
const IS_LOCKED: usize = 1 << 0;
const HAS_WAITERS: usize = 1 << 1;
impl<T> Mutex<T> {
/// Creates a new futures-aware mutex.
pub const fn new(t: T) -> Self {
Self {
state: AtomicUsize::new(0),
waiters: StdMutex::new(Slab::new()),
value: UnsafeCell::new(t),
}
}
/// Consumes this mutex, returning the underlying data.
///
/// # Examples
///
/// ```
/// use futures::lock::Mutex;
///
/// let mutex = Mutex::new(0);
/// assert_eq!(mutex.into_inner(), 0);
/// ```
pub fn into_inner(self) -> T {
self.value.into_inner()
}
}
impl<T: ?Sized> Mutex<T> {
/// Attempt to acquire the lock immediately.
///
/// If the lock is currently held, this will return `None`.
pub fn try_lock(&self) -> Option<MutexGuard<'_, T>> {
let old_state = self.state.fetch_or(IS_LOCKED, Ordering::Acquire);
if (old_state & IS_LOCKED) == 0 {
Some(MutexGuard { mutex: self })
} else {
None
}
}
/// Attempt to acquire the lock immediately.
///
/// If the lock is currently held, this will return `None`.
pub fn try_lock_owned(self: &Arc<Self>) -> Option<OwnedMutexGuard<T>> {
let old_state = self.state.fetch_or(IS_LOCKED, Ordering::Acquire);
if (old_state & IS_LOCKED) == 0 {
Some(OwnedMutexGuard { mutex: self.clone() })
} else {
None
}
}
/// Acquire the lock asynchronously.
///
/// This method returns a future that will resolve once the lock has been
/// successfully acquired.
pub fn lock(&self) -> MutexLockFuture<'_, T> {
MutexLockFuture { mutex: Some(self), wait_key: WAIT_KEY_NONE }
}
/// Acquire the lock asynchronously.
///
/// This method returns a future that will resolve once the lock has been
/// successfully acquired.
pub fn lock_owned(self: Arc<Self>) -> OwnedMutexLockFuture<T> {
OwnedMutexLockFuture { mutex: Some(self), wait_key: WAIT_KEY_NONE }
}
/// Returns a mutable reference to the underlying data.
///
/// Since this call borrows the `Mutex` mutably, no actual locking needs to
/// take place -- the mutable borrow statically guarantees no locks exist.
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::lock::Mutex;
///
/// let mut mutex = Mutex::new(0);
/// *mutex.get_mut() = 10;
/// assert_eq!(*mutex.lock().await, 10);
/// # });
/// ```
pub fn get_mut(&mut self) -> &mut T {
// We know statically that there are no other references to `self`, so
// there's no need to lock the inner mutex.
unsafe { &mut *self.value.get() }
}
fn remove_waker(&self, wait_key: usize, wake_another: bool) {
if wait_key != WAIT_KEY_NONE {
let mut waiters = self.waiters.lock().unwrap();
match waiters.remove(wait_key) {
Waiter::Waiting(_) => {}
Waiter::Woken => {
// We were awoken, but then dropped before we could
// wake up to acquire the lock. Wake up another
// waiter.
if wake_another {
if let Some((_i, waiter)) = waiters.iter_mut().next() {
waiter.wake();
}
}
}
}
if waiters.is_empty() {
self.state.fetch_and(!HAS_WAITERS, Ordering::Relaxed); // released by mutex unlock
}
}
}
// Unlocks the mutex. Called by MutexGuard and MappedMutexGuard when they are
// dropped.
fn unlock(&self) {
let old_state = self.state.fetch_and(!IS_LOCKED, Ordering::AcqRel);
if (old_state & HAS_WAITERS) != 0 {
let mut waiters = self.waiters.lock().unwrap();
if let Some((_i, waiter)) = waiters.iter_mut().next() {
waiter.wake();
}
}
}
}
// Sentinel for when no slot in the `Slab` has been dedicated to this object.
const WAIT_KEY_NONE: usize = usize::MAX;
/// A future which resolves when the target mutex has been successfully acquired, owned version.
pub struct OwnedMutexLockFuture<T: ?Sized> {
// `None` indicates that the mutex was successfully acquired.
mutex: Option<Arc<Mutex<T>>>,
wait_key: usize,
}
impl<T: ?Sized> fmt::Debug for OwnedMutexLockFuture<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OwnedMutexLockFuture")
.field("was_acquired", &self.mutex.is_none())
.field("mutex", &self.mutex)
.field(
"wait_key",
&(if self.wait_key == WAIT_KEY_NONE { None } else { Some(self.wait_key) }),
)
.finish()
}
}
impl<T: ?Sized> FusedFuture for OwnedMutexLockFuture<T> {
fn is_terminated(&self) -> bool {
self.mutex.is_none()
}
}
impl<T: ?Sized> Future for OwnedMutexLockFuture<T> {
type Output = OwnedMutexGuard<T>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.get_mut();
let mutex = this.mutex.as_ref().expect("polled OwnedMutexLockFuture after completion");
if let Some(lock) = mutex.try_lock_owned() {
mutex.remove_waker(this.wait_key, false);
this.mutex = None;
return Poll::Ready(lock);
}
{
let mut waiters = mutex.waiters.lock().unwrap();
if this.wait_key == WAIT_KEY_NONE {
this.wait_key = waiters.insert(Waiter::Waiting(cx.waker().clone()));
if waiters.len() == 1 {
mutex.state.fetch_or(HAS_WAITERS, Ordering::Relaxed); // released by mutex unlock
}
} else {
waiters[this.wait_key].register(cx.waker());
}
}
// Ensure that we haven't raced `MutexGuard::drop`'s unlock path by
// attempting to acquire the lock again.
if let Some(lock) = mutex.try_lock_owned() {
mutex.remove_waker(this.wait_key, false);
this.mutex = None;
return Poll::Ready(lock);
}
Poll::Pending
}
}
impl<T: ?Sized> Drop for OwnedMutexLockFuture<T> {
fn drop(&mut self) {
if let Some(mutex) = self.mutex.as_ref() {
// This future was dropped before it acquired the mutex.
//
// Remove ourselves from the map, waking up another waiter if we
// had been awoken to acquire the lock.
mutex.remove_waker(self.wait_key, true);
}
}
}
/// An RAII guard returned by the `lock_owned` and `try_lock_owned` methods.
/// When this structure is dropped (falls out of scope), the lock will be
/// unlocked.
#[clippy::has_significant_drop]
pub struct OwnedMutexGuard<T: ?Sized> {
mutex: Arc<Mutex<T>>,
}
impl<T: ?Sized + fmt::Debug> fmt::Debug for OwnedMutexGuard<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OwnedMutexGuard")
.field("value", &&**self)
.field("mutex", &self.mutex)
.finish()
}
}
impl<T: ?Sized> Drop for OwnedMutexGuard<T> {
fn drop(&mut self) {
self.mutex.unlock()
}
}
impl<T: ?Sized> Deref for OwnedMutexGuard<T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.mutex.value.get() }
}
}
impl<T: ?Sized> DerefMut for OwnedMutexGuard<T> {
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *self.mutex.value.get() }
}
}
/// A future which resolves when the target mutex has been successfully acquired.
pub struct MutexLockFuture<'a, T: ?Sized> {
// `None` indicates that the mutex was successfully acquired.
mutex: Option<&'a Mutex<T>>,
wait_key: usize,
}
impl<T: ?Sized> fmt::Debug for MutexLockFuture<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("MutexLockFuture")
.field("was_acquired", &self.mutex.is_none())
.field("mutex", &self.mutex)
.field(
"wait_key",
&(if self.wait_key == WAIT_KEY_NONE { None } else { Some(self.wait_key) }),
)
.finish()
}
}
impl<T: ?Sized> FusedFuture for MutexLockFuture<'_, T> {
fn is_terminated(&self) -> bool {
self.mutex.is_none()
}
}
impl<'a, T: ?Sized> Future for MutexLockFuture<'a, T> {
type Output = MutexGuard<'a, T>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mutex = self.mutex.expect("polled MutexLockFuture after completion");
if let Some(lock) = mutex.try_lock() {
mutex.remove_waker(self.wait_key, false);
self.mutex = None;
return Poll::Ready(lock);
}
{
let mut waiters = mutex.waiters.lock().unwrap();
if self.wait_key == WAIT_KEY_NONE {
self.wait_key = waiters.insert(Waiter::Waiting(cx.waker().clone()));
if waiters.len() == 1 {
mutex.state.fetch_or(HAS_WAITERS, Ordering::Relaxed); // released by mutex unlock
}
} else {
waiters[self.wait_key].register(cx.waker());
}
}
// Ensure that we haven't raced `MutexGuard::drop`'s unlock path by
// attempting to acquire the lock again.
if let Some(lock) = mutex.try_lock() {
mutex.remove_waker(self.wait_key, false);
self.mutex = None;
return Poll::Ready(lock);
}
Poll::Pending
}
}
impl<T: ?Sized> Drop for MutexLockFuture<'_, T> {
fn drop(&mut self) {
if let Some(mutex) = self.mutex {
// This future was dropped before it acquired the mutex.
//
// Remove ourselves from the map, waking up another waiter if we
// had been awoken to acquire the lock.
mutex.remove_waker(self.wait_key, true);
}
}
}
/// An RAII guard returned by the `lock` and `try_lock` methods.
/// When this structure is dropped (falls out of scope), the lock will be
/// unlocked.
#[clippy::has_significant_drop]
pub struct MutexGuard<'a, T: ?Sized> {
mutex: &'a Mutex<T>,
}
impl<'a, T: ?Sized> MutexGuard<'a, T> {
/// Returns a locked view over a portion of the locked data.
///
/// # Example
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::lock::{Mutex, MutexGuard};
///
/// let data = Mutex::new(Some("value".to_string()));
/// {
/// let locked_str = MutexGuard::map(data.lock().await, |opt| opt.as_mut().unwrap());
/// assert_eq!(&*locked_str, "value");
/// }
/// # });
/// ```
#[inline]
pub fn map<U: ?Sized, F>(this: Self, f: F) -> MappedMutexGuard<'a, T, U>
where
F: FnOnce(&mut T) -> &mut U,
{
let mutex = this.mutex;
let value = f(unsafe { &mut *this.mutex.value.get() });
// Don't run the `drop` method for MutexGuard. The ownership of the underlying
// locked state is being moved to the returned MappedMutexGuard.
mem::forget(this);
MappedMutexGuard { mutex, value, _marker: PhantomData }
}
}
impl<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()
}
}
impl<T: ?Sized> Drop for MutexGuard<'_, T> {
fn drop(&mut self) {
self.mutex.unlock()
}
}
impl<T: ?Sized> Deref for MutexGuard<'_, T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.mutex.value.get() }
}
}
impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *self.mutex.value.get() }
}
}
/// An RAII guard returned by the `MutexGuard::map` and `MappedMutexGuard::map` methods.
/// When this structure is dropped (falls out of scope), the lock will be unlocked.
#[clippy::has_significant_drop]
pub struct MappedMutexGuard<'a, T: ?Sized, U: ?Sized> {
mutex: &'a Mutex<T>,
value: *mut U,
_marker: PhantomData<&'a mut U>,
}
impl<'a, T: ?Sized, U: ?Sized> MappedMutexGuard<'a, T, U> {
/// Returns a locked view over a portion of the locked data.
///
/// # Example
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::lock::{MappedMutexGuard, Mutex, MutexGuard};
///
/// let data = Mutex::new(Some("value".to_string()));
/// {
/// let locked_str = MutexGuard::map(data.lock().await, |opt| opt.as_mut().unwrap());
/// let locked_char = MappedMutexGuard::map(locked_str, |s| s.get_mut(0..1).unwrap());
/// assert_eq!(&*locked_char, "v");
/// }
/// # });
/// ```
#[inline]
pub fn map<V: ?Sized, F>(this: Self, f: F) -> MappedMutexGuard<'a, T, V>
where
F: FnOnce(&mut U) -> &mut V,
{
let mutex = this.mutex;
let value = f(unsafe { &mut *this.value });
// Don't run the `drop` method for MappedMutexGuard. The ownership of the underlying
// locked state is being moved to the returned MappedMutexGuard.
mem::forget(this);
MappedMutexGuard { mutex, value, _marker: PhantomData }
}
}
impl<T: ?Sized, U: ?Sized + fmt::Debug> fmt::Debug for MappedMutexGuard<'_, T, U> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("MappedMutexGuard")
.field("value", &&**self)
.field("mutex", &self.mutex)
.finish()
}
}
impl<T: ?Sized, U: ?Sized> Drop for MappedMutexGuard<'_, T, U> {
fn drop(&mut self) {
self.mutex.unlock()
}
}
impl<T: ?Sized, U: ?Sized> Deref for MappedMutexGuard<'_, T, U> {
type Target = U;
fn deref(&self) -> &U {
unsafe { &*self.value }
}
}
impl<T: ?Sized, U: ?Sized> DerefMut for MappedMutexGuard<'_, T, U> {
fn deref_mut(&mut self) -> &mut U {
unsafe { &mut *self.value }
}
}
// Mutexes can be moved freely between threads and acquired on any thread so long
// as the inner value can be safely sent between threads.
unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
// It's safe to switch which thread the acquire is being attempted on so long as
// `T` can be accessed on that thread.
unsafe impl<T: ?Sized + Send> Send for MutexLockFuture<'_, T> {}
// doesn't have any interesting `&self` methods (only Debug)
unsafe impl<T: ?Sized> Sync for MutexLockFuture<'_, T> {}
// It's safe to switch which thread the acquire is being attempted on so long as
// `T` can be accessed on that thread.
unsafe impl<T: ?Sized + Send> Send for OwnedMutexLockFuture<T> {}
// doesn't have any interesting `&self` methods (only Debug)
unsafe impl<T: ?Sized> Sync for OwnedMutexLockFuture<T> {}
// Safe to send since we don't track any thread-specific details-- the inner
// lock is essentially spinlock-equivalent (attempt to flip an atomic bool)
unsafe impl<T: ?Sized + Send> Send for MutexGuard<'_, T> {}
unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
unsafe impl<T: ?Sized + Send> Send for OwnedMutexGuard<T> {}
unsafe impl<T: ?Sized + Sync> Sync for OwnedMutexGuard<T> {}
unsafe impl<T: ?Sized + Send, U: ?Sized + Send> Send for MappedMutexGuard<'_, T, U> {}
unsafe impl<T: ?Sized + Sync, U: ?Sized + Sync> Sync for MappedMutexGuard<'_, T, U> {}
#[cfg(test)]
mod tests {
use super::*;
use std::format;
#[test]
fn test_mutex_guard_debug_not_recurse() {
let mutex = Mutex::new(42);
let guard = mutex.try_lock().unwrap();
let _ = format!("{guard:?}");
let guard = MutexGuard::map(guard, |n| n);
let _ = format!("{guard:?}");
}
}

31
vendor/futures-util/src/macros.rs vendored Normal file
View File

@@ -0,0 +1,31 @@
/// Pins a value on the stack.
///
/// Can safely pin values that are not `Unpin` by taking ownership.
///
/// **Note:** Since Rust 1.68, this macro is soft-deprecated in favor of
/// [`pin!`](https://doc.rust-lang.org/std/pin/macro.pin.html) macro
/// in the standard library.
///
/// # Example
///
/// ```rust
/// # use futures_util::pin_mut;
/// # use core::pin::Pin;
/// # struct Foo {}
/// let foo = Foo { /* ... */ };
/// pin_mut!(foo);
/// let _: Pin<&mut Foo> = foo;
/// ```
#[macro_export]
macro_rules! pin_mut {
($($x:ident),* $(,)?) => { $(
// Move the value to ensure that it is owned
let mut $x = $x;
// Shadow the original binding so that it can't be directly accessed
// ever again.
#[allow(unused_mut)]
let mut $x = unsafe {
$crate::__private::Pin::new_unchecked(&mut $x)
};
)* }
}

18
vendor/futures-util/src/never.rs vendored Normal file
View File

@@ -0,0 +1,18 @@
//! This module contains the `Never` type.
//!
//! Values of this type can never be created and will never exist.
/// A type with no possible values.
///
/// This is used to indicate values which can never be created, such as the
/// error type of infallible futures.
///
/// This type is a stable equivalent to the `!` type from `std`.
///
/// This is currently an alias for [`std::convert::Infallible`], but in
/// the future it may be an alias for [`!`][never].
/// See ["Future compatibility" section of `std::convert::Infallible`][infallible] for more.
///
/// [never]: https://doc.rust-lang.org/nightly/std/primitive.never.html
/// [infallible]: https://doc.rust-lang.org/nightly/std/convert/enum.Infallible.html#future-compatibility
pub type Never = core::convert::Infallible;

105
vendor/futures-util/src/sink/buffer.rs vendored Normal file
View File

@@ -0,0 +1,105 @@
use alloc::collections::VecDeque;
use core::pin::Pin;
use futures_core::ready;
use futures_core::stream::{FusedStream, Stream};
use futures_core::task::{Context, Poll};
use futures_sink::Sink;
use pin_project_lite::pin_project;
pin_project! {
/// Sink for the [`buffer`](super::SinkExt::buffer) method.
#[derive(Debug)]
#[must_use = "sinks do nothing unless polled"]
pub struct Buffer<Si, Item> {
#[pin]
sink: Si,
buf: VecDeque<Item>,
// Track capacity separately from the `VecDeque`, which may be rounded up
capacity: usize,
}
}
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 }
}
delegate_access_inner!(sink, Si, ());
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() {
this.sink.as_mut().start_send(item)?;
if !this.buf.is_empty() {
ready!(this.sink.as_mut().poll_ready(cx))?;
}
}
Poll::Ready(Ok(()))
}
}
// Forwarding impl of Stream from the underlying sink
impl<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>> {
self.project().sink.poll_next(cx)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.sink.size_hint()
}
}
impl<S, Item> FusedStream for Buffer<S, Item>
where
S: Sink<Item> + FusedStream,
{
fn is_terminated(&self) -> bool {
self.sink.is_terminated()
}
}
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>> {
if self.capacity == 0 {
return self.project().sink.poll_ready(cx);
}
let _ = self.as_mut().try_empty_buffer(cx)?;
if self.buf.len() >= self.capacity {
Poll::Pending
} else {
Poll::Ready(Ok(()))
}
}
fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
if self.capacity == 0 {
self.project().sink.start_send(item)
} else {
self.project().buf.push_back(item);
Ok(())
}
}
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<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>> {
ready!(self.as_mut().try_empty_buffer(cx))?;
debug_assert!(self.buf.is_empty());
self.project().sink.poll_close(cx)
}
}

32
vendor/futures-util/src/sink/close.rs vendored Normal file
View File

@@ -0,0 +1,32 @@
use core::marker::PhantomData;
use core::pin::Pin;
use futures_core::future::Future;
use futures_core::task::{Context, Poll};
use futures_sink::Sink;
/// Future for the [`close`](super::SinkExt::close) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Close<'a, Si: ?Sized, Item> {
sink: &'a mut Si,
_phantom: PhantomData<fn(Item)>,
}
impl<Si: Unpin + ?Sized, Item> Unpin for Close<'_, Si, Item> {}
/// A future that completes when the sink has finished closing.
///
/// The sink itself is returned after closing is complete.
impl<'a, Si: Sink<Item> + Unpin + ?Sized, Item> Close<'a, Si, Item> {
pub(super) fn new(sink: &'a mut Si) -> Self {
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> {
Pin::new(&mut self.sink).poll_close(cx)
}
}

59
vendor/futures-util/src/sink/drain.rs vendored Normal file
View File

@@ -0,0 +1,59 @@
use super::assert_sink;
use crate::never::Never;
use core::marker::PhantomData;
use core::pin::Pin;
use futures_core::task::{Context, Poll};
use futures_sink::Sink;
/// Sink for the [`drain`] function.
#[derive(Debug)]
#[must_use = "sinks do nothing unless polled"]
pub struct Drain<T> {
marker: PhantomData<T>,
}
/// Create a sink that will just discard all items given to it.
///
/// Similar to [`io::Sink`](::std::io::Sink).
///
/// # Examples
///
/// ```
/// # futures::executor::block_on(async {
/// use futures::sink::{self, SinkExt};
///
/// let mut drain = sink::drain();
/// drain.send(5).await?;
/// # Ok::<(), futures::never::Never>(()) }).unwrap();
/// ```
pub fn drain<T>() -> Drain<T> {
assert_sink::<T, Never, _>(Drain { marker: PhantomData })
}
impl<T> Unpin for Drain<T> {}
impl<T> Clone for Drain<T> {
fn clone(&self) -> Self {
drain()
}
}
impl<T> Sink<T> for Drain<T> {
type Error = Never;
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> {
Ok(())
}
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>> {
Poll::Ready(Ok(()))
}
}

View File

@@ -0,0 +1,57 @@
use crate::sink::{SinkExt, SinkMapErr};
use futures_core::stream::{FusedStream, Stream};
use futures_sink::Sink;
use pin_project_lite::pin_project;
pin_project! {
/// Sink for the [`sink_err_into`](super::SinkExt::sink_err_into) method.
#[derive(Debug)]
#[must_use = "sinks do nothing unless polled"]
pub struct SinkErrInto<Si: Sink<Item>, Item, E> {
#[pin]
sink: SinkMapErr<Si, fn(Si::Error) -> E>,
}
}
impl<Si, E, Item> SinkErrInto<Si, Item, 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) }
}
delegate_access_inner!(sink, Si, (.));
}
impl<Si, Item, E> Sink<Item> for SinkErrInto<Si, Item, E>
where
Si: Sink<Item>,
Si::Error: Into<E>,
{
type Error = E;
delegate_sink!(sink, Item);
}
// 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>,
{
type Item = S::Item;
delegate_stream!(sink);
}
impl<S, Item, E> FusedStream for SinkErrInto<S, Item, E>
where
S: Sink<Item> + FusedStream,
S::Error: Into<E>,
{
fn is_terminated(&self) -> bool {
self.sink.is_terminated()
}
}

111
vendor/futures-util/src/sink/fanout.rs vendored Normal file
View File

@@ -0,0 +1,111 @@
use core::fmt::{Debug, Formatter, Result as FmtResult};
use core::pin::Pin;
use futures_core::task::{Context, Poll};
use futures_sink::Sink;
use pin_project_lite::pin_project;
pin_project! {
/// Sink that clones incoming items and forwards them to two sinks at the same time.
///
/// Backpressure from any downstream sink propagates up, which means that this sink
/// can only process items as fast as its _slowest_ downstream sink.
#[must_use = "sinks do nothing unless polled"]
pub struct Fanout<Si1, Si2> {
#[pin]
sink1: Si1,
#[pin]
sink2: Si2
}
}
impl<Si1, Si2> Fanout<Si1, Si2> {
pub(super) fn new(sink1: Si1, sink2: Si2) -> Self {
Self { sink1, sink2 }
}
/// Get a shared reference to the inner sinks.
pub fn get_ref(&self) -> (&Si1, &Si2) {
(&self.sink1, &self.sink2)
}
/// Get a mutable reference to the inner sinks.
pub fn get_mut(&mut self) -> (&mut Si1, &mut Si2) {
(&mut self.sink1, &mut self.sink2)
}
/// Get a pinned mutable reference to the inner sinks.
pub fn get_pin_mut(self: Pin<&mut Self>) -> (Pin<&mut Si1>, Pin<&mut Si2>) {
let this = self.project();
(this.sink1, this.sink2)
}
/// Consumes this combinator, returning the underlying sinks.
///
/// Note that this may discard intermediate state of this combinator,
/// so care should be taken to avoid losing resources when this is called.
pub fn into_inner(self) -> (Si1, Si2) {
(self.sink1, self.sink2)
}
}
impl<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()
}
}
impl<Si1, Si2, Item> Sink<Item> for Fanout<Si1, Si2>
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>> {
let this = self.project();
let sink1_ready = this.sink1.poll_ready(cx)?.is_ready();
let sink2_ready = this.sink2.poll_ready(cx)?.is_ready();
let ready = sink1_ready && sink2_ready;
if ready {
Poll::Ready(Ok(()))
} else {
Poll::Pending
}
}
fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
let this = self.project();
this.sink1.start_send(item.clone())?;
this.sink2.start_send(item)?;
Ok(())
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<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
}
}
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
}
}
}

43
vendor/futures-util/src/sink/feed.rs vendored Normal file
View File

@@ -0,0 +1,43 @@
use core::pin::Pin;
use futures_core::future::Future;
use futures_core::ready;
use futures_core::task::{Context, Poll};
use futures_sink::Sink;
/// Future for the [`feed`](super::SinkExt::feed) method.
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Feed<'a, Si: ?Sized, Item> {
sink: &'a mut Si,
item: Option<Item>,
}
// Pinning is never projected to children
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) }
}
pub(super) fn sink_pin_mut(&mut self) -> Pin<&mut Si> {
Pin::new(self.sink)
}
pub(super) fn is_item_pending(&self) -> bool {
self.item.is_some()
}
}
impl<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> {
let this = self.get_mut();
let mut sink = Pin::new(&mut this.sink);
ready!(sink.as_mut().poll_ready(cx))?;
let item = this.item.take().expect("polled Feed after completion");
sink.as_mut().start_send(item)?;
Poll::Ready(Ok(()))
}
}

Some files were not shown because too many files have changed in this diff Show More