Files
phy/self_cell/macro.self_cell.html
Orion Kindel 0ce894e6b0 doc
2025-03-18 10:30:23 -05:00

145 lines
14 KiB
HTML
Raw Permalink 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="This macro declares a new struct of `$StructName` and implements traits based on `$AutomaticDerive`."><title>self_cell in self_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="self_cell" data-themes="" data-resource-suffix="" data-rustdoc-version="1.84.0 (9fc6b4312 2025-01-07)" data-channel="1.84.0" 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 macro"><!--[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="../self_cell/index.html">self_<wbr>cell</a><span class="version">1.1.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">self_<wbr>cell</a></h2><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#example" title="Example:">Example:</a></li><li><a href="#generated-api" title="Generated API:">Generated API:</a></li><li><a href="#parameters" title="Parameters:">Parameters:</a></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="index.html">In crate self_<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">self_cell</a></span><h1>Macro <span class="macro">self_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/self_cell/lib.rs.html#320-577">Source</a> </span></div><pre class="rust item-decl"><code>macro_rules! self_cell {
(
$(#[$StructMeta:meta])*
$Vis:vis struct $StructName:ident $(&lt;$OwnerLifetime:lifetime&gt;)? {
owner: $Owner:ty,
#[$Covariance:ident]
dependent: $Dependent:ident,
}
$(impl {$($AutomaticDerive:ident),*})?
) =&gt; { ... };
}</code></pre><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>This macro declares a new struct of <code>$StructName</code> and implements traits
based on <code>$AutomaticDerive</code>.</p>
<h4 id="example"><a class="doc-anchor" href="#example">§</a>Example:</h4>
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>self_cell::self_cell;
<span class="attr">#[derive(Debug, Eq, PartialEq)]
</span><span class="kw">struct </span>Ast&lt;<span class="lifetime">'a</span>&gt;(Vec&lt;<span class="kw-2">&amp;</span><span class="lifetime">'a </span>str&gt;);
<span class="macro">self_cell!</span>(
<span class="attr">#[doc(hidden)]
</span><span class="kw">struct </span>PackedAstCell {
owner: String,
<span class="attr">#[covariant]
</span>dependent: Ast,
}
<span class="kw">impl </span>{Debug, PartialEq, Eq, Hash}
);</code></pre></div>
<p>See the crate overview to get a get an overview and a motivating example.</p>
<h4 id="generated-api"><a class="doc-anchor" href="#generated-api">§</a>Generated API:</h4>
<p>The macro implements these constructors:</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">fn </span>new(
owner: <span class="macro-nonterminal">$Owner</span>,
dependent_builder: <span class="kw">impl for</span>&lt;<span class="lifetime">'a</span>&gt; ::core::ops::FnOnce(<span class="kw-2">&amp;</span><span class="lifetime">'a </span><span class="macro-nonterminal">$Owner</span>) -&gt; <span class="macro-nonterminal">$Dependent</span>&lt;<span class="lifetime">'a</span>&gt;
) -&gt; <span class="self">Self</span></code></pre></div>
<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">fn </span>try_new&lt;<span class="prelude-val">Err</span>&gt;(
owner: <span class="macro-nonterminal">$Owner</span>,
dependent_builder: <span class="kw">impl for</span>&lt;<span class="lifetime">'a</span>&gt; ::core::ops::FnOnce(<span class="kw-2">&amp;</span><span class="lifetime">'a </span><span class="macro-nonterminal">$Owner</span>) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="macro-nonterminal">$Dependent</span>&lt;<span class="lifetime">'a</span>&gt;, <span class="prelude-val">Err</span>&gt;
) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="self">Self</span>, <span class="prelude-val">Err</span>&gt;</code></pre></div>
<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">fn </span>try_new_or_recover&lt;<span class="prelude-val">Err</span>&gt;(
owner: <span class="macro-nonterminal">$Owner</span>,
dependent_builder: <span class="kw">impl for</span>&lt;<span class="lifetime">'a</span>&gt; ::core::ops::FnOnce(<span class="kw-2">&amp;</span><span class="lifetime">'a </span><span class="macro-nonterminal">$Owner</span>) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="macro-nonterminal">$Dependent</span>&lt;<span class="lifetime">'a</span>&gt;, <span class="prelude-val">Err</span>&gt;
) -&gt; <span class="prelude-ty">Result</span>&lt;<span class="self">Self</span>, (<span class="macro-nonterminal">$Owner</span>, <span class="prelude-val">Err</span>)&gt;</code></pre></div>
<p>The macro implements these methods:</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">fn </span>borrow_owner&lt;<span class="lifetime">'a</span>&gt;(<span class="kw-2">&amp;</span><span class="lifetime">'a </span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span><span class="lifetime">'a </span><span class="macro-nonterminal">$Owner</span></code></pre></div>
<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="comment">// Only available if dependent is covariant.
</span><span class="kw">fn </span>borrow_dependent&lt;<span class="lifetime">'a</span>&gt;(<span class="kw-2">&amp;</span><span class="lifetime">'a </span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span><span class="lifetime">'a </span><span class="macro-nonterminal">$Dependent</span>&lt;<span class="lifetime">'a</span>&gt;</code></pre></div>
<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">fn </span>with_dependent&lt;<span class="lifetime">'outer_fn</span>, Ret&gt;(
<span class="kw-2">&amp;</span><span class="lifetime">'outer_fn </span><span class="self">self</span>,
func: <span class="kw">impl for</span>&lt;<span class="lifetime">'a</span>&gt; ::core::ops::FnOnce(<span class="kw-2">&amp;</span><span class="lifetime">'a </span><span class="macro-nonterminal">$Owner</span>, <span class="kw-2">&amp;</span><span class="lifetime">'outer_fn </span><span class="macro-nonterminal">$Dependent</span>&lt;<span class="lifetime">'a</span>&gt;
) -&gt; Ret) -&gt; Ret</code></pre></div>
<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">fn </span>with_dependent_mut&lt;<span class="lifetime">'outer_fn</span>, Ret&gt;(
<span class="kw-2">&amp;</span><span class="lifetime">'outer_fn </span><span class="kw-2">mut </span><span class="self">self</span>,
func: <span class="kw">impl for</span>&lt;<span class="lifetime">'a</span>&gt; ::core::ops::FnOnce(<span class="kw-2">&amp;</span><span class="lifetime">'a </span><span class="macro-nonterminal">$Owner</span>, <span class="kw-2">&amp;</span><span class="lifetime">'outer_fn </span><span class="kw-2">mut </span><span class="macro-nonterminal">$Dependent</span>&lt;<span class="lifetime">'a</span>&gt;) -&gt; Ret
) -&gt; Ret</code></pre></div>
<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">fn </span>into_owner(<span class="self">self</span>) -&gt; <span class="macro-nonterminal">$Owner</span></code></pre></div>
<h4 id="parameters"><a class="doc-anchor" href="#parameters">§</a>Parameters:</h4>
<ul>
<li>
<p><code>$Vis:vis struct $StructName:ident</code> Name of the struct that will be
declared, this needs to be unique for the relevant scope. Example: <code>struct AstCell</code> or <code>pub struct AstCell</code>. <code>$Vis</code> can be used to mark the struct
and all functions implemented by the macro as public.</p>
<p><code>$(#[$StructMeta:meta])*</code> allows you specify further meta items for this
struct, eg. <code>#[doc(hidden)] struct AstCell</code>.</p>
</li>
<li>
<p><code>$Owner:ty</code> Type of owner. This has to have a <code>'static</code> lifetime. Example:
<code>String</code>.</p>
</li>
<li>
<p><code>$Dependent:ident</code> Name of the dependent type without specified lifetime.
This cant be a nested type name. As workaround either create a type alias
<code>type Dep&lt;'a&gt; = Option&lt;Vec&lt;&amp;'a str&gt;&gt;;</code> or create a new-type <code>struct Dep&lt;'a&gt;(Option&lt;Vec&lt;&amp;'a str&gt;&gt;);</code>. Example: <code>Ast</code>.</p>
<p><code>$Covariance:ident</code> Marker declaring if <code>$Dependent</code> is
<a href="https://doc.rust-lang.org/nightly/nomicon/subtyping.html">covariant</a>.
Possible Values:</p>
<ul>
<li>
<p><strong>covariant</strong>: This generates the direct reference accessor function
<code>borrow_dependent</code>. This is only safe to do if this compiles <code>fn _assert_covariance&lt;'x: 'y, 'y&gt;(x: &amp;'y $Dependent&lt;'x&gt;) -&gt; &amp;'y $Dependent&lt;'y&gt; {x}</code>. Otherwise you could choose a lifetime that is too short for types
with interior mutability like <code>Cell</code>, which can lead to UB in safe code.
Which would violate the promise of this library that it is safe-to-use.
If you accidentally mark a type that is not covariant as covariant, you
will get a compile time error.</p>
</li>
<li>
<p><strong>not_covariant</strong>: This generates no additional code but you can use the
<code>with_dependent</code> function. See <a href="https://github.com/Voultapher/self_cell/tree/main/examples/lazy_ast">How to build a lazy AST with
self_cell</a>
for a usage example.</p>
</li>
</ul>
<p>In both cases you can use the <code>with_dependent_mut</code> function to mutate the
dependent value. This is safe to do because notionally you are replacing
pointers to a value not the other way around.</p>
</li>
<li>
<p><code>impl {$($AutomaticDerive:ident),*},</code> Optional comma separated list of
optional automatic trait implementations. Possible Values:</p>
<ul>
<li>
<p><strong>Debug</strong>: Prints the debug representation of owner and dependent.
Example: <code>AstCell { owner: "fox = cat + dog", dependent: Ast(["fox", "cat", "dog"]) }</code></p>
</li>
<li>
<p><strong>PartialEq</strong>: Logic <code>*self.borrow_owner() == *other.borrow_owner()</code>,
this assumes that <code>Dependent&lt;'a&gt;::From&lt;&amp;'a Owner&gt;</code> is deterministic, so
that only comparing owner is enough.</p>
</li>
<li>
<p><strong>Eq</strong>: Will implement the trait marker <code>Eq</code> for <code>$StructName</code>. Beware
if you select this <code>Eq</code> will be implemented regardless if <code>$Owner</code>
implements <code>Eq</code>, thats an unfortunate technical limitation.</p>
</li>
<li>
<p><strong>Hash</strong>: Logic <code>self.borrow_owner().hash(state);</code>, this assumes that
<code>Dependent&lt;'a&gt;::From&lt;&amp;'a Owner&gt;</code> is deterministic, so that only hashing
owner is enough.</p>
</li>
</ul>
<p>All <code>AutomaticDerive</code> are optional and you can implement you own version
of these traits. The declared struct is part of your module and you are
free to implement any trait in any way you want. Access to the unsafe
internals is only possible via unsafe functions, so you cant accidentally
use them in safe code.</p>
<p>There is limited nested cell support. Eg, having an owner with non static
references. Eg <code>struct ChildCell&lt;'a&gt; { owner: &amp;'a String, ...</code>. You can
use any lifetime name you want, except <code>_q</code> and only a single lifetime is
supported, and can only be used in the owner. Due to macro_rules
limitations, no <code>AutomaticDerive</code> are supported if an owner lifetime is
provided.</p>
</li>
</ul>
</div></details></section></div></main></body></html>