Files
tantivy/master/fail/index.html
2019-06-16 03:00:46 +00:00

279 lines
26 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html lang="en"><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="API documentation for the Rust `fail` crate."><meta name="keywords" content="rust, rustlang, rust-lang, fail"><title>fail - Rust</title><link rel="stylesheet" type="text/css" href="../normalize.css"><link rel="stylesheet" type="text/css" href="../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" type="text/css" href="../dark.css"><link rel="stylesheet" type="text/css" href="../light.css" id="themeStyle"><script src="../storage.js"></script><noscript><link rel="stylesheet" href="../noscript.css"></noscript><link rel="shortcut icon" href="../favicon.ico"><style type="text/css">#crate-search{background-image:url("../down-arrow.svg");}</style></head><body class="rustdoc mod"><!--[if lte IE 8]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="sidebar-menu">&#9776;</div><a href='../fail/index.html'><img src='../rust-logo.png' alt='logo' width='100'></a><p class='location'>Crate fail</p><div class="sidebar-elems"><a id='all-types' href='all.html'><p>See all fail's items</p></a><div class="block items"><ul><li><a href="#macros">Macros</a></li><li><a href="#functions">Functions</a></li></ul></div><p class='location'></p><script>window.sidebarCurrent = {name: 'fail', ty: 'mod', relpath: '../'};</script></div></nav><div class="theme-picker"><button id="theme-picker" aria-label="Pick another theme!"><img src="../brush.svg" width="18" alt="Pick another theme!"></button><div id="theme-choices"></div></div><script src="../theme.js"></script><nav class="sub"><form class="search-form js-only"><div class="search-container"><div><select id="crate-search"><option value="All crates">All crates</option></select><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press S to search, ? for more options…" type="search"></div><a id="settings-menu" href="../settings.html"><img src="../wheel.svg" width="18" alt="Change settings"></a></div></form></nav><section id="main" class="content"><h1 class='fqn'><span class='out-of-band'><span id='render-detail'><a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">[<span class='inner'>&#x2212;</span>]</a></span><a class='srclink' href='../src/fail/lib.rs.html#14-1051' title='goto source code'>[src]</a></span><span class='in-band'>Crate <a class="mod" href=''>fail</a></span></h1><div class='docblock'><p>A fail point implementation for Rust.</p>
<p>Fail points are code instrumentations that allow errors and other behavior
to be injected dynamically at runtime, primarily for testing purposes. Fail
points are flexible and can be configured to exhibit a variety of behavior,
including panics, early returns, and sleeping. They can be controlled both
programmatically and via the environment, and can be triggered
conditionally and probabilistically.</p>
<p>This crate is inspired by FreeBSD's
<a href="https://freebsd.org/cgi/man.cgi?query=fail">failpoints</a>.</p>
<h2 id="usage" class="section-header"><a href="#usage">Usage</a></h2>
<p>First, add this to your <code>Cargo.toml</code>:</p>
<pre><code class="language-toml">[dependencies]
fail = &quot;0.2&quot;
</code></pre>
<p>Now you can import the <code>fail_point!</code> macro from the <code>fail</code> crate and use it
to inject dynamic failures.</p>
<p>As an example, here's a simple program that uses a fail point to simulate an
I/O panic:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="attribute">#[<span class="ident">macro_use</span>]</span>
<span class="kw">extern</span> <span class="kw">crate</span> <span class="ident">fail</span>;
<span class="kw">fn</span> <span class="ident">do_fallible_work</span>() {
<span class="macro">fail_point</span><span class="macro">!</span>(<span class="string">&quot;read-dir&quot;</span>);
<span class="kw">let</span> <span class="ident">_dir</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">std</span>::<span class="ident">fs</span>::<span class="ident">read_dir</span>(<span class="string">&quot;.&quot;</span>).<span class="ident">unwrap</span>().<span class="ident">collect</span>();
<span class="comment">// ... do some work on the directory ...</span>
}
<span class="kw">fn</span> <span class="ident">main</span>() {
<span class="ident">fail</span>::<span class="ident">setup</span>();
<span class="ident">do_fallible_work</span>();
<span class="ident">fail</span>::<span class="ident">teardown</span>();
<span class="macro">println</span><span class="macro">!</span>(<span class="string">&quot;done&quot;</span>);
}</pre></div>
<p>Here, the program calls <code>unwrap</code> on the result of <code>read_dir</code>, a function
that returns a <code>Result</code>. In other words, this particular program expects
this call to <code>read_dir</code> to always succeed. And in practice it almost always
will, which makes the behavior of this program when <code>read_dir</code> fails
difficult to test. By instrumenting the program with a fail point we can
pretend that <code>read_dir</code> failed, causing the subsequent <code>unwrap</code> to panic,
and allowing us to observe the program's behavior under failure conditions.</p>
<p>When the program is run normally it just prints &quot;done&quot;:</p>
<pre><code class="language-sh">$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/failpointtest`
done
</code></pre>
<p>But now, by setting the <code>FAILPOINTS</code> variable we can see what happens if the
<code>read_dir</code> fails:</p>
<pre><code class="language-sh">FAILPOINTS=read-dir=panic cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/failpointtest`
thread 'main' panicked at 'failpoint read-dir panic', /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/fail-0.2.0/src/lib.rs:286:25
note: Run with `RUST_BACKTRACE=1` for a backtrace.
</code></pre>
<h2 id="usage-in-tests" class="section-header"><a href="#usage-in-tests">Usage in tests</a></h2>
<p>The previous example triggers a fail point by modifying the <code>FAILPOINT</code>
environment variable. In practice, you'll often want to trigger fail points
programmatically, in unit tests. Unfortunately, unit testing with fail
points is complicated by concurrency concerns, so requires some careful
setup. First, let's see the intuitive — but wrong — way to test
with fail points.</p>
<p>This next example is like the previous, except instead of controlling fail
points with an environment variable, it does so with the <code>fail::cfg</code>
function, and instead of having a <code>main</code> function, it has a test case:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="attribute">#[<span class="ident">macro_use</span>]</span>
<span class="kw">extern</span> <span class="kw">crate</span> <span class="ident">fail</span>;
<span class="kw">fn</span> <span class="ident">do_fallible_work</span>() {
<span class="macro">fail_point</span><span class="macro">!</span>(<span class="string">&quot;read-dir&quot;</span>);
<span class="kw">let</span> <span class="ident">_dir</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">std</span>::<span class="ident">fs</span>::<span class="ident">read_dir</span>(<span class="string">&quot;.&quot;</span>).<span class="ident">unwrap</span>().<span class="ident">collect</span>();
<span class="comment">// ... do some work on the directory ...</span>
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="attribute">#[<span class="ident">should_panic</span>]</span>
<span class="kw">fn</span> <span class="ident">test_fallible_work</span>() {
<span class="ident">fail</span>::<span class="ident">setup</span>();
<span class="ident">fail</span>::<span class="ident">cfg</span>(<span class="string">&quot;read-dir&quot;</span>, <span class="string">&quot;panic&quot;</span>).<span class="ident">unwrap</span>();
<span class="ident">do_fallible_work</span>();
<span class="ident">fail</span>::<span class="ident">teardown</span>();
}</pre></div>
<p>So this is a test that sets up the fail point to panic, and the test is
expected to panic because it has the <code>#[should_panic]</code> attribute.</p>
<p>And this works fine.</p>
<p>But only in this simple case. It is not correct generally. This is because
fail points are global resources that can be accessed from any thread, and
<code>setup</code> and <code>teardown</code> are operations that have global effect, and Rust
tests are run in multiple threads, in parallel. As a result, <em>if more than
one test calls <code>setup</code>, <code>teardown</code>, or configures the same fail point then
their result is non-deterministic</em>.</p>
<p>To account for this we need to serialize the execution of tests by holding
a global lock, and only running a single fail point test at a time.</p>
<p>Here's the correct way to write this test, and the basic pattern for writing
tests with fail points:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="attribute">#[<span class="ident">macro_use</span>]</span>
<span class="kw">extern</span> <span class="kw">crate</span> <span class="ident">lazy_static</span>;
<span class="attribute">#[<span class="ident">macro_use</span>]</span>
<span class="kw">extern</span> <span class="kw">crate</span> <span class="ident">fail</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">sync</span>::{<span class="ident">Mutex</span>, <span class="ident">MutexGuard</span>};
<span class="kw">fn</span> <span class="ident">do_fallible_work</span>() {
<span class="macro">fail_point</span><span class="macro">!</span>(<span class="string">&quot;read-dir&quot;</span>);
<span class="kw">let</span> <span class="ident">_dir</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">std</span>::<span class="ident">fs</span>::<span class="ident">read_dir</span>(<span class="string">&quot;.&quot;</span>).<span class="ident">unwrap</span>().<span class="ident">collect</span>();
<span class="comment">// ... do some work on the directory ...</span>
}
<span class="macro">lazy_static</span><span class="macro">!</span> {
<span class="kw">static</span> <span class="kw-2">ref</span> <span class="ident">LOCK</span>: <span class="ident">Mutex</span><span class="op">&lt;</span>()<span class="op">&gt;</span> <span class="op">=</span> <span class="ident">Mutex</span>::<span class="ident">new</span>(());
}
<span class="kw">fn</span> <span class="ident">setup</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span><span class="op">&gt;</span>() <span class="op">-&gt;</span> <span class="ident">MutexGuard</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span>, ()<span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">guard</span> <span class="op">=</span> <span class="ident">LOCK</span>.<span class="ident">lock</span>().<span class="ident">unwrap_or_else</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> <span class="ident">e</span>.<span class="ident">into_inner</span>());
<span class="ident">fail</span>::<span class="ident">teardown</span>();
<span class="ident">fail</span>::<span class="ident">setup</span>();
<span class="ident">guard</span>
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="attribute">#[<span class="ident">should_panic</span>]</span>
<span class="kw">fn</span> <span class="ident">test_fallible_work</span>() {
<span class="kw">let</span> <span class="ident">_gaurd</span> <span class="op">=</span> <span class="ident">setup</span>();
<span class="ident">fail</span>::<span class="ident">cfg</span>(<span class="string">&quot;read-dir&quot;</span>, <span class="string">&quot;panic&quot;</span>).<span class="ident">unwrap</span>();
<span class="ident">do_fallible_work</span>();
}</pre></div>
<p>With this arrangement, any test that calls <code>setup</code> and holds the resulting
guard for the duration will not run in parallel with other tests. It depends
on the <a href="https://crates.io/crates/lazy_static"><code>lazy_static</code></a> crate to
initialize a global mutex.</p>
<p>Note that this type of guard is not only necessary for test cases that
configure fail points, but also, if there are <em>any</em> test cases that enable
fail points in the same crate, then the guard is also necessary for any
tests that execute the code containing those fail points, even if those
tests don't call <code>fail::cfg</code> themselves. In our example, consider what
happens of we have two test cases that test <code>do_fallible_work</code>, and one of
them configures the fail point, expecting the function to fail, while the
other does not configure the fail point, expecting it to succeed. Then
consider what might happen if those tests execute in parallel — the
result is not deterministic and there will be spurious test failures.</p>
<p>Because of this it is a best practice to put all fail point unit tests into
their own binary. Here's an example of a snippet from <code>Cargo.toml</code> that
creates a fail-point-specific test binary:</p>
<pre><code class="language-toml">[[test]]
name = &quot;failpoints&quot;
path = &quot;tests/failpoints/mod.rs&quot;
</code></pre>
<h2 id="early-return" class="section-header"><a href="#early-return">Early return</a></h2>
<p>The previous examples illustrate injecting panics via fail points, but
panics aren't the only — or even the most common — error pattern
in Rust. The more common type of error is propagated by <code>Result</code> return
values, and fail points can inject those as well with &quot;early returns&quot;. That
is, when configuring a fail point as &quot;return&quot; (as opposed to &quot;panic&quot;), the
fail point will immediately return from the function, optionally with a
configurable value.</p>
<p>The setup for early return requires a slightly diferent invocation of the
<code>fail_point!</code> macro. To illustrate this, let's modify the <code>do_fallible_work</code>
function we used earlier to return a <code>Result</code>:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="attribute">#[<span class="ident">macro_use</span>]</span>
<span class="kw">extern</span> <span class="kw">crate</span> <span class="ident">fail</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">io</span>;
<span class="kw">fn</span> <span class="ident">do_fallible_work</span>() <span class="op">-&gt;</span> <span class="ident">io</span>::<span class="prelude-ty">Result</span><span class="op">&lt;</span>()<span class="op">&gt;</span> {
<span class="macro">fail_point</span><span class="macro">!</span>(<span class="string">&quot;read-dir&quot;</span>);
<span class="kw">let</span> <span class="ident">_dir</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">std</span>::<span class="ident">fs</span>::<span class="ident">read_dir</span>(<span class="string">&quot;.&quot;</span>)<span class="question-mark">?</span>.<span class="ident">collect</span>();
<span class="comment">// ... do some work on the directory ...</span>
<span class="prelude-val">Ok</span>(())
}
<span class="kw">fn</span> <span class="ident">main</span>() <span class="op">-&gt;</span> <span class="ident">io</span>::<span class="prelude-ty">Result</span><span class="op">&lt;</span>()<span class="op">&gt;</span> {
<span class="ident">fail</span>::<span class="ident">setup</span>();
<span class="ident">do_fallible_work</span>()<span class="question-mark">?</span>;
<span class="ident">fail</span>::<span class="ident">teardown</span>();
<span class="macro">println</span><span class="macro">!</span>(<span class="string">&quot;done&quot;</span>);
<span class="prelude-val">Ok</span>(())
}</pre></div>
<p>So this example has more proper Rust error handling, with no unwraps
anywhere. Instead it uses <code>?</code> to propagate errors via the <code>Result</code> type
return values. This is more realistic Rust code.</p>
<p>The &quot;read-dir&quot; fail point though is not yet configured to support early
return, so if we attempt to configure it to &quot;return&quot;, we'll see an error
like</p>
<pre><code class="language-sh">$ FAILPOINTS=read-dir=return cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.13s
Running `target/debug/failpointtest`
thread 'main' panicked at 'Return is not supported for the fail point &quot;read-dir&quot;', src/main.rs:7:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
</code></pre>
<p>This error tells us that the &quot;read-dir&quot; fail point is not defined correctly
to support early return, and gives us the line number of that fail point.
What we're missing in the fail point definition is code describring <em>how</em> to
return an error value, and the way we do this is by passing <code>fail_point!</code> a
closure that returns the same type as the enclosing function.</p>
<p>Here's a variation that does so:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">fn</span> <span class="ident">do_fallible_work</span>() <span class="op">-&gt;</span> <span class="ident">io</span>::<span class="prelude-ty">Result</span><span class="op">&lt;</span>()<span class="op">&gt;</span> {
<span class="macro">fail_point</span><span class="macro">!</span>(<span class="string">&quot;read-dir&quot;</span>, <span class="op">|</span><span class="kw">_</span><span class="op">|</span> {
<span class="prelude-val">Err</span>(<span class="ident">io</span>::<span class="ident">Error</span>::<span class="ident">new</span>(<span class="ident">io</span>::<span class="ident">ErrorKind</span>::<span class="ident">PermissionDenied</span>, <span class="string">&quot;error&quot;</span>))
});
<span class="kw">let</span> <span class="ident">_dir</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">std</span>::<span class="ident">fs</span>::<span class="ident">read_dir</span>(<span class="string">&quot;.&quot;</span>)<span class="question-mark">?</span>.<span class="ident">collect</span>();
<span class="comment">// ... do some work on the directory ...</span>
<span class="prelude-val">Ok</span>(())
}</pre></div>
<p>And now if the &quot;read-dir&quot; fail point is configured to &quot;return&quot; we get a
different result:</p>
<pre><code class="language-sh">$ FAILPOINTS=read-dir=return cargo run
Compiling failpointtest v0.1.0 (/home/brian/pingcap/failpointtest)
Finished dev [unoptimized + debuginfo] target(s) in 2.38s
Running `target/debug/failpointtest`
Error: Custom { kind: PermissionDenied, error: StringError(&quot;error&quot;) }
</code></pre>
<p>This time, <code>do_fallible_work</code> returned the error defined in our closure,
which propagated all the way up and out of main, then Rust's default error
handler printed the error. All as expected.</p>
<p>There's one other thing to understand about this closure used for early
return, and that's the purpose of the argument. Notice that in the previous
example our closure accepted an argument, but only with the placeholder <code>_</code>
— it didn't do anything with it.</p>
<p>The purpose of this argument is to customize the return value dynamically:
when configuring a fail point for return, you can also provide a string
representing <em>what</em> should be returned, e.g. &quot;return(true)&quot; or
&quot;return(false)&quot;. The closure receives that string inside an <code>Option&lt;String&gt;</code>
and is responsible for converting into the proper return type.</p>
<p>So here's one final variation that accepts that string and incorporates it
into the return value:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered">
<span class="kw">fn</span> <span class="ident">do_fallible_work</span>() <span class="op">-&gt;</span> <span class="ident">io</span>::<span class="prelude-ty">Result</span><span class="op">&lt;</span>()<span class="op">&gt;</span> {
<span class="macro">fail_point</span><span class="macro">!</span>(<span class="string">&quot;read-dir&quot;</span>, <span class="op">|</span><span class="ident">err</span><span class="op">|</span> {
<span class="kw">let</span> <span class="ident">err</span> <span class="op">=</span> <span class="ident">err</span>.<span class="ident">unwrap_or</span>(<span class="string">&quot;error&quot;</span>.<span class="ident">to_string</span>());
<span class="prelude-val">Err</span>(<span class="ident">io</span>::<span class="ident">Error</span>::<span class="ident">new</span>(<span class="ident">io</span>::<span class="ident">ErrorKind</span>::<span class="ident">PermissionDenied</span>, <span class="ident">err</span>))
});
<span class="kw">let</span> <span class="ident">_dir</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">std</span>::<span class="ident">fs</span>::<span class="ident">read_dir</span>(<span class="string">&quot;.&quot;</span>)<span class="question-mark">?</span>.<span class="ident">collect</span>();
<span class="comment">// ... do some work on the directory ...</span>
<span class="prelude-val">Ok</span>(())
}</pre></div>
<p>And running it with a custom value:</p>
<pre><code class="language-sh">$ FAILPOINTS=&quot;read-dir=return(kablooey)&quot; cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.10s
Running `target/debug/failpointtest`
Error: Custom { kind: PermissionDenied, error: StringError(&quot;kablooey&quot;) }
</code></pre>
<h2 id="advanced-usage" class="section-header"><a href="#advanced-usage">Advanced usage</a></h2>
<p>That's the basics of fail points: defining them with <code>fail_point!</code>,
configuring them with <code>FAILPOINTS</code> and <code>fail::cfg</code>, and configuring them to
panic and return early. But that's not all they can do. To learn more see
the documentation for <a href="fn.cfg.html"><code>cfg</code></a> and
<a href="macro.fail_point.html"><code>fail_point!</code></a>.</p>
<h2 id="usage-considerations" class="section-header"><a href="#usage-considerations">Usage considerations</a></h2>
<p>For most effective fail point usage, keep in mind the following:</p>
<ul>
<li>Enable the <code>no_fail</code> feature in your release build. This will remove all
the code for individual fail points, though not the code for calls to
<code>setup</code> and <code>teardown</code>.</li>
<li>Carefully consider complex, concurrent, non-deterministic combinations of
fail points. Put test cases exercising fail points into their own test
crate and protect each test case with a mutex guard.</li>
<li>Use self-describing fail point names.</li>
<li>Fail points might have the same name, in which case they take the
same actions. Be careful about duplicating fail point names, either within
a single crate, or across multiple crates.</li>
</ul>
</div><h2 id='macros' class='section-header'><a href="#macros">Macros</a></h2>
<table><tr class='module-item'><td><a class="macro" href="macro.fail_point.html" title='fail::fail_point macro'>fail_point</a></td><td class='docblock-short'></td></tr></table><h2 id='functions' class='section-header'><a href="#functions">Functions</a></h2>
<table><tr class='module-item'><td><a class="fn" href="fn.cfg.html" title='fail::cfg fn'>cfg</a></td><td class='docblock-short'><p>Configure the actions for a fail point at runtime.</p>
</td></tr><tr class='module-item'><td><a class="fn" href="fn.list.html" title='fail::list fn'>list</a></td><td class='docblock-short'><p>Get all registered fail points.</p>
</td></tr><tr class='module-item'><td><a class="fn" href="fn.remove.html" title='fail::remove fn'>remove</a></td><td class='docblock-short'><p>Remove a fail point.</p>
</td></tr><tr class='module-item'><td><a class="fn" href="fn.setup.html" title='fail::setup fn'>setup</a></td><td class='docblock-short'><p>Set up the fail point system.</p>
</td></tr><tr class='module-item'><td><a class="fn" href="fn.teardown.html" title='fail::teardown fn'>teardown</a></td><td class='docblock-short'><p>Tear down the fail point system.</p>
</td></tr></table></section><section id="search" class="content hidden"></section><section class="footer"></section><aside id="help" class="hidden"><div><h1 class="hidden">Help</h1><div class="shortcuts"><h2>Keyboard Shortcuts</h2><dl><dt><kbd>?</kbd></dt><dd>Show this help dialog</dd><dt><kbd>S</kbd></dt><dd>Focus the search field</dd><dt><kbd></kbd></dt><dd>Move up in search results</dd><dt><kbd></kbd></dt><dd>Move down in search results</dd><dt><kbd></kbd></dt><dd>Switch tab</dd><dt><kbd>&#9166;</kbd></dt><dd>Go to active search result</dd><dt><kbd>+</kbd></dt><dd>Expand all sections</dd><dt><kbd>-</kbd></dt><dd>Collapse all sections</dd></dl></div><div class="infos"><h2>Search Tricks</h2><p>Prefix searches with a type followed by a colon (e.g., <code>fn:</code>) to restrict the search to a given type.</p><p>Accepted types are: <code>fn</code>, <code>mod</code>, <code>struct</code>, <code>enum</code>, <code>trait</code>, <code>type</code>, <code>macro</code>, and <code>const</code>.</p><p>Search functions by type signature (e.g., <code>vec -> usize</code> or <code>* -> vec</code>)</p><p>Search multiple things at once by splitting your query with comma (e.g., <code>str,u8</code> or <code>String,struct:Vec,test</code>)</p></div></div></aside><script>window.rootPath = "../";window.currentCrate = "fail";</script><script src="../aliases.js"></script><script src="../main.js"></script><script defer src="../search-index.js"></script></body></html>