Fix research tool UI: remove duplicate header, add footer spacing, remove spinner, widen command display
- Remove duplicate tool header (lib.rs already prints it) - Add newline before timing footer for visual separation - Remove spinner animation (incompatible with update_tool_output_line) - Change shell command format to " > `cmd` ..." with 60 char width
This commit is contained in:
413
tmp/async_stream_docs.html
Normal file
413
tmp/async_stream_docs.html
Normal file
@@ -0,0 +1,413 @@
|
||||
<html lang="en" data-theme="dark" data-docs-rs-theme="dark"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Asynchronous stream of elements."><title>async_stream - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="/-/rustdoc.static/${f}">`).join(""))</script><link rel="preload" as="font" type="font/woff2" href="/-/rustdoc.static/SourceSerif4-Regular-6b053e98.ttf.woff2"><link rel="preload" as="font" type="font/woff2" href="/-/rustdoc.static/FiraSans-Italic-81dc35de.woff2"><link rel="preload" as="font" type="font/woff2" href="/-/rustdoc.static/FiraSans-Regular-0fe48ade.woff2"><link rel="preload" as="font" type="font/woff2" href="/-/rustdoc.static/FiraSans-MediumItalic-ccf7e434.woff2"><link rel="preload" as="font" type="font/woff2" href="/-/rustdoc.static/FiraSans-Medium-e1aa3f0a.woff2"><link rel="preload" as="font" type="font/woff2" href="/-/rustdoc.static/SourceCodePro-Regular-8badfe75.ttf.woff2"><link rel="preload" as="font" type="font/woff2" href="/-/rustdoc.static/SourceCodePro-Semibold-aa29a496.ttf.woff2"><link rel="stylesheet" href="/-/rustdoc.static/normalize-9960930a.css"><link rel="stylesheet" href="/-/static/vendored.css?0-1-0-7bfb09c2-2026-01-03" media="all"><link rel="stylesheet" href="/-/rustdoc.static/rustdoc-80aa586b.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="/-/rustdoc.static/" data-current-crate="async_stream" data-themes="" data-resource-suffix="-20251223-1.94.0-nightly-2ca7bcd03" data-rustdoc-version="1.94.0-nightly (2ca7bcd03 2025-12-23)" data-channel="nightly" data-search-js="search-9e2438ea.js" data-stringdex-js="stringdex-b897f86f.js" data-settings-js="settings-c38705f0.js"><script src="/-/rustdoc.static/storage-e2aeef58.js"></script><script defer="" src="../crates-20251223-1.94.0-nightly-2ca7bcd03.js"></script><script defer="" src="/-/rustdoc.static/main-3e30299d.js"></script><noscript><link rel="stylesheet" href="/-/rustdoc.static/noscript-ffcac47a.css"></noscript><link rel="alternate icon" type="image/png" href="/-/rustdoc.static/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="/-/rustdoc.static/favicon-044be391.svg"><link rel="stylesheet" href="/-/static/rustdoc-2025-08-20.css?0-1-0-7bfb09c2-2026-01-03" media="all"><link rel="stylesheet" href="/-/static/font-awesome.css?0-1-0-7bfb09c2-2026-01-03" media="all">
|
||||
|
||||
<link rel="search" href="/-/static/opensearch.xml" type="application/opensearchdescription+xml" title="Docs.rs">
|
||||
|
||||
<script type="text/javascript">(function() {
|
||||
function applyTheme(theme) {
|
||||
if (theme) {
|
||||
document.documentElement.dataset.docsRsTheme = theme;
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("storage", ev => {
|
||||
if (ev.key === "rustdoc-theme") {
|
||||
applyTheme(ev.newValue);
|
||||
}
|
||||
});
|
||||
|
||||
// see ./storage-change-detection.html for details
|
||||
window.addEventListener("message", ev => {
|
||||
if (ev.data && ev.data.storage && ev.data.storage.key === "rustdoc-theme") {
|
||||
applyTheme(ev.data.storage.value);
|
||||
}
|
||||
});
|
||||
|
||||
applyTheme(window.localStorage.getItem("rustdoc-theme"));
|
||||
})();</script></head><div style="display: none; position: fixed; width: 100%; height: 100%; z-index: 1;"></div><body class="rustdoc-page">
|
||||
<div class="nav-container">
|
||||
<div class="container">
|
||||
<div class="pure-menu pure-menu-horizontal" role="navigation" aria-label="Main navigation">
|
||||
<form action="/releases/search" method="GET" id="nav-search-form" class="landing-search-form-nav ">
|
||||
|
||||
|
||||
<a href="/" class="pure-menu-heading pure-menu-link docsrs-logo" aria-label="Docs.rs">
|
||||
<span title="Docs.rs"><span class="fa fa-solid fa-cubes " aria-hidden="true"></span></span>
|
||||
<span class="title">Docs.rs</span>
|
||||
</a><ul class="pure-menu-list">
|
||||
<script id="crate-metadata" type="application/json">
|
||||
|
||||
{
|
||||
"name": "async-stream",
|
||||
"version": "0.3.6"
|
||||
}
|
||||
</script><li class="pure-menu-item pure-menu-has-children">
|
||||
<a href="#" class="pure-menu-link crate-name" title="Asynchronous streams using async & await notation" aria-haspopup="menu">
|
||||
<span class="fa fa-solid fa-cube " aria-hidden="true"></span>
|
||||
<span class="title">async-stream-0.3.6</span>
|
||||
</a><div class="pure-menu-children package-details-menu" role="menu">
|
||||
|
||||
<ul class="pure-menu-list menu-item-divided">
|
||||
<li class="pure-menu-heading" id="crate-title">
|
||||
async-stream 0.3.6
|
||||
<span id="clipboard" class="svg-clipboard" title="Copy crate name and version information"></span>
|
||||
</li><li class="pure-menu-item">
|
||||
<a href="/async-stream/0.3.6/async_stream/" class="pure-menu-link description" id="permalink" title="Get a link to this specific version"><span class="fa fa-solid fa-link " aria-hidden="true"></span> Permalink
|
||||
</a>
|
||||
</li><li class="pure-menu-item">
|
||||
<a href="/crate/async-stream/latest" class="pure-menu-link description" title="See async-stream in docs.rs">
|
||||
<span class="fa fa-solid fa-cube " aria-hidden="true"></span> Docs.rs crate page
|
||||
</a>
|
||||
</li><li class="pure-menu-item">
|
||||
<span class="pure-menu-link description"><span class="fa fa-solid fa-scale-unbalanced-flip " aria-hidden="true"></span>
|
||||
<a href="https://spdx.org/licenses/MIT" class="pure-menu-sublink">MIT</a></span>
|
||||
</li></ul>
|
||||
|
||||
<div class="pure-g menu-item-divided">
|
||||
<div class="pure-u-1-2 right-border">
|
||||
<ul class="pure-menu-list">
|
||||
<li class="pure-menu-heading">Links</li>
|
||||
|
||||
<li class="pure-menu-item">
|
||||
<a href="https://github.com/tokio-rs/async-stream" class="pure-menu-link">
|
||||
<span class="fa fa-solid fa-code-branch " aria-hidden="true"></span> Repository
|
||||
</a>
|
||||
</li><li class="pure-menu-item">
|
||||
<a href="https://crates.io/crates/async-stream" class="pure-menu-link" title="See async-stream in crates.io">
|
||||
<span class="fa fa-solid fa-cube " aria-hidden="true"></span> crates.io
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li class="pure-menu-item">
|
||||
<a href="/crate/async-stream/latest/source/" title="Browse source of async-stream-0.3.6" class="pure-menu-link">
|
||||
<span class="fa fa-solid fa-folder-open " aria-hidden="true"></span> Source
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div><div class="pure-u-1-2">
|
||||
<ul class="pure-menu-list" id="topbar-owners">
|
||||
<li class="pure-menu-heading">Owners</li><li class="pure-menu-item">
|
||||
<a href="https://crates.io/users/carllerche" class="pure-menu-link">
|
||||
<span class="fa fa-solid fa-user " aria-hidden="true"></span> carllerche
|
||||
</a>
|
||||
</li><li class="pure-menu-item">
|
||||
<a href="https://crates.io/teams/github:tokio-rs:core" class="pure-menu-link">
|
||||
<span class="fa fa-solid fa-user " aria-hidden="true"></span> github:tokio-rs:core
|
||||
</a>
|
||||
</li></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pure-g menu-item-divided">
|
||||
<div class="pure-u-1-2 right-border">
|
||||
<ul class="pure-menu-list">
|
||||
<li class="pure-menu-heading">Dependencies</li>
|
||||
|
||||
|
||||
<li class="pure-menu-item">
|
||||
<div class="pure-menu pure-menu-scrollable sub-menu" tabindex="-1">
|
||||
<ul class="pure-menu-list">
|
||||
<li class="pure-menu-item"><a href="/async-stream-impl/=0.3.6/" class="pure-menu-link">
|
||||
async-stream-impl =0.3.6
|
||||
|
||||
<i class="dependencies normal">normal</i>
|
||||
|
||||
|
||||
</a>
|
||||
</li><li class="pure-menu-item"><a href="/futures-core/^0.3/" class="pure-menu-link">
|
||||
futures-core ^0.3
|
||||
|
||||
<i class="dependencies normal">normal</i>
|
||||
|
||||
|
||||
</a>
|
||||
</li><li class="pure-menu-item"><a href="/pin-project-lite/^0.2/" class="pure-menu-link">
|
||||
pin-project-lite ^0.2
|
||||
|
||||
<i class="dependencies normal">normal</i>
|
||||
|
||||
|
||||
</a>
|
||||
</li><li class="pure-menu-item"><a href="/futures-util/^0.3/" class="pure-menu-link">
|
||||
futures-util ^0.3
|
||||
|
||||
<i class="dependencies dev">dev</i>
|
||||
|
||||
|
||||
</a>
|
||||
</li><li class="pure-menu-item"><a href="/rustversion/^1/" class="pure-menu-link">
|
||||
rustversion ^1
|
||||
|
||||
<i class="dependencies dev">dev</i>
|
||||
|
||||
|
||||
</a>
|
||||
</li><li class="pure-menu-item"><a href="/tokio/^1/" class="pure-menu-link">
|
||||
tokio ^1
|
||||
|
||||
<i class="dependencies dev">dev</i>
|
||||
|
||||
|
||||
</a>
|
||||
</li><li class="pure-menu-item"><a href="/trybuild/^1/" class="pure-menu-link">
|
||||
trybuild ^1
|
||||
|
||||
<i class="dependencies dev">dev</i>
|
||||
|
||||
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="pure-u-1-2">
|
||||
<ul class="pure-menu-list">
|
||||
<li class="pure-menu-heading">Versions</li>
|
||||
|
||||
<li class="pure-menu-item">
|
||||
<div class="pure-menu pure-menu-scrollable sub-menu" id="releases-list" tabindex="-1" data-url="/crate/async-stream/latest/menus/releases/async_stream/">
|
||||
<span class="rotate"><span class="fa fa-solid fa-spinner " aria-hidden="true"></span></span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-1">
|
||||
<ul class="pure-menu-list">
|
||||
<li>
|
||||
<a href="/crate/async-stream/latest" class="pure-menu-link">
|
||||
<b>100%</b>
|
||||
of the crate is documented
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div></div>
|
||||
</li><li class="pure-menu-item pure-menu-has-children">
|
||||
<a href="#" class="pure-menu-link" aria-label="Platform" aria-haspopup="menu">
|
||||
<span class="fa fa-solid fa-gears " aria-hidden="true"></span>
|
||||
<span class="title">Platform</span>
|
||||
</a>
|
||||
|
||||
|
||||
<ul class="pure-menu-children" id="platforms" data-url="/crate/async-stream/latest/menus/platforms/async_stream/" role="menu"><li class="pure-menu-item">
|
||||
<a href="/crate/async-stream/latest/target-redirect/aarch64-apple-darwin/async_stream/" class="pure-menu-link" data-fragment="retain" rel="nofollow">aarch64-apple-darwin</a>
|
||||
</li><li class="pure-menu-item">
|
||||
<a href="/crate/async-stream/latest/target-redirect/aarch64-unknown-linux-gnu/async_stream/" class="pure-menu-link" data-fragment="retain" rel="nofollow">aarch64-unknown-linux-gnu</a>
|
||||
</li><li class="pure-menu-item">
|
||||
<a href="/crate/async-stream/latest/target-redirect/i686-pc-windows-msvc/async_stream/" class="pure-menu-link" data-fragment="retain" rel="nofollow">i686-pc-windows-msvc</a>
|
||||
</li><li class="pure-menu-item">
|
||||
<a href="/crate/async-stream/latest/target-redirect/x86_64-pc-windows-msvc/async_stream/" class="pure-menu-link" data-fragment="retain" rel="nofollow">x86_64-pc-windows-msvc</a>
|
||||
</li><li class="pure-menu-item">
|
||||
<a href="/crate/async-stream/latest/target-redirect/async_stream/" class="pure-menu-link" data-fragment="retain" rel="nofollow">x86_64-unknown-linux-gnu</a>
|
||||
</li></ul>
|
||||
</li><li class="pure-menu-item">
|
||||
<a href="/crate/async-stream/latest/features" title="Browse available feature flags of async-stream-0.3.6" class="pure-menu-link">
|
||||
<span class="fa fa-solid fa-flag " aria-hidden="true"></span>
|
||||
<span class="title">Feature flags</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
</ul><div class="spacer"></div>
|
||||
|
||||
|
||||
|
||||
<ul class="pure-menu-list">
|
||||
<li class="pure-menu-item pure-menu-has-children">
|
||||
<a href="#" class="pure-menu-link" aria-label="docs.rs" aria-haspopup="menu">docs.rs</a>
|
||||
<ul class="pure-menu-children aligned-icons" role="menu"><li class="pure-menu-item"><a class="pure-menu-link" href="/about"><span class="fa fa-solid fa-circle-info " aria-hidden="true"></span> About docs.rs</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/about/badges"><span class="fa fa-brands fa-fonticons " aria-hidden="true"></span> Badges</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/about/builds"><span class="fa fa-solid fa-gears " aria-hidden="true"></span> Builds</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/about/metadata"><span class="fa fa-solid fa-table " aria-hidden="true"></span> Metadata</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/about/redirections"><span class="fa fa-solid fa-road " aria-hidden="true"></span> Shorthand URLs</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/about/download"><span class="fa fa-solid fa-download " aria-hidden="true"></span> Download</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/about/rustdoc-json"><span class="fa fa-solid fa-file-code " aria-hidden="true"></span> Rustdoc JSON</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="/releases/queue"><span class="fa fa-solid fa-gears " aria-hidden="true"></span> Build queue</a></li><li class="pure-menu-item"><a class="pure-menu-link" href="https://foundation.rust-lang.org/policies/privacy-policy/#docs.rs" target="_blank"><span class="fa fa-solid fa-shield-halved " aria-hidden="true"></span> Privacy policy</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="pure-menu-list"><li class="pure-menu-item pure-menu-has-children">
|
||||
<a href="#" class="pure-menu-link" aria-label="Rust" aria-haspopup="menu">Rust</a>
|
||||
<ul class="pure-menu-children" role="menu">
|
||||
<li class="pure-menu-item"><a class="pure-menu-link" href="https://www.rust-lang.org/" target="_blank">Rust website</a></li>
|
||||
<li class="pure-menu-item"><a class="pure-menu-link" href="https://doc.rust-lang.org/book/" target="_blank">The Book</a></li>
|
||||
|
||||
<li class="pure-menu-item"><a class="pure-menu-link" href="https://doc.rust-lang.org/std/" target="_blank">Standard Library API Reference</a></li>
|
||||
|
||||
<li class="pure-menu-item"><a class="pure-menu-link" href="https://doc.rust-lang.org/rust-by-example/" target="_blank">Rust by Example</a></li>
|
||||
|
||||
<li class="pure-menu-item"><a class="pure-menu-link" href="https://doc.rust-lang.org/cargo/guide/" target="_blank">The Cargo Guide</a></li>
|
||||
|
||||
<li class="pure-menu-item"><a class="pure-menu-link" href="https://doc.rust-lang.org/nightly/clippy" target="_blank">Clippy Documentation</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div id="search-input-nav">
|
||||
<label for="nav-search">
|
||||
<span class="fa fa-solid fa-magnifying-glass " aria-hidden="true"></span>
|
||||
</label>
|
||||
|
||||
|
||||
|
||||
<input id="nav-search" name="query" type="text" aria-label="Find crate by search query" tabindex="-1" placeholder="Find crate">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="rustdoc mod crate container-rustdoc" id="rustdoc_body_wrapper" tabindex="-1"><script async="" src="/-/static/menu.js?0-1-0-7bfb09c2-2026-01-03"></script>
|
||||
<script async="" src="/-/static/index.js?0-1-0-7bfb09c2-2026-01-03"></script>
|
||||
|
||||
<iframe src="/-/storage-change-detection.html" width="0" height="0" style="display: none"></iframe><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><rustdoc-topbar>
|
||||
<button class="sidebar-menu-toggle" slot="sidebar-menu-toggle" title="show sidebar">
|
||||
</button>
|
||||
<div class="settings-menu" slot="settings-menu" tabindex="-1">
|
||||
<a href="../settings.html"><span class="label">Settings</span></a>
|
||||
</div>
|
||||
<div class="help-menu" slot="help-menu" tabindex="-1">
|
||||
<a href="../help.html"><span class="label">Help</span></a>
|
||||
</div>
|
||||
<h2><a href="#">Crate async_stream</a></h2></rustdoc-topbar><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../async_stream/index.html">async_<wbr>stream</a><span class="version">0.3.6</span></h2></div><div class="sidebar-elems"><ul class="block"><li><a id="all-types" href="all.html">All Items</a></li></ul><section id="rustdoc-toc"><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#usage" title="Usage">Usage</a></li><li><a href="#implementation" title="Implementation">Implementation</a></li></ul><h3><a href="#macros">Crate Items</a></h3><ul class="block"><li><a href="#macros" title="Macros">Macros</a></li></ul></section><div id="rustdoc-modnav"><h3>Crates</h3><ul class="block crate"><li class="current"><a href="../async_stream/index.html">async_stream</a></li></ul></div></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><div class="width-limiter"><section id="main-content" class="content"><div class="main-heading"><div id="sidebar-button"><a href="../async_stream/all.html" title="show sidebar"></a></div><h1>Crate <span>async_<wbr>stream</span> <button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><span class="sub-heading"><a class="src" href="../src/async_stream/lib.rs.html#1-242">Source</a> </span><rustdoc-toolbar>
|
||||
<div id="search-button" tabindex="-1">
|
||||
<a href="https://docs.rs/async-stream/latest/async_stream/?search="><span class="label">Search</span></a>
|
||||
</div>
|
||||
<div class="settings-menu" tabindex="-1">
|
||||
<a href="../settings.html"><span class="label">Settings</span></a>
|
||||
</div>
|
||||
<div class="help-menu" tabindex="-1">
|
||||
<a href="../help.html"><span class="label">Help</span></a>
|
||||
</div>
|
||||
<button id="toggle-all-docs" title="Collapse sections (shift-click to also collapse impl blocks)"><span class="label">Summary</span></button></rustdoc-toolbar></div><details class="toggle top-doc" open=""><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Asynchronous stream of elements.</p>
|
||||
<p>Provides two macros, <code>stream!</code> and <code>try_stream!</code>, allowing the caller to
|
||||
define asynchronous streams of elements. These are implemented using <code>async</code>
|
||||
& <code>await</code> notation. This crate works without unstable features.</p>
|
||||
<p>The <code>stream!</code> macro returns an anonymous type implementing the <a href="https://docs.rs/futures-core/*/futures_core/stream/trait.Stream.html"><code>Stream</code></a>
|
||||
trait. The <code>Item</code> associated type is the type of the values yielded from the
|
||||
stream. The <code>try_stream!</code> also returns an anonymous type implementing the
|
||||
<a href="https://docs.rs/futures-core/*/futures_core/stream/trait.Stream.html"><code>Stream</code></a> trait, but the <code>Item</code> associated type is <code>Result<T, Error></code>. The
|
||||
<code>try_stream!</code> macro supports using <code>?</code> notation as part of the
|
||||
implementation.</p>
|
||||
<h2 id="usage"><a class="doc-anchor" href="#usage">§</a>Usage</h2>
|
||||
<p>A basic stream yielding numbers. Values are yielded using the <code>yield</code>
|
||||
keyword. The stream block must return <code>()</code>.</p>
|
||||
|
||||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>async_stream::stream;
|
||||
|
||||
<span class="kw">use </span>futures_util::pin_mut;
|
||||
<span class="kw">use </span>futures_util::stream::StreamExt;
|
||||
|
||||
<span class="attr">#[tokio::main]
|
||||
</span><span class="kw">async fn </span>main() {
|
||||
<span class="kw">let </span>s = <span class="macro">stream!</span> {
|
||||
<span class="kw">for </span>i <span class="kw">in </span><span class="number">0</span>..<span class="number">3 </span>{
|
||||
<span class="kw">yield </span>i;
|
||||
}
|
||||
};
|
||||
|
||||
<span class="macro">pin_mut!</span>(s); <span class="comment">// needed for iteration
|
||||
|
||||
</span><span class="kw">while let </span><span class="prelude-val">Some</span>(value) = s.next().<span class="kw">await </span>{
|
||||
<span class="macro">println!</span>(<span class="string">"got {}"</span>, value);
|
||||
}
|
||||
}</code></pre></div>
|
||||
<p>Streams may be returned by using <code>impl Stream<Item = T></code>:</p>
|
||||
|
||||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>async_stream::stream;
|
||||
|
||||
<span class="kw">use </span>futures_core::stream::Stream;
|
||||
<span class="kw">use </span>futures_util::pin_mut;
|
||||
<span class="kw">use </span>futures_util::stream::StreamExt;
|
||||
|
||||
<span class="kw">fn </span>zero_to_three() -> <span class="kw">impl </span>Stream<Item = u32> {
|
||||
<span class="macro">stream!</span> {
|
||||
<span class="kw">for </span>i <span class="kw">in </span><span class="number">0</span>..<span class="number">3 </span>{
|
||||
<span class="kw">yield </span>i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<span class="attr">#[tokio::main]
|
||||
</span><span class="kw">async fn </span>main() {
|
||||
<span class="kw">let </span>s = zero_to_three();
|
||||
<span class="macro">pin_mut!</span>(s); <span class="comment">// needed for iteration
|
||||
|
||||
</span><span class="kw">while let </span><span class="prelude-val">Some</span>(value) = s.next().<span class="kw">await </span>{
|
||||
<span class="macro">println!</span>(<span class="string">"got {}"</span>, value);
|
||||
}
|
||||
}</code></pre></div>
|
||||
<p>Streams may be implemented in terms of other streams - <code>async-stream</code> provides <code>for await</code>
|
||||
syntax to assist with this:</p>
|
||||
|
||||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>async_stream::stream;
|
||||
|
||||
<span class="kw">use </span>futures_core::stream::Stream;
|
||||
<span class="kw">use </span>futures_util::pin_mut;
|
||||
<span class="kw">use </span>futures_util::stream::StreamExt;
|
||||
|
||||
<span class="kw">fn </span>zero_to_three() -> <span class="kw">impl </span>Stream<Item = u32> {
|
||||
<span class="macro">stream!</span> {
|
||||
<span class="kw">for </span>i <span class="kw">in </span><span class="number">0</span>..<span class="number">3 </span>{
|
||||
<span class="kw">yield </span>i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<span class="kw">fn </span>double<S: Stream<Item = u32>>(input: S)
|
||||
-> <span class="kw">impl </span>Stream<Item = u32>
|
||||
{
|
||||
<span class="macro">stream!</span> {
|
||||
<span class="kw">for await </span>value <span class="kw">in </span>input {
|
||||
<span class="kw">yield </span>value * <span class="number">2</span>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<span class="attr">#[tokio::main]
|
||||
</span><span class="kw">async fn </span>main() {
|
||||
<span class="kw">let </span>s = double(zero_to_three());
|
||||
<span class="macro">pin_mut!</span>(s); <span class="comment">// needed for iteration
|
||||
|
||||
</span><span class="kw">while let </span><span class="prelude-val">Some</span>(value) = s.next().<span class="kw">await </span>{
|
||||
<span class="macro">println!</span>(<span class="string">"got {}"</span>, value);
|
||||
}
|
||||
}</code></pre></div>
|
||||
<p>Rust try notation (<code>?</code>) can be used with the <code>try_stream!</code> macro. The <code>Item</code>
|
||||
of the returned stream is <code>Result</code> with <code>Ok</code> being the value yielded and
|
||||
<code>Err</code> the error type returned by <code>?</code>.</p>
|
||||
|
||||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>tokio::net::{TcpListener, TcpStream};
|
||||
|
||||
<span class="kw">use </span>async_stream::try_stream;
|
||||
<span class="kw">use </span>futures_core::stream::Stream;
|
||||
|
||||
<span class="kw">use </span>std::io;
|
||||
<span class="kw">use </span>std::net::SocketAddr;
|
||||
|
||||
<span class="kw">fn </span>bind_and_accept(addr: SocketAddr)
|
||||
-> <span class="kw">impl </span>Stream<Item = io::Result<TcpStream>>
|
||||
{
|
||||
<span class="macro">try_stream!</span> {
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>listener = TcpListener::bind(addr).<span class="kw">await</span><span class="question-mark">?</span>;
|
||||
|
||||
<span class="kw">loop </span>{
|
||||
<span class="kw">let </span>(stream, addr) = listener.accept().<span class="kw">await</span><span class="question-mark">?</span>;
|
||||
<span class="macro">println!</span>(<span class="string">"received on {:?}"</span>, addr);
|
||||
<span class="kw">yield </span>stream;
|
||||
}
|
||||
}
|
||||
}</code></pre></div><h2 id="implementation"><a class="doc-anchor" href="#implementation">§</a>Implementation</h2>
|
||||
<p>The <code>stream!</code> and <code>try_stream!</code> macros are implemented using proc macros.
|
||||
The macro searches the syntax tree for instances of <code>yield $expr</code> and
|
||||
transforms them into <code>sender.send($expr).await</code>.</p>
|
||||
<p>The stream uses a lightweight sender to send values from the stream
|
||||
implementation to the caller. When entering the stream, an <code>Option<T></code> is
|
||||
stored on the stack. A pointer to the cell is stored in a thread local and
|
||||
<code>poll</code> is called on the async block. When <code>poll</code> returns.
|
||||
<code>sender.send(value)</code> stores the value that cell and yields back to the
|
||||
caller.</p>
|
||||
</div></details><h2 id="macros" class="section-header">Macros<a href="#macros" class="anchor">§</a></h2><dl class="item-table"><dt><a class="macro" href="macro.stream.html" title="macro async_stream::stream">stream</a></dt><dd>Asynchronous stream</dd><dt><a class="macro" href="macro.try_stream.html" title="macro async_stream::try_stream">try_<wbr>stream</a></dt><dd>Asynchronous fallible stream</dd></dl></section><section id="alternative-display" class="content hidden"></section><section id="not-displayed" class="hidden"><section id="search"><div class="main-heading search-results-main-heading"><nav class="sub">
|
||||
<form class="search-form loading">
|
||||
<span></span> <!-- This empty span is a hacky fix for Safari: see #93184 -->
|
||||
<input class="search-input" name="search" aria-label="Run search in the documentation" autocomplete="off" spellcheck="false" placeholder="Type ‘S’ or ‘/’ to search, ‘?’ for more options…" type="search">
|
||||
</form>
|
||||
</nav><div class="search-switcher"></div></div><div class="search-out"></div></section></section></div></main></div></body></html>
|
||||
Reference in New Issue
Block a user