deploy: de38ae62916547ad097c066f94a32e9ba7790eeb

This commit is contained in:
NotAShelf 2025-02-05 00:10:33 +00:00
commit 9a86359447
28502 changed files with 1261284 additions and 0 deletions

1
once_cell/all.html Normal file
View file

@ -0,0 +1 @@
<!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="List of all items in this crate"><title>List of all items in this crate</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Regular-0fe48ade.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" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-42caa33d.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="once_cell" data-themes="" data-resource-suffix="" data-rustdoc-version="1.84.1 (e71f9a9a9 2025-01-27)" data-channel="1.84.1" data-search-js="search-92e6798f.js" data-settings-js="settings-0f613d39.js" ><script src="../static.files/storage-59e33391.js"></script><script defer src="../static.files/main-5f194d8c.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod sys"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../once_cell/index.html">once_<wbr>cell</a><span class="version">1.20.2</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h3><a href="#structs">Crate Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><h1>List of all items</h1><h3 id="structs">Structs</h3><ul class="all-items"><li><a href="race/struct.OnceBool.html">race::OnceBool</a></li><li><a href="race/struct.OnceBox.html">race::OnceBox</a></li><li><a href="race/struct.OnceNonZeroUsize.html">race::OnceNonZeroUsize</a></li><li><a href="race/struct.OnceRef.html">race::OnceRef</a></li><li><a href="sync/struct.Lazy.html">sync::Lazy</a></li><li><a href="sync/struct.OnceCell.html">sync::OnceCell</a></li><li><a href="unsync/struct.Lazy.html">unsync::Lazy</a></li><li><a href="unsync/struct.OnceCell.html">unsync::OnceCell</a></li></ul></section></div></main></body></html>

288
once_cell/index.html Normal file
View file

@ -0,0 +1,288 @@
<!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="Overview"><title>once_cell - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Regular-0fe48ade.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" crossorigin href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-42caa33d.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="once_cell" data-themes="" data-resource-suffix="" data-rustdoc-version="1.84.1 (e71f9a9a9 2025-01-27)" data-channel="1.84.1" data-search-js="search-92e6798f.js" data-settings-js="settings-0f613d39.js" ><script src="../static.files/storage-59e33391.js"></script><script defer src="../crates.js"></script><script defer src="../static.files/main-5f194d8c.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod crate"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../once_cell/index.html">once_<wbr>cell</a><span class="version">1.20.2</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="#overview" title="Overview">Overview</a></li><li><a href="#recipes" title="Recipes">Recipes</a><ul><li><a href="#safe-initialization-of-global-data" title="Safe Initialization of Global Data">Safe Initialization of Global Data</a></li><li><a href="#lazy-initialized-global-data" title="Lazy Initialized Global Data">Lazy Initialized Global Data</a></li><li><a href="#general-purpose-lazy-evaluation" title="General purpose lazy evaluation">General purpose lazy evaluation</a></li><li><a href="#lazily-compiled-regex" title="Lazily Compiled Regex">Lazily Compiled Regex</a></li><li><a href="#runtime-include_bytes" title="Runtime `include_bytes!`">Runtime <code>include_bytes!</code></a></li><li><a href="#lateinit" title="`lateinit`"><code>lateinit</code></a></li></ul></li><li><a href="#comparison-with-std" title="Comparison with std">Comparison with std</a></li><li><a href="#minimum-supported-rustc-version" title="Minimum Supported `rustc` Version">Minimum Supported <code>rustc</code> Version</a></li><li><a href="#implementation-details" title="Implementation details">Implementation details</a></li><li><a href="#faq" title="F.A.Q.">F.A.Q.</a></li><li><a href="#related-crates" title="Related crates">Related crates</a></li></ul><h3><a href="#modules">Crate Items</a></h3><ul class="block"><li><a href="#modules" title="Modules">Modules</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><h1>Crate <span>once_cell</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/once_cell/lib.rs.html#1-1412">Source</a> </span></div><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><h2 id="overview"><a class="doc-anchor" href="#overview">§</a>Overview</h2>
<p><code>once_cell</code> provides two new cell-like types, <a href="unsync/struct.OnceCell.html"><code>unsync::OnceCell</code></a> and
<a href="sync/struct.OnceCell.html"><code>sync::OnceCell</code></a>. A <code>OnceCell</code> might store arbitrary non-<code>Copy</code> types, can
be assigned to at most once and provides direct access to the stored
contents. The core API looks <em>roughly</em> like this (and theres much more
inside, read on!):</p>
<div class="example-wrap ignore"><a href="#" class="tooltip" title="This example is not tested"></a><pre class="rust rust-example-rendered"><code><span class="kw">impl</span>&lt;T&gt; OnceCell&lt;T&gt; {
<span class="kw">const fn </span>new() -&gt; OnceCell&lt;T&gt; { ... }
<span class="kw">fn </span>set(<span class="kw-2">&amp;</span><span class="self">self</span>, value: T) -&gt; <span class="prelude-ty">Result</span>&lt;(), T&gt; { ... }
<span class="kw">fn </span>get(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span>T&gt; { ... }
}</code></pre></div>
<p>Note that, like with <a href="https://doc.rust-lang.org/std/cell/struct.RefCell.html"><code>RefCell</code></a> and <a href="https://doc.rust-lang.org/std/sync/struct.Mutex.html"><code>Mutex</code></a>, the <code>set</code> method requires
only a shared reference. Because of the single assignment restriction <code>get</code>
can return a <code>&amp;T</code> instead of <code>Ref&lt;T&gt;</code> or <code>MutexGuard&lt;T&gt;</code>.</p>
<p>The <code>sync</code> flavor is thread-safe (that is, implements the <a href="https://doc.rust-lang.org/std/marker/trait.Sync.html"><code>Sync</code></a> trait),
while the <code>unsync</code> one is not.</p>
<h2 id="recipes"><a class="doc-anchor" href="#recipes">§</a>Recipes</h2>
<p><code>OnceCell</code> might be useful for a variety of patterns.</p>
<h3 id="safe-initialization-of-global-data"><a class="doc-anchor" href="#safe-initialization-of-global-data">§</a>Safe Initialization of Global Data</h3>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>std::{env, io};
<span class="kw">use </span>once_cell::sync::OnceCell;
<span class="attr">#[derive(Debug)]
</span><span class="kw">pub struct </span>Logger {
<span class="comment">// ...
</span>}
<span class="kw">static </span>INSTANCE: OnceCell&lt;Logger&gt; = OnceCell::new();
<span class="kw">impl </span>Logger {
<span class="kw">pub fn </span>global() -&gt; <span class="kw-2">&amp;</span><span class="lifetime">'static </span>Logger {
INSTANCE.get().expect(<span class="string">"logger is not initialized"</span>)
}
<span class="kw">fn </span>from_cli(args: env::Args) -&gt; <span class="prelude-ty">Result</span>&lt;Logger, std::io::Error&gt; {
<span class="comment">// ...
</span>}
}
<span class="kw">fn </span>main() {
<span class="kw">let </span>logger = Logger::from_cli(env::args()).unwrap();
INSTANCE.set(logger).unwrap();
<span class="comment">// use `Logger::global()` from now on
</span>}</code></pre></div>
<h3 id="lazy-initialized-global-data"><a class="doc-anchor" href="#lazy-initialized-global-data">§</a>Lazy Initialized Global Data</h3>
<p>This is essentially the <code>lazy_static!</code> macro, but without a macro.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>std::{sync::Mutex, collections::HashMap};
<span class="kw">use </span>once_cell::sync::OnceCell;
<span class="kw">fn </span>global_data() -&gt; <span class="kw-2">&amp;</span><span class="lifetime">'static </span>Mutex&lt;HashMap&lt;i32, String&gt;&gt; {
<span class="kw">static </span>INSTANCE: OnceCell&lt;Mutex&lt;HashMap&lt;i32, String&gt;&gt;&gt; = OnceCell::new();
INSTANCE.get_or_init(|| {
<span class="kw">let </span><span class="kw-2">mut </span>m = HashMap::new();
m.insert(<span class="number">13</span>, <span class="string">"Spica"</span>.to_string());
m.insert(<span class="number">74</span>, <span class="string">"Hoyten"</span>.to_string());
Mutex::new(m)
})
}</code></pre></div>
<p>There are also the <a href="sync/struct.Lazy.html"><code>sync::Lazy</code></a> and <a href="unsync/struct.Lazy.html"><code>unsync::Lazy</code></a> convenience types to
streamline this pattern:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>std::{sync::Mutex, collections::HashMap};
<span class="kw">use </span>once_cell::sync::Lazy;
<span class="kw">static </span>GLOBAL_DATA: Lazy&lt;Mutex&lt;HashMap&lt;i32, String&gt;&gt;&gt; = Lazy::new(|| {
<span class="kw">let </span><span class="kw-2">mut </span>m = HashMap::new();
m.insert(<span class="number">13</span>, <span class="string">"Spica"</span>.to_string());
m.insert(<span class="number">74</span>, <span class="string">"Hoyten"</span>.to_string());
Mutex::new(m)
});
<span class="kw">fn </span>main() {
<span class="macro">println!</span>(<span class="string">"{:?}"</span>, GLOBAL_DATA.lock().unwrap());
}</code></pre></div>
<p>Note that the variable that holds <code>Lazy</code> is declared as <code>static</code>, <em>not</em>
<code>const</code>. This is important: using <code>const</code> instead compiles, but works wrong.</p>
<h3 id="general-purpose-lazy-evaluation"><a class="doc-anchor" href="#general-purpose-lazy-evaluation">§</a>General purpose lazy evaluation</h3>
<p>Unlike <code>lazy_static!</code>, <code>Lazy</code> works with local variables.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>once_cell::unsync::Lazy;
<span class="kw">fn </span>main() {
<span class="kw">let </span>ctx = <span class="macro">vec!</span>[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>];
<span class="kw">let </span>thunk = Lazy::new(|| {
ctx.iter().sum::&lt;i32&gt;()
});
<span class="macro">assert_eq!</span>(<span class="kw-2">*</span>thunk, <span class="number">6</span>);
}</code></pre></div>
<p>If you need a lazy field in a struct, you probably should use <code>OnceCell</code>
directly, because that will allow you to access <code>self</code> during
initialization.</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>std::{fs, path::PathBuf};
<span class="kw">use </span>once_cell::unsync::OnceCell;
<span class="kw">struct </span>Ctx {
config_path: PathBuf,
config: OnceCell&lt;String&gt;,
}
<span class="kw">impl </span>Ctx {
<span class="kw">pub fn </span>get_config(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="kw-2">&amp;</span>str, std::io::Error&gt; {
<span class="kw">let </span>cfg = <span class="self">self</span>.config.get_or_try_init(|| {
fs::read_to_string(<span class="kw-2">&amp;</span><span class="self">self</span>.config_path)
})<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(cfg.as_str())
}
}</code></pre></div>
<h3 id="lazily-compiled-regex"><a class="doc-anchor" href="#lazily-compiled-regex">§</a>Lazily Compiled Regex</h3>
<p>This is a <code>regex!</code> macro which takes a string literal and returns an
<em>expression</em> that evaluates to a <code>&amp;'static Regex</code>:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="macro">macro_rules!</span> regex {
(<span class="macro-nonterminal">$re</span>:literal $(,)<span class="question-mark">?</span>) =&gt; {{
<span class="kw">static </span>RE: once_cell::sync::OnceCell&lt;regex::Regex&gt; = once_cell::sync::OnceCell::new();
RE.get_or_init(|| regex::Regex::new(<span class="macro-nonterminal">$re</span>).unwrap())
}};
}</code></pre></div>
<p>This macro can be useful to avoid the “compile regex on every loop
iteration” problem.</p>
<h3 id="runtime-include_bytes"><a class="doc-anchor" href="#runtime-include_bytes">§</a>Runtime <code>include_bytes!</code></h3>
<p>The <code>include_bytes</code> macro is useful to include test resources, but it slows
down test compilation a lot. An alternative is to load the resources at
runtime:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>std::path::Path;
<span class="kw">use </span>once_cell::sync::OnceCell;
<span class="kw">pub struct </span>TestResource {
path: <span class="kw-2">&amp;</span><span class="lifetime">'static </span>str,
cell: OnceCell&lt;Vec&lt;u8&gt;&gt;,
}
<span class="kw">impl </span>TestResource {
<span class="kw">pub const fn </span>new(path: <span class="kw-2">&amp;</span><span class="lifetime">'static </span>str) -&gt; TestResource {
TestResource { path, cell: OnceCell::new() }
}
<span class="kw">pub fn </span>bytes(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>[u8] {
<span class="self">self</span>.cell.get_or_init(|| {
<span class="kw">let </span>dir = std::env::var(<span class="string">"CARGO_MANIFEST_DIR"</span>).unwrap();
<span class="kw">let </span>path = Path::new(dir.as_str()).join(<span class="self">self</span>.path);
std::fs::read(<span class="kw-2">&amp;</span>path).unwrap_or_else(|_err| {
<span class="macro">panic!</span>(<span class="string">"failed to load test resource: {}"</span>, path.display())
})
}).as_slice()
}
}
<span class="kw">static </span>TEST_IMAGE: TestResource = TestResource::new(<span class="string">"test_data/lena.png"</span>);
<span class="attr">#[test]
</span><span class="kw">fn </span>test_sobel_filter() {
<span class="kw">let </span>rgb: <span class="kw-2">&amp;</span>[u8] = TEST_IMAGE.bytes();
<span class="comment">// ...
</span>}</code></pre></div>
<h3 id="lateinit"><a class="doc-anchor" href="#lateinit">§</a><code>lateinit</code></h3>
<p><code>LateInit</code> type for delayed initialization. It is reminiscent of Kotlins
<code>lateinit</code> keyword and allows construction of cyclic data structures:</p>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>once_cell::sync::OnceCell;
<span class="kw">pub struct </span>LateInit&lt;T&gt; { cell: OnceCell&lt;T&gt; }
<span class="kw">impl</span>&lt;T&gt; LateInit&lt;T&gt; {
<span class="kw">pub fn </span>init(<span class="kw-2">&amp;</span><span class="self">self</span>, value: T) {
<span class="macro">assert!</span>(<span class="self">self</span>.cell.set(value).is_ok())
}
}
<span class="kw">impl</span>&lt;T&gt; Default <span class="kw">for </span>LateInit&lt;T&gt; {
<span class="kw">fn </span>default() -&gt; <span class="self">Self </span>{ LateInit { cell: OnceCell::default() } }
}
<span class="kw">impl</span>&lt;T&gt; std::ops::Deref <span class="kw">for </span>LateInit&lt;T&gt; {
<span class="kw">type </span>Target = T;
<span class="kw">fn </span>deref(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>T {
<span class="self">self</span>.cell.get().unwrap()
}
}
<span class="attr">#[derive(Default)]
</span><span class="kw">struct </span>A&lt;<span class="lifetime">'a</span>&gt; {
b: LateInit&lt;<span class="kw-2">&amp;</span><span class="lifetime">'a </span>B&lt;<span class="lifetime">'a</span>&gt;&gt;,
}
<span class="attr">#[derive(Default)]
</span><span class="kw">struct </span>B&lt;<span class="lifetime">'a</span>&gt; {
a: LateInit&lt;<span class="kw-2">&amp;</span><span class="lifetime">'a </span>A&lt;<span class="lifetime">'a</span>&gt;&gt;
}
<span class="kw">fn </span>build_cycle() {
<span class="kw">let </span>a = A::default();
<span class="kw">let </span>b = B::default();
a.b.init(<span class="kw-2">&amp;</span>b);
b.a.init(<span class="kw-2">&amp;</span>a);
<span class="kw">let </span>_a = <span class="kw-2">&amp;</span>a.b.a.b.a;
}</code></pre></div>
<h2 id="comparison-with-std"><a class="doc-anchor" href="#comparison-with-std">§</a>Comparison with std</h2><div><table><thead><tr><th><code>!Sync</code> types</th><th>Access Mode</th><th>Drawbacks</th></tr></thead><tbody>
<tr><td><code>Cell&lt;T&gt;</code></td><td><code>T</code></td><td>requires <code>T: Copy</code> for <code>get</code></td></tr>
<tr><td><code>RefCell&lt;T&gt;</code></td><td><code>RefMut&lt;T&gt;</code> / <code>Ref&lt;T&gt;</code></td><td>may panic at runtime</td></tr>
<tr><td><code>unsync::OnceCell&lt;T&gt;</code></td><td><code>&amp;T</code></td><td>assignable only once</td></tr>
</tbody></table>
</div><div><table><thead><tr><th><code>Sync</code> types</th><th>Access Mode</th><th>Drawbacks</th></tr></thead><tbody>
<tr><td><code>AtomicT</code></td><td><code>T</code></td><td>works only with certain <code>Copy</code> types</td></tr>
<tr><td><code>Mutex&lt;T&gt;</code></td><td><code>MutexGuard&lt;T&gt;</code></td><td>may deadlock at runtime, may block the thread</td></tr>
<tr><td><code>sync::OnceCell&lt;T&gt;</code></td><td><code>&amp;T</code></td><td>assignable only once, may block the thread</td></tr>
</tbody></table>
</div>
<p>Technically, calling <code>get_or_init</code> will also cause a panic or a deadlock if
it recursively calls itself. However, because the assignment can happen only
once, such cases should be more rare than equivalents with <code>RefCell</code> and
<code>Mutex</code>.</p>
<h2 id="minimum-supported-rustc-version"><a class="doc-anchor" href="#minimum-supported-rustc-version">§</a>Minimum Supported <code>rustc</code> Version</h2>
<p>If only the <code>std</code>, <code>alloc</code>, or <code>race</code> features are enabled, MSRV will be
updated conservatively, supporting at least latest 8 versions of the compiler.
When using other features, like <code>parking_lot</code>, MSRV might be updated more
frequently, up to the latest stable. In both cases, increasing MSRV is <em>not</em>
considered a semver-breaking change and requires only a minor version bump.</p>
<h2 id="implementation-details"><a class="doc-anchor" href="#implementation-details">§</a>Implementation details</h2>
<p>The implementation is based on the
<a href="https://github.com/rust-lang-nursery/lazy-static.rs/"><code>lazy_static</code></a> and
<a href="https://github.com/indiv0/lazycell/"><code>lazy_cell</code></a> crates and
<a href="https://doc.rust-lang.org/std/sync/struct.Once.html"><code>std::sync::Once</code></a>. In some sense, <code>once_cell</code> just streamlines and unifies
those APIs.</p>
<p>To implement a sync flavor of <code>OnceCell</code>, this crates uses either a custom
re-implementation of <code>std::sync::Once</code> or <code>parking_lot::Mutex</code>. This is
controlled by the <code>parking_lot</code> feature (disabled by default). Performance
is the same for both cases, but the <code>parking_lot</code> based <code>OnceCell&lt;T&gt;</code> is
smaller by up to 16 bytes.</p>
<p>This crate uses <code>unsafe</code>.</p>
<h2 id="faq"><a class="doc-anchor" href="#faq">§</a>F.A.Q.</h2>
<p><strong>Should I use the sync or unsync flavor?</strong></p>
<p>Because Rust compiler checks thread safety for you, its impossible to
accidentally use <code>unsync</code> where <code>sync</code> is required. So, use <code>unsync</code> in
single-threaded code and <code>sync</code> in multi-threaded. Its easy to switch
between the two if code becomes multi-threaded later.</p>
<p>At the moment, <code>unsync</code> has an additional benefit that reentrant
initialization causes a panic, which might be easier to debug than a
deadlock.</p>
<p><strong>Does this crate support async?</strong></p>
<p>No, but you can use
<a href="https://crates.io/crates/async_once_cell"><code>async_once_cell</code></a> instead.</p>
<p><strong>Does this crate support <code>no_std</code>?</strong></p>
<p>Yes, but with caveats. <code>OnceCell</code> is a synchronization primitive which
<em>semantically</em> relies on blocking. <code>OnceCell</code> guarantees that at most one
<code>f</code> will be called to compute the value. If two threads of execution call
<code>get_or_init</code> concurrently, one of them has to wait.</p>
<p>Waiting fundamentally requires OS support. Execution environment needs to
understand who waits on whom to prevent deadlocks due to priority inversion.
You <em>could</em> make code to compile by blindly using pure spinlocks, but the
runtime behavior would be subtly wrong.</p>
<p>Given these constraints, <code>once_cell</code> provides the following options:</p>
<ul>
<li>The <code>race</code> module provides similar, but distinct synchronization primitive
which is compatible with <code>no_std</code>. With <code>race</code>, the <code>f</code> function can be
called multiple times by different threads, but only one thread will win
to install the value.</li>
<li><code>critical-section</code> feature (with a <code>-</code>, not <code>_</code>) uses <code>critical_section</code>
to implement blocking.</li>
</ul>
<p><strong>Can I bring my own mutex?</strong></p>
<p>There is <a href="https://crates.io/crates/generic_once_cell">generic_once_cell</a> to
allow just that.</p>
<p><strong>Should I use <code>std::cell::OnceCell</code>, <code>once_cell</code>, or <code>lazy_static</code>?</strong></p>
<p>If you can use <code>std</code> version (your MSRV is at least 1.70, and you dont need
extra features <code>once_cell</code> provides), use <code>std</code>. Otherwise, use <code>once_cell</code>.
Dont use <code>lazy_static</code>.</p>
<h2 id="related-crates"><a class="doc-anchor" href="#related-crates">§</a>Related crates</h2>
<ul>
<li>Most of this crates functionality is available in <code>std</code> starting with
Rust 1.70. See <code>std::cell::OnceCell</code> and <code>std::sync::OnceLock</code>.</li>
<li><a href="https://github.com/niklasf/double-checked-cell">double-checked-cell</a></li>
<li><a href="https://crates.io/crates/lazy-init">lazy-init</a></li>
<li><a href="https://crates.io/crates/lazycell">lazycell</a></li>
<li><a href="https://crates.io/crates/mitochondria">mitochondria</a></li>
<li><a href="https://crates.io/crates/lazy_static">lazy_static</a></li>
<li><a href="https://crates.io/crates/async_once_cell">async_once_cell</a></li>
<li><a href="https://crates.io/crates/generic_once_cell">generic_once_cell</a> (bring
your own mutex)</li>
</ul>
</div></details><h2 id="modules" class="section-header">Modules<a href="#modules" class="anchor">§</a></h2><ul class="item-table"><li><div class="item-name"><a class="mod" href="race/index.html" title="mod once_cell::race">race</a></div><div class="desc docblock-short">Thread-safe, non-blocking, “first one wins” flavor of <code>OnceCell</code>.</div></li><li><div class="item-name"><a class="mod" href="sync/index.html" title="mod once_cell::sync">sync</a></div><div class="desc docblock-short">Thread-safe, blocking version of <code>OnceCell</code>.</div></li><li><div class="item-name"><a class="mod" href="unsync/index.html" title="mod once_cell::unsync">unsync</a></div><div class="desc docblock-short">Single-threaded version of <code>OnceCell</code>.</div></li></ul></section></div></main></body></html>

17
once_cell/race/index.html Normal file
View file

@ -0,0 +1,17 @@
<!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="Thread-safe, non-blocking, “first one wins” flavor of `OnceCell`."><title>once_cell::race - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Regular-0fe48ade.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" crossorigin href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-42caa33d.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="once_cell" data-themes="" data-resource-suffix="" data-rustdoc-version="1.84.1 (e71f9a9a9 2025-01-27)" data-channel="1.84.1" data-search-js="search-92e6798f.js" data-settings-js="settings-0f613d39.js" ><script src="../../static.files/storage-59e33391.js"></script><script defer src="../sidebar-items.js"></script><script defer src="../../static.files/main-5f194d8c.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc mod"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../../once_cell/index.html">once_<wbr>cell</a><span class="version">1.20.2</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">Module race</a></h2><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#atomic-orderings" title="Atomic orderings">Atomic orderings</a></li></ul><h3><a href="#structs">Module Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="../index.html">In crate once_<wbr>cell</a></h2></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><span class="rustdoc-breadcrumbs"><a href="../index.html">once_cell</a></span><h1>Module <span>race</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../../src/once_cell/race.rs.html#1-419">Source</a> </span></div><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Thread-safe, non-blocking, “first one wins” flavor of <code>OnceCell</code>.</p>
<p>If two threads race to initialize a type from the <code>race</code> module, they
dont block, execute initialization function together, but only one of
them stores the result.</p>
<p>This module does not require <code>std</code> feature.</p>
<h2 id="atomic-orderings"><a class="doc-anchor" href="#atomic-orderings">§</a>Atomic orderings</h2>
<p>All types in this module use <code>Acquire</code> and <code>Release</code>
<a href="https://doc.rust-lang.org/1.84.1/core/sync/atomic/enum.Ordering.html" title="enum core::sync::atomic::Ordering">atomic orderings</a> for all their operations. While this is not
strictly necessary for types other than <code>OnceBox</code>, it is useful for users as
it allows them to be certain that after <code>get</code> or <code>get_or_init</code> returns on
one thread, any side-effects caused by the setter thread prior to them
calling <code>set</code> or <code>get_or_init</code> will be made visible to that thread; without
it, its possible for it to appear as if they havent happened yet from the
getter threads perspective. This is an acceptable tradeoff to make since
<code>Acquire</code> and <code>Release</code> have very little performance overhead on most
architectures versus <code>Relaxed</code>.</p>
</div></details><h2 id="structs" class="section-header">Structs<a href="#structs" class="anchor">§</a></h2><ul class="item-table"><li><div class="item-name"><a class="struct" href="struct.OnceBool.html" title="struct once_cell::race::OnceBool">Once<wbr>Bool</a></div><div class="desc docblock-short">A thread-safe cell which can be written to only once.</div></li><li><div class="item-name"><a class="struct" href="struct.OnceBox.html" title="struct once_cell::race::OnceBox">OnceBox</a></div><div class="desc docblock-short">A thread-safe cell which can be written to only once.</div></li><li><div class="item-name"><a class="struct" href="struct.OnceNonZeroUsize.html" title="struct once_cell::race::OnceNonZeroUsize">Once<wbr>NonZero<wbr>Usize</a></div><div class="desc docblock-short">A thread-safe cell which can be written to only once.</div></li><li><div class="item-name"><a class="struct" href="struct.OnceRef.html" title="struct once_cell::race::OnceRef">OnceRef</a></div><div class="desc docblock-short">A thread-safe cell which can be written to only once.</div></li></ul></section></div></main></body></html>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="0;URL=../../../once_cell/race/struct.OnceBox.html">
<title>Redirection</title>
</head>
<body>
<p>Redirecting to <a href="../../../once_cell/race/struct.OnceBox.html">../../../once_cell/race/struct.OnceBox.html</a>...</p>
<script>location.replace("../../../once_cell/race/struct.OnceBox.html" + location.search + location.hash);</script>
</body>
</html>

View file

@ -0,0 +1 @@
window.SIDEBAR_ITEMS = {"struct":["OnceBool","OnceBox","OnceNonZeroUsize","OnceRef"]};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
window.SIDEBAR_ITEMS = {"mod":["race","sync","unsync"]};

View file

@ -0,0 +1,2 @@
<!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="Thread-safe, blocking version of `OnceCell`."><title>once_cell::sync - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Regular-0fe48ade.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" crossorigin href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-42caa33d.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="once_cell" data-themes="" data-resource-suffix="" data-rustdoc-version="1.84.1 (e71f9a9a9 2025-01-27)" data-channel="1.84.1" data-search-js="search-92e6798f.js" data-settings-js="settings-0f613d39.js" ><script src="../../static.files/storage-59e33391.js"></script><script defer src="../sidebar-items.js"></script><script defer src="../../static.files/main-5f194d8c.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc mod"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../../once_cell/index.html">once_<wbr>cell</a><span class="version">1.20.2</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">Module sync</a></h2><h3><a href="#structs">Module Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="../index.html">In crate once_<wbr>cell</a></h2></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><span class="rustdoc-breadcrumbs"><a href="../index.html">once_cell</a></span><h1>Module <span>sync</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../../src/once_cell/lib.rs.html#863">Source</a> </span></div><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Thread-safe, blocking version of <code>OnceCell</code>.</p>
</div></details><h2 id="structs" class="section-header">Structs<a href="#structs" class="anchor">§</a></h2><ul class="item-table"><li><div class="item-name"><a class="struct" href="struct.Lazy.html" title="struct once_cell::sync::Lazy">Lazy</a></div><div class="desc docblock-short">A value which is initialized on the first access.</div></li><li><div class="item-name"><a class="struct" href="struct.OnceCell.html" title="struct once_cell::sync::OnceCell">Once<wbr>Cell</a></div><div class="desc docblock-short">A thread-safe cell which can be written to only once.</div></li></ul></section></div></main></body></html>

View file

@ -0,0 +1 @@
window.SIDEBAR_ITEMS = {"struct":["Lazy","OnceCell"]};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,2 @@
<!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="Single-threaded version of `OnceCell`."><title>once_cell::unsync - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Regular-0fe48ade.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" crossorigin href="../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../static.files/rustdoc-42caa33d.css"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="once_cell" data-themes="" data-resource-suffix="" data-rustdoc-version="1.84.1 (e71f9a9a9 2025-01-27)" data-channel="1.84.1" data-search-js="search-92e6798f.js" data-settings-js="settings-0f613d39.js" ><script src="../../static.files/storage-59e33391.js"></script><script defer src="../sidebar-items.js"></script><script defer src="../../static.files/main-5f194d8c.js"></script><noscript><link rel="stylesheet" href="../../static.files/noscript-893ab5e7.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-6580c154.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-044be391.svg"></head><body class="rustdoc mod"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle" title="show sidebar"></button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../../once_cell/index.html">once_<wbr>cell</a><span class="version">1.20.2</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">Module unsync</a></h2><h3><a href="#structs">Module Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="../index.html">In crate once_<wbr>cell</a></h2></div></div></nav><div class="sidebar-resizer"></div><main><div class="width-limiter"><rustdoc-search></rustdoc-search><section id="main-content" class="content"><div class="main-heading"><span class="rustdoc-breadcrumbs"><a href="../index.html">once_cell</a></span><h1>Module <span>unsync</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../../src/once_cell/lib.rs.html#383">Source</a> </span></div><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Single-threaded version of <code>OnceCell</code>.</p>
</div></details><h2 id="structs" class="section-header">Structs<a href="#structs" class="anchor">§</a></h2><ul class="item-table"><li><div class="item-name"><a class="struct" href="struct.Lazy.html" title="struct once_cell::unsync::Lazy">Lazy</a></div><div class="desc docblock-short">A value which is initialized on the first access.</div></li><li><div class="item-name"><a class="struct" href="struct.OnceCell.html" title="struct once_cell::unsync::OnceCell">Once<wbr>Cell</a></div><div class="desc docblock-short">A cell which can be written to only once. It is not thread safe.</div></li></ul></section></div></main></body></html>

View file

@ -0,0 +1 @@
window.SIDEBAR_ITEMS = {"struct":["Lazy","OnceCell"]};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long