async-stream-0.3.6/.cargo_vcs_info.json0000644000000001750000000000100134530ustar { "git": { "sha1": "b0b2f22df8e87b7fed7b2fa234509797adbff7db", "dirty": true }, "path_in_vcs": "async-stream" }async-stream-0.3.6/CHANGELOG.md000064400000000000000000000010551046102023000140520ustar 00000000000000# 0.3.6 * Fix soundness bugs (#109) * Bump MSRV to 1.65 (#109) # 0.3.5 * Update to syn 2.0 (#93) * Bump MSRV to 1.56 (#97) # 0.3.4 * Improve support for `#[track_caller]` (#72) * Reduce unsafe code (#77) # 0.3.3 * Fix a bug where `yield` and `?` cannot be used on the same line (#66) # 0.3.2 * Expand `yield` in internal macro calls (#57) # 0.3.1 * Support reexporting (#46) * Allow yielding `!Unpin` values (#50) * Implement `Stream::size_hint` method on `AsyncStream` (#40) * Documentation improvements # 0.3.0 * Remove proc-macro-hack (#30) async-stream-0.3.6/Cargo.lock0000644000000362020000000000100114260ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "addr2line" version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" dependencies = [ "gimli", ] [[package]] name = "adler2" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "async-stream" version = "0.3.6" dependencies = [ "async-stream-impl", "futures-core", "futures-util", "pin-project-lite", "rustversion", "tokio", "trybuild", ] [[package]] name = "async-stream-impl" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "autocfg" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", "windows-targets", ] [[package]] name = "bitflags" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bytes" version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "equivalent" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "futures-core" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-macro" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "futures-task" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", "futures-macro", "futures-task", "pin-project-lite", "pin-utils", "slab", ] [[package]] name = "gimli" version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" [[package]] name = "glob" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hermit-abi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "indexmap" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown", ] [[package]] name = "itoa" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "libc" version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "lock_api" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", ] [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "miniz_oxide" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ "adler2", ] [[package]] name = "mio" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ "hermit-abi", "libc", "wasi", "windows-sys 0.52.0", ] [[package]] name = "object" version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" dependencies = [ "memchr", ] [[package]] name = "parking_lot" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", ] [[package]] name = "parking_lot_core" version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", "windows-targets", ] [[package]] name = "pin-project-lite" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "proc-macro2" version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] [[package]] name = "redox_syscall" version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" dependencies = [ "bitflags", ] [[package]] name = "rustc-demangle" version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustversion" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_json" version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", "memchr", "ryu", "serde", ] [[package]] name = "serde_spanned" version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] [[package]] name = "signal-hook-registry" version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] [[package]] name = "slab" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", ] [[package]] name = "syn" version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "termcolor" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "tokio" version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "toml" version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", "toml_datetime", "toml_edit", ] [[package]] name = "toml_datetime" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" version = "0.22.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", "winnow", ] [[package]] name = "trybuild" version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "207aa50d36c4be8d8c6ea829478be44a372c6a77669937bb39c698e52f1491e8" dependencies = [ "glob", "serde", "serde_derive", "serde_json", "termcolor", "toml", ] [[package]] name = "unicode-ident" version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "winapi-util" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ "windows-sys 0.59.0", ] [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ "windows-targets", ] [[package]] name = "windows-sys" version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ "memchr", ] async-stream-0.3.6/Cargo.toml0000644000000030120000000000100114420ustar # 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 = "2021" rust-version = "1.65" name = "async-stream" version = "0.3.6" authors = ["Carl Lerche "] build = false autobins = false autoexamples = false autotests = false autobenches = false description = "Asynchronous streams using async & await notation" readme = "README.md" license = "MIT" repository = "https://github.com/tokio-rs/async-stream" [lib] name = "async_stream" path = "src/lib.rs" [[example]] name = "tcp_accept" path = "examples/tcp_accept.rs" [[test]] name = "for_await" path = "tests/for_await.rs" [[test]] name = "spans_preserved" path = "tests/spans_preserved.rs" [[test]] name = "stream" path = "tests/stream.rs" [[test]] name = "try_stream" path = "tests/try_stream.rs" [dependencies.async-stream-impl] version = "=0.3.6" [dependencies.futures-core] version = "0.3" [dependencies.pin-project-lite] version = "0.2" [dev-dependencies.futures-util] version = "0.3" [dev-dependencies.rustversion] version = "1" [dev-dependencies.tokio] version = "1" features = ["full"] [dev-dependencies.trybuild] version = "1" async-stream-0.3.6/Cargo.toml.orig000064400000000000000000000012421046102023000151260ustar 00000000000000[package] name = "async-stream" # When releasing to crates.io: # - Update CHANGELOG.md # - Create git tag version = "0.3.6" edition = "2021" rust-version = "1.65" license = "MIT" authors = ["Carl Lerche "] description = "Asynchronous streams using async & await notation" repository = "https://github.com/tokio-rs/async-stream" [dependencies] async-stream-impl = { version = "=0.3.6", path = "../async-stream-impl" } futures-core = "0.3" pin-project-lite = "0.2" [dev-dependencies] futures-util = "0.3" rustversion = "1" tokio = { version = "1", features = ["full"] } # tokio-test = "0.4" # https://github.com/rust-lang/cargo/issues/4242 trybuild = "1" async-stream-0.3.6/LICENSE000064400000000000000000000041001046102023000132400ustar 00000000000000Copyright (c) 2019 Carl Lerche 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. Copyright (c) 2018 David Tolnay 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. async-stream-0.3.6/README.md000064400000000000000000000100141046102023000135130ustar 00000000000000# Asynchronous streams for Rust Asynchronous stream of elements. Provides two macros, `stream!` and `try_stream!`, allowing the caller to define asynchronous streams of elements. These are implemented using `async` & `await` notation. This crate works without unstable features. The `stream!` macro returns an anonymous type implementing the [`Stream`] trait. The `Item` associated type is the type of the values yielded from the stream. The `try_stream!` also returns an anonymous type implementing the [`Stream`] trait, but the `Item` associated type is `Result`. The `try_stream!` macro supports using `?` notation as part of the implementation. ## Usage A basic stream yielding numbers. Values are yielded using the `yield` keyword. The stream block must return `()`. ```rust use async_stream::stream; use futures_util::pin_mut; use futures_util::stream::StreamExt; #[tokio::main] async fn main() { let s = stream! { for i in 0..3 { yield i; } }; pin_mut!(s); // needed for iteration while let Some(value) = s.next().await { println!("got {}", value); } } ``` Streams may be returned by using `impl Stream`: ```rust use async_stream::stream; use futures_core::stream::Stream; use futures_util::pin_mut; use futures_util::stream::StreamExt; fn zero_to_three() -> impl Stream { stream! { for i in 0..3 { yield i; } } } #[tokio::main] async fn main() { let s = zero_to_three(); pin_mut!(s); // needed for iteration while let Some(value) = s.next().await { println!("got {}", value); } } ``` Streams may be implemented in terms of other streams - `async-stream` provides `for await` syntax to assist with this: ```rust use async_stream::stream; use futures_core::stream::Stream; use futures_util::pin_mut; use futures_util::stream::StreamExt; fn zero_to_three() -> impl Stream { stream! { for i in 0..3 { yield i; } } } fn double>(input: S) -> impl Stream { stream! { for await value in input { yield value * 2; } } } #[tokio::main] async fn main() { let s = double(zero_to_three()); pin_mut!(s); // needed for iteration while let Some(value) = s.next().await { println!("got {}", value); } } ``` Rust try notation (`?`) can be used with the `try_stream!` macro. The `Item` of the returned stream is `Result` with `Ok` being the value yielded and `Err` the error type returned by `?`. ```rust use tokio::net::{TcpListener, TcpStream}; use async_stream::try_stream; use futures_core::stream::Stream; use std::io; use std::net::SocketAddr; fn bind_and_accept(addr: SocketAddr) -> impl Stream> { try_stream! { let mut listener = TcpListener::bind(addr).await?; loop { let (stream, addr) = listener.accept().await?; println!("received on {:?}", addr); yield stream; } } } ``` ## Implementation The `stream!` and `try_stream!` macros are implemented using proc macros. The macro searches the syntax tree for instances of `yield $expr` and transforms them into `sender.send($expr).await`. The stream uses a lightweight sender to send values from the stream implementation to the caller. When entering the stream, an `Option` is stored on the stack. A pointer to the cell is stored in a thread local and `poll` is called on the async block. When `poll` returns. `sender.send(value)` stores the value that cell and yields back to the caller. [`Stream`]: https://docs.rs/futures-core/*/futures_core/stream/trait.Stream.html ## Supported Rust Versions The current minimum supported Rust version is 1.65. ## License This project is licensed under the [MIT license](LICENSE). ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in `async-stream` by you, shall be licensed as MIT, without any additional terms or conditions. async-stream-0.3.6/README.tpl000064400000000000000000000005051046102023000137160ustar 00000000000000# Asynchronous streams for Rust {{readme}} ## License This project is licensed under the [MIT license](LICENSE). ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in `async-stream` by you, shall be licensed as MIT, without any additional terms or conditions. async-stream-0.3.6/examples/tcp_accept.rs000064400000000000000000000007541046102023000165370ustar 00000000000000use async_stream::stream; use futures_util::pin_mut; use futures_util::stream::StreamExt; use tokio::net::TcpListener; #[tokio::main] async fn main() { let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); let incoming = stream! { loop { let (socket, _) = listener.accept().await.unwrap(); yield socket; } }; pin_mut!(incoming); while let Some(v) = incoming.next().await { println!("handle = {:?}", v); } } async-stream-0.3.6/src/async_stream.rs000064400000000000000000000030241046102023000160640ustar 00000000000000use crate::yielder::Receiver; use futures_core::{FusedStream, Stream}; use pin_project_lite::pin_project; use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; pin_project! { #[doc(hidden)] #[derive(Debug)] pub struct AsyncStream { rx: Receiver, done: bool, #[pin] generator: U, } } impl AsyncStream { #[doc(hidden)] pub fn new(rx: Receiver, generator: U) -> AsyncStream { AsyncStream { rx, done: false, generator, } } } impl FusedStream for AsyncStream where U: Future, { fn is_terminated(&self) -> bool { self.done } } impl Stream for AsyncStream where U: Future, { type Item = T; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let me = self.project(); if *me.done { return Poll::Ready(None); } let mut dst = None; let res = { let _enter = me.rx.enter(&mut dst); me.generator.poll(cx) }; *me.done = res.is_ready(); if dst.is_some() { return Poll::Ready(dst.take()); } if *me.done { Poll::Ready(None) } else { Poll::Pending } } fn size_hint(&self) -> (usize, Option) { if self.done { (0, Some(0)) } else { (0, None) } } } async-stream-0.3.6/src/lib.rs000064400000000000000000000141521046102023000141460ustar 00000000000000#![warn( missing_debug_implementations, missing_docs, rust_2018_idioms, unreachable_pub )] #![doc(test(no_crate_inject, attr(deny(rust_2018_idioms))))] //! Asynchronous stream of elements. //! //! Provides two macros, `stream!` and `try_stream!`, allowing the caller to //! define asynchronous streams of elements. These are implemented using `async` //! & `await` notation. This crate works without unstable features. //! //! The `stream!` macro returns an anonymous type implementing the [`Stream`] //! trait. The `Item` associated type is the type of the values yielded from the //! stream. The `try_stream!` also returns an anonymous type implementing the //! [`Stream`] trait, but the `Item` associated type is `Result`. The //! `try_stream!` macro supports using `?` notation as part of the //! implementation. //! //! # Usage //! //! A basic stream yielding numbers. Values are yielded using the `yield` //! keyword. The stream block must return `()`. //! //! ```rust //! use async_stream::stream; //! //! use futures_util::pin_mut; //! use futures_util::stream::StreamExt; //! //! #[tokio::main] //! async fn main() { //! let s = stream! { //! for i in 0..3 { //! yield i; //! } //! }; //! //! pin_mut!(s); // needed for iteration //! //! while let Some(value) = s.next().await { //! println!("got {}", value); //! } //! } //! ``` //! //! Streams may be returned by using `impl Stream`: //! //! ```rust //! use async_stream::stream; //! //! use futures_core::stream::Stream; //! use futures_util::pin_mut; //! use futures_util::stream::StreamExt; //! //! fn zero_to_three() -> impl Stream { //! stream! { //! for i in 0..3 { //! yield i; //! } //! } //! } //! //! #[tokio::main] //! async fn main() { //! let s = zero_to_three(); //! pin_mut!(s); // needed for iteration //! //! while let Some(value) = s.next().await { //! println!("got {}", value); //! } //! } //! ``` //! //! Streams may be implemented in terms of other streams - `async-stream` provides `for await` //! syntax to assist with this: //! //! ```rust //! use async_stream::stream; //! //! use futures_core::stream::Stream; //! use futures_util::pin_mut; //! use futures_util::stream::StreamExt; //! //! fn zero_to_three() -> impl Stream { //! stream! { //! for i in 0..3 { //! yield i; //! } //! } //! } //! //! fn double>(input: S) //! -> impl Stream //! { //! stream! { //! for await value in input { //! yield value * 2; //! } //! } //! } //! //! #[tokio::main] //! async fn main() { //! let s = double(zero_to_three()); //! pin_mut!(s); // needed for iteration //! //! while let Some(value) = s.next().await { //! println!("got {}", value); //! } //! } //! ``` //! //! Rust try notation (`?`) can be used with the `try_stream!` macro. The `Item` //! of the returned stream is `Result` with `Ok` being the value yielded and //! `Err` the error type returned by `?`. //! //! ```rust //! use tokio::net::{TcpListener, TcpStream}; //! //! use async_stream::try_stream; //! use futures_core::stream::Stream; //! //! use std::io; //! use std::net::SocketAddr; //! //! fn bind_and_accept(addr: SocketAddr) //! -> impl Stream> //! { //! try_stream! { //! let mut listener = TcpListener::bind(addr).await?; //! //! loop { //! let (stream, addr) = listener.accept().await?; //! println!("received on {:?}", addr); //! yield stream; //! } //! } //! } //! ``` //! //! # Implementation //! //! The `stream!` and `try_stream!` macros are implemented using proc macros. //! The macro searches the syntax tree for instances of `yield $expr` and //! transforms them into `sender.send($expr).await`. //! //! The stream uses a lightweight sender to send values from the stream //! implementation to the caller. When entering the stream, an `Option` is //! stored on the stack. A pointer to the cell is stored in a thread local and //! `poll` is called on the async block. When `poll` returns. //! `sender.send(value)` stores the value that cell and yields back to the //! caller. //! //! [`Stream`]: https://docs.rs/futures-core/*/futures_core/stream/trait.Stream.html mod async_stream; mod next; mod yielder; /// Asynchronous stream /// /// See [crate](index.html) documentation for more details. /// /// # Examples /// /// ``` /// use async_stream::stream; /// /// use futures_util::pin_mut; /// use futures_util::stream::StreamExt; /// /// #[tokio::main] /// async fn main() { /// let s = stream! { /// for i in 0..3 { /// yield i; /// } /// }; /// /// pin_mut!(s); // needed for iteration /// /// while let Some(value) = s.next().await { /// println!("got {}", value); /// } /// } /// ``` #[macro_export] macro_rules! stream { ($($tt:tt)*) => { $crate::__private::stream_inner!(($crate) $($tt)*) } } /// Asynchronous fallible stream /// /// See [crate](index.html) documentation for more details. /// /// # Examples /// /// ``` /// use tokio::net::{TcpListener, TcpStream}; /// /// use async_stream::try_stream; /// use futures_core::stream::Stream; /// /// use std::io; /// use std::net::SocketAddr; /// /// fn bind_and_accept(addr: SocketAddr) /// -> impl Stream> /// { /// try_stream! { /// let mut listener = TcpListener::bind(addr).await?; /// /// loop { /// let (stream, addr) = listener.accept().await?; /// println!("received on {:?}", addr); /// yield stream; /// } /// } /// } /// ``` #[macro_export] macro_rules! try_stream { ($($tt:tt)*) => { $crate::__private::try_stream_inner!(($crate) $($tt)*) } } // Not public API. #[doc(hidden)] pub mod __private { pub use crate::async_stream::AsyncStream; pub use crate::next::next; pub use async_stream_impl::{stream_inner, try_stream_inner}; pub mod yielder { pub use crate::yielder::pair; } } async-stream-0.3.6/src/next.rs000064400000000000000000000013761046102023000143620ustar 00000000000000use futures_core::Stream; use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; // This is equivalent to the `futures::StreamExt::next` method. // But we want to make this crate dependency as small as possible, so we define our `next` function. #[doc(hidden)] pub fn next(stream: &mut S) -> impl Future> + '_ where S: Stream + Unpin, { Next { stream } } #[derive(Debug)] struct Next<'a, S> { stream: &'a mut S, } impl Unpin for Next<'_, S> where S: Unpin {} impl Future for Next<'_, S> where S: Stream + Unpin, { type Output = Option; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Pin::new(&mut self.stream).poll_next(cx) } } async-stream-0.3.6/src/yielder.rs000064400000000000000000000042241046102023000150340ustar 00000000000000use std::cell::Cell; use std::future::Future; use std::marker::PhantomData; use std::pin::Pin; use std::ptr; use std::task::{Context, Poll}; #[derive(Debug)] pub struct Sender { _p: PhantomData T>, } #[derive(Debug)] pub struct Receiver { _p: PhantomData, } pub(crate) struct Enter<'a, T> { _rx: &'a mut Receiver, prev: *mut (), } // Note: It is considered unsound for anyone other than our macros to call // this function. This is a private API intended only for calls from our // macros, and users should never call it, but some people tend to // misinterpret it as fine to call unless it is marked unsafe. #[doc(hidden)] pub unsafe fn pair() -> (Sender, Receiver) { let tx = Sender { _p: PhantomData }; let rx = Receiver { _p: PhantomData }; (tx, rx) } // Tracks the pointer to `Option`. // // TODO: Ensure wakers match? thread_local!(static STORE: Cell<*mut ()> = const { Cell::new(ptr::null_mut()) }); // ===== impl Sender ===== impl Sender { pub fn send(&mut self, value: T) -> impl Future { Send { value: Some(value) } } } struct Send { value: Option, } impl Unpin for Send {} impl Future for Send { type Output = (); fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<()> { if self.value.is_none() { return Poll::Ready(()); } STORE.with(|cell| { let ptr = cell.get() as *mut Option; let option_ref = unsafe { ptr.as_mut() }.expect("invalid usage"); if option_ref.is_none() { *option_ref = self.value.take(); } Poll::Pending }) } } // ===== impl Receiver ===== impl Receiver { pub(crate) fn enter<'a>(&'a mut self, dst: &'a mut Option) -> Enter<'a, T> { let prev = STORE.with(|cell| { let prev = cell.get(); cell.set(dst as *mut _ as *mut ()); prev }); Enter { _rx: self, prev } } } // ===== impl Enter ===== impl<'a, T> Drop for Enter<'a, T> { fn drop(&mut self) { STORE.with(|cell| cell.set(self.prev)); } } async-stream-0.3.6/tests/for_await.rs000064400000000000000000000006611046102023000157260ustar 00000000000000use async_stream::stream; use futures_util::stream::StreamExt; #[tokio::test] async fn test() { let s = stream! { yield "hello"; yield "world"; }; let s = stream! { for await x in s { yield x.to_owned() + "!"; } }; let values: Vec<_> = s.collect().await; assert_eq!(2, values.len()); assert_eq!("hello!", values[0]); assert_eq!("world!", values[1]); } async-stream-0.3.6/tests/spans_preserved.rs000064400000000000000000000004301046102023000171500ustar 00000000000000use async_stream::stream; use futures_util::pin_mut; use futures_util::stream::StreamExt; #[tokio::test] async fn spans_preserved() { let s = stream! { assert_eq!(line!(), 8); }; pin_mut!(s); while s.next().await.is_some() { unreachable!(); } } async-stream-0.3.6/tests/stream.rs000064400000000000000000000110051046102023000152400ustar 00000000000000use async_stream::stream; use futures_core::stream::{FusedStream, Stream}; use futures_util::pin_mut; use futures_util::stream::StreamExt; use tokio::sync::mpsc; use tokio_test::assert_ok; #[tokio::test] async fn noop_stream() { let s = stream! {}; pin_mut!(s); while s.next().await.is_some() { unreachable!(); } } #[tokio::test] async fn empty_stream() { let mut ran = false; { let r = &mut ran; let s = stream! { *r = true; println!("hello world!"); }; pin_mut!(s); while s.next().await.is_some() { unreachable!(); } } assert!(ran); } #[tokio::test] async fn yield_single_value() { let s = stream! { yield "hello"; }; let values: Vec<_> = s.collect().await; assert_eq!(1, values.len()); assert_eq!("hello", values[0]); } #[tokio::test] async fn fused() { let s = stream! { yield "hello"; }; pin_mut!(s); assert!(!s.is_terminated()); assert_eq!(s.next().await, Some("hello")); assert_eq!(s.next().await, None); assert!(s.is_terminated()); // This should return None from now on assert_eq!(s.next().await, None); } #[tokio::test] async fn yield_multi_value() { let s = stream! { yield "hello"; yield "world"; yield "dizzy"; }; let values: Vec<_> = s.collect().await; assert_eq!(3, values.len()); assert_eq!("hello", values[0]); assert_eq!("world", values[1]); assert_eq!("dizzy", values[2]); } #[tokio::test] async fn unit_yield_in_select() { use tokio::select; async fn do_stuff_async() {} let s = stream! { select! { _ = do_stuff_async() => yield, else => yield, } }; let values: Vec<_> = s.collect().await; assert_eq!(values.len(), 1); } #[tokio::test] async fn yield_with_select() { use tokio::select; async fn do_stuff_async() {} async fn more_async_work() {} let s = stream! { select! { _ = do_stuff_async() => yield "hey", _ = more_async_work() => yield "hey", else => yield "hey", } }; let values: Vec<_> = s.collect().await; assert_eq!(values, vec!["hey"]); } #[tokio::test] async fn return_stream() { fn build_stream() -> impl Stream { stream! { yield 1; yield 2; yield 3; } } let s = build_stream(); let values: Vec<_> = s.collect().await; assert_eq!(3, values.len()); assert_eq!(1, values[0]); assert_eq!(2, values[1]); assert_eq!(3, values[2]); } #[tokio::test] async fn consume_channel() { let (tx, mut rx) = mpsc::channel(10); let s = stream! { while let Some(v) = rx.recv().await { yield v; } }; pin_mut!(s); for i in 0..3 { assert_ok!(tx.send(i).await); assert_eq!(Some(i), s.next().await); } drop(tx); assert_eq!(None, s.next().await); } #[tokio::test] async fn borrow_self() { struct Data(String); impl Data { fn stream<'a>(&'a self) -> impl Stream + 'a { stream! { yield &self.0[..]; } } } let data = Data("hello".to_string()); let s = data.stream(); pin_mut!(s); assert_eq!(Some("hello"), s.next().await); } #[tokio::test] async fn stream_in_stream() { let s = stream! { let s = stream! { for i in 0..3 { yield i; } }; pin_mut!(s); while let Some(v) = s.next().await { yield v; } }; let values: Vec<_> = s.collect().await; assert_eq!(3, values.len()); } #[tokio::test] async fn yield_non_unpin_value() { let s: Vec<_> = stream! { for i in 0..3 { yield async move { i }; } } .buffered(1) .collect() .await; assert_eq!(s, vec![0, 1, 2]); } #[test] fn inner_try_stream() { use async_stream::try_stream; use tokio::select; async fn do_stuff_async() {} let _ = stream! { select! { _ = do_stuff_async() => { let another_s = try_stream! { yield; }; let _: Result<(), ()> = Box::pin(another_s).next().await.unwrap(); }, else => {}, } yield }; } #[rustversion::attr(not(stable), ignore)] #[test] fn test() { let t = trybuild::TestCases::new(); t.compile_fail("tests/ui/*.rs"); } async-stream-0.3.6/tests/try_stream.rs000064400000000000000000000036141046102023000161450ustar 00000000000000use async_stream::try_stream; use futures_core::stream::Stream; use futures_util::stream::StreamExt; #[tokio::test] async fn single_err() { let s = try_stream! { if true { Err("hello")?; } else { yield "world"; } unreachable!(); }; let values: Vec<_> = s.collect().await; assert_eq!(1, values.len()); assert_eq!(Err("hello"), values[0]); } #[tokio::test] async fn yield_then_err() { let s = try_stream! { yield "hello"; Err("world")?; unreachable!(); }; let values: Vec<_> = s.collect().await; assert_eq!(2, values.len()); assert_eq!(Ok("hello"), values[0]); assert_eq!(Err("world"), values[1]); } #[tokio::test] async fn convert_err() { struct ErrorA(u8); #[derive(PartialEq, Debug)] struct ErrorB(u8); impl From for ErrorB { fn from(a: ErrorA) -> ErrorB { ErrorB(a.0) } } fn test() -> impl Stream> { try_stream! { if true { Err(ErrorA(1))?; } else { Err(ErrorB(2))?; } yield "unreachable"; } } let values: Vec<_> = test().collect().await; assert_eq!(1, values.len()); assert_eq!(Err(ErrorB(1)), values[0]); } #[tokio::test] async fn multi_try() { fn test() -> impl Stream> { try_stream! { let a = Ok::<_, String>(Ok::<_, String>(123))??; for _ in 1..10 { yield a; } } } let values: Vec<_> = test().collect().await; assert_eq!(9, values.len()); assert_eq!( std::iter::repeat(123).take(9).map(Ok).collect::>(), values ); } #[allow(unused)] fn issue_65() -> impl Stream> { try_stream! { yield Err(())?; } } async-stream-0.3.6/tests/ui/unsoundness_issue_106.rs000064400000000000000000000012101046102023000205410ustar 00000000000000use async_stream::stream; use futures_util::StreamExt; use std::pin::pin; macro_rules! asynk { ($e:expr) => { async { $e } }; } #[tokio::main] async fn main() { pin!(stream! { let yield_42 = asynk!(yield 42_usize); let s = stream! { yield Box::new(12345); yield_42.await; // yield 42 -- wait that's not a Box!? }; for await (n, i) in s.enumerate() { println!("Item at index {n}:\n {i}"); // Item at index 0: // 12345 // Item at index 1: // Segmentation fault } }) .next() .await; } async-stream-0.3.6/tests/ui/unsoundness_issue_106.stderr000064400000000000000000000025641046102023000214350ustar 00000000000000error[E0767]: use of unreachable label `'__async_stream_private_check_scope` --> tests/ui/unsoundness_issue_106.rs:14:10 | 14 | pin!(stream! { | __________^ 15 | | let yield_42 = asynk!(yield 42_usize); 16 | | let s = stream! { 17 | | yield Box::new(12345); ... | 26 | | } 27 | | }) | | ^ | | | | |_____unreachable label `'__async_stream_private_check_scope` | unreachable label defined here | = note: labels are unreachable through functions, closures, async blocks and modules = note: this error originates in the macro `$crate::__private::stream_inner` which comes from the expansion of the macro `stream` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0267]: `break` inside `async` block --> tests/ui/unsoundness_issue_106.rs:14:10 | 8 | async { $e } | ----- enclosing `async` block ... 14 | pin!(stream! { | __________^ 15 | | let yield_42 = asynk!(yield 42_usize); 16 | | let s = stream! { 17 | | yield Box::new(12345); ... | 26 | | } 27 | | }) | |_____^ cannot `break` inside `async` block | = note: this error originates in the macro `$crate::__private::stream_inner` which comes from the expansion of the macro `stream` (in Nightly builds, run with -Z macro-backtrace for more info) async-stream-0.3.6/tests/ui/unsoundness_issue_107.rs000064400000000000000000000007621046102023000205550ustar 00000000000000use async_stream::stream; use futures_util::StreamExt; use std::pin::pin; #[tokio::main] async fn main() { let mut outer = vec![]; { let v = vec![0; 10]; let v_ref = &v; let mut s = pin!(stream! { for x in v_ref { yield x } }); while let Some(x) = s.next().await { outer.push(x); } }; // use-after-free println!("{outer:?}"); // […garbage allocator internals…, 0, 0, 0] } async-stream-0.3.6/tests/ui/unsoundness_issue_107.stderr000064400000000000000000000007601046102023000214320ustar 00000000000000error[E0597]: `v` does not live long enough --> tests/ui/unsoundness_issue_107.rs:11:21 | 10 | let v = vec![0; 10]; | - binding `v` declared here 11 | let v_ref = &v; | ^^ borrowed value does not live long enough ... 20 | }; | - `v` dropped here while still borrowed 21 | // use-after-free 22 | println!("{outer:?}"); // […garbage allocator internals…, 0, 0, 0] | --------- borrow later used here async-stream-0.3.6/tests/ui/yield_bad_expr_in_macro.rs000064400000000000000000000002441046102023000212060ustar 00000000000000use async_stream::stream; fn main() { async fn work() {} stream! { tokio::select! { _ = work() => yield fn f() {}, } }; } async-stream-0.3.6/tests/ui/yield_bad_expr_in_macro.stderr000064400000000000000000000002461046102023000220670ustar 00000000000000error: expected an expression --> tests/ui/yield_bad_expr_in_macro.rs:8:33 | 8 | _ = work() => yield fn f() {}, | ^^ async-stream-0.3.6/tests/ui/yield_in_async.rs000064400000000000000000000002221046102023000173520ustar 00000000000000use async_stream::stream; fn main() { stream! { let f = async { yield 123; }; let v = f.await; }; } async-stream-0.3.6/tests/ui/yield_in_async.stderr000064400000000000000000000006041046102023000202350ustar 00000000000000error[E0658]: yield syntax is experimental --> tests/ui/yield_in_async.rs:6:13 | 6 | yield 123; | ^^^^^^^^^ | = note: see issue #43122 for more information error[E0727]: `async` coroutines are not yet supported --> tests/ui/yield_in_async.rs:6:13 | 6 | yield 123; | ^^^^^^^^^ async-stream-0.3.6/tests/ui/yield_in_closure.rs000064400000000000000000000002561046102023000177200ustar 00000000000000use async_stream::stream; fn main() { stream! { Ok("value") .and_then(|v| { yield v; Ok(()) }); }; } async-stream-0.3.6/tests/ui/yield_in_closure.stderr000064400000000000000000000027201046102023000205750ustar 00000000000000error[E0658]: yield syntax is experimental --> tests/ui/yield_in_closure.rs:7:17 | 7 | yield v; | ^^^^^^^ | = note: see issue #43122 for more information error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks --> tests/ui/yield_in_closure.rs:7:17 | 7 | yield v; | ^^^^^^^ | help: use `#[coroutine]` to make this closure a coroutine | 6 | .and_then(#[coroutine] |v| { | ++++++++++++ error[E0277]: expected a `FnOnce(&str)` closure, found `{coroutine@$DIR/tests/ui/yield_in_closure.rs:6:23: 6:26}` --> tests/ui/yield_in_closure.rs:6:23 | 6 | .and_then(|v| { | ______________--------_^ | | | | | required by a bound introduced by this call 7 | | yield v; 8 | | Ok(()) 9 | | }); | |_____________^ expected an `FnOnce(&str)` closure, found `{coroutine@$DIR/tests/ui/yield_in_closure.rs:6:23: 6:26}` | = help: the trait `FnOnce(&str)` is not implemented for `{coroutine@$DIR/tests/ui/yield_in_closure.rs:6:23: 6:26}` note: required by a bound in `Result::::and_then` --> $RUST/core/src/result.rs | | pub fn and_then Result>(self, op: F) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Result::::and_then` async-stream-0.3.6/tests/ui/yield_in_nested_fn.rs000064400000000000000000000001661046102023000202110ustar 00000000000000use async_stream::stream; fn main() { stream! { fn foo() { yield "hello"; } }; } async-stream-0.3.6/tests/ui/yield_in_nested_fn.stderr000064400000000000000000000013271046102023000210700ustar 00000000000000error[E0658]: yield syntax is experimental --> tests/ui/yield_in_nested_fn.rs:6:13 | 6 | yield "hello"; | ^^^^^^^^^^^^^ | = note: see issue #43122 for more information error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks --> tests/ui/yield_in_nested_fn.rs:6:13 | 6 | yield "hello"; | ^^^^^^^^^^^^^ | help: use `#[coroutine]` to make this closure a coroutine | 5 | #[coroutine] fn foo() { | ++++++++++++ error[E0627]: yield expression outside of coroutine literal --> tests/ui/yield_in_nested_fn.rs:6:13 | 6 | yield "hello"; | ^^^^^^^^^^^^^