190 lines
14 KiB
HTML
190 lines
14 KiB
HTML
<!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="What `#[derive(AsRef)]` generates"><title>AsRef in derive_more_impl - 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="derive_more_impl" 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 derive"><!--[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="../derive_more_impl/index.html">derive_<wbr>more_<wbr>impl</a><span class="version">1.0.0</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">AsRef</a></h2><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#what-deriveasref-generates" title="What `#[derive(AsRef)]` generates">What <code>#[derive(AsRef)]</code> generates</a><ul><li><a href="#newtypes-and-structs-with-one-field" title="Newtypes and Structs with One Field">Newtypes and Structs with One Field</a></li><li><a href="#structs-with-multiple-fields" title="Structs with Multiple Fields">Structs with Multiple Fields</a></li><li><a href="#enums" title="Enums">Enums</a></li></ul></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="index.html">In crate derive_<wbr>more_<wbr>impl</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">derive_more_impl</a></span><h1>Derive Macro <span class="derive">AsRef</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/derive_more_impl/lib.rs.html#138">Source</a> </span></div><pre class="rust item-decl"><code>#[derive(AsRef)]
|
||
{
|
||
<span class="comment">// Attributes available to this derive:</span>
|
||
#[as_ref]
|
||
}
|
||
</code></pre><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><h2 id="what-deriveasref-generates"><a class="doc-anchor" href="#what-deriveasref-generates">§</a>What <code>#[derive(AsRef)]</code> generates</h2>
|
||
<p>Deriving <code>AsRef</code> generates one or more implementations of <code>AsRef</code>, each
|
||
corresponding to one of the fields of the decorated type.
|
||
This allows types which contain some <code>T</code> to be passed anywhere that an
|
||
<code>AsRef<T></code> is accepted.</p>
|
||
<h3 id="newtypes-and-structs-with-one-field"><a class="doc-anchor" href="#newtypes-and-structs-with-one-field">§</a>Newtypes and Structs with One Field</h3>
|
||
<p>When <code>AsRef</code> is derived for a newtype or struct with one field, a single
|
||
implementation is generated to expose the underlying field.</p>
|
||
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="attr">#[derive(AsRef)]
|
||
</span><span class="kw">struct </span>MyWrapper(String);</code></pre></div>
|
||
<p>Generates:</p>
|
||
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">impl </span>derive_more::AsRef<String> <span class="kw">for </span>MyWrapper {
|
||
<span class="kw">fn </span>as_ref(<span class="kw-2">&</span><span class="self">self</span>) -> <span class="kw-2">&</span>String {
|
||
<span class="kw-2">&</span><span class="self">self</span>.<span class="number">0
|
||
</span>}
|
||
}</code></pre></div>
|
||
<p>It’s also possible to use the <code>#[as_ref(forward)]</code> attribute to forward
|
||
to the <code>as_ref</code> implementation of the field. So here <code>SingleFieldForward</code>
|
||
implements all <code>AsRef</code> for all types that <code>Vec<i32></code> implements <code>AsRef</code> for.</p>
|
||
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="attr">#[derive(AsRef)]
|
||
#[as_ref(forward)]
|
||
</span><span class="kw">struct </span>SingleFieldForward(Vec<i32>);
|
||
|
||
<span class="kw">let </span>item = SingleFieldForward(<span class="macro">vec!</span>[]);
|
||
<span class="kw">let _</span>: <span class="kw-2">&</span>[i32] = (<span class="kw-2">&</span>item).as_ref();</code></pre></div>
|
||
<p>This generates code equivalent to:</p>
|
||
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">impl</span><T: <span class="question-mark">?</span>Sized> derive_more::AsRef<T> <span class="kw">for </span>SingleFieldForward
|
||
<span class="kw">where
|
||
</span>Vec<i32>: derive_more::AsRef<T>,
|
||
{
|
||
<span class="attr">#[inline]
|
||
</span><span class="kw">fn </span>as_ref(<span class="kw-2">&</span><span class="self">self</span>) -> <span class="kw-2">&</span>T {
|
||
<span class="self">self</span>.<span class="number">0</span>.as_ref()
|
||
}
|
||
}</code></pre></div>
|
||
<p>Specifying concrete types, to derive impls for, is also supported via
|
||
<code>#[as_ref(<types>)]</code> attribute. These types can include both the type
|
||
of the field itself, and types for which the field type implements <code>AsRef</code>.</p>
|
||
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="attr">#[derive(AsRef)]
|
||
#[as_ref(str, [u8]</span>, String)]
|
||
<span class="kw">struct </span>Types(String);
|
||
|
||
<span class="kw">let </span>item = Types(<span class="string">"test"</span>.to_owned());
|
||
<span class="kw">let _</span>: <span class="kw-2">&</span>str = item.as_ref();
|
||
<span class="kw">let _</span>: <span class="kw-2">&</span>[u8] = item.as_ref();
|
||
<span class="kw">let _</span>: <span class="kw-2">&</span>String = item.as_ref();</code></pre></div>
|
||
<blockquote>
|
||
<p><strong>WARNING</strong>: When either the field type, or the specified conversion type,
|
||
contains generic parameters, they are considered as the same type only if
|
||
are named string-equally, otherwise are assumed as different types even
|
||
when represent the same type in fact (type aliases, for example).</p>
|
||
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="attr">#[derive(AsRef)]
|
||
#[as_ref(i32)] </span><span class="comment">// generates `impl<T: AsRef<i32>> AsRef<i32> for Generic<T>`
|
||
</span><span class="kw">struct </span>Generic<T>(T);
|
||
|
||
<span class="attr">#[derive(AsRef)]
|
||
#[as_ref(T)] </span><span class="comment">// generates `impl<T> AsRef<T> for Transparent<T>`
|
||
</span><span class="kw">struct </span>Transparent<T>(T);
|
||
|
||
<span class="attr">#[derive(AsRef)]
|
||
</span><span class="comment">// #[as_ref(RenamedVec<T>)] // not supported, as types are not named string-equally
|
||
</span><span class="kw">struct </span>Foo<T>(Vec<T>);
|
||
<span class="kw">type </span>RenamedVec<T> = Vec<T>;
|
||
|
||
<span class="attr">#[derive(AsRef)]
|
||
#[as_ref(RenamedString)] </span><span class="comment">// generates `impl AsRef<RenamedString> for Bar`,
|
||
</span><span class="kw">struct </span>Bar(String); <span class="comment">// as generics are not involved
|
||
</span><span class="kw">type </span>RenamedString = String;</code></pre></div>
|
||
</blockquote>
|
||
<p>Generating code like this is not supported:</p>
|
||
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">struct </span>Generic<T>(T);
|
||
|
||
<span class="kw">impl </span>AsRef<i32> <span class="kw">for </span>Generic<i32> {
|
||
<span class="kw">fn </span>as_ref(<span class="kw-2">&</span><span class="self">self</span>) -> <span class="kw-2">&</span>i32 {
|
||
<span class="kw-2">&</span><span class="self">self</span>.<span class="number">0
|
||
</span>}
|
||
}</code></pre></div>
|
||
<h3 id="structs-with-multiple-fields"><a class="doc-anchor" href="#structs-with-multiple-fields">§</a>Structs with Multiple Fields</h3>
|
||
<p>When <code>AsRef</code> is derived for a struct with more than one field (including tuple
|
||
structs), you must also mark one or more fields with the <code>#[as_ref]</code> attribute.
|
||
An implementation will be generated for each indicated field.</p>
|
||
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="attr">#[derive(AsRef)]
|
||
</span><span class="kw">struct </span>MyWrapper {
|
||
<span class="attr">#[as_ref(str)]
|
||
</span>name: String,
|
||
<span class="attr">#[as_ref]
|
||
</span>num: i32,
|
||
valid: bool,
|
||
}</code></pre></div>
|
||
<p>Generates:</p>
|
||
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">impl </span>AsRef<str> <span class="kw">for </span>MyWrapper {
|
||
<span class="kw">fn </span>as_ref(<span class="kw-2">&</span><span class="self">self</span>) -> <span class="kw-2">&</span>str {
|
||
<span class="self">self</span>.name.as_ref()
|
||
}
|
||
}
|
||
|
||
<span class="kw">impl </span>AsRef<i32> <span class="kw">for </span>MyWrapper {
|
||
<span class="kw">fn </span>as_ref(<span class="kw-2">&</span><span class="self">self</span>) -> <span class="kw-2">&</span>i32 {
|
||
<span class="kw-2">&</span><span class="self">self</span>.num
|
||
}
|
||
}</code></pre></div>
|
||
<h4 id="tuples-not-supported"><a class="doc-anchor" href="#tuples-not-supported">§</a>Tuples (not supported)</h4>
|
||
<p>Only conversions that use a single field are possible with this derive.
|
||
Something like this wouldn’t work, due to the nature of the <code>AsRef</code> trait
|
||
itself:</p>
|
||
|
||
<div class="example-wrap compile_fail"><a href="#" class="tooltip" title="This example deliberately fails to compile">ⓘ</a><pre class="rust rust-example-rendered"><code><span class="attr">#[derive(AsRef)]
|
||
#[as_ref((str, [u8]</span>))]
|
||
<span class="kw">struct </span>MyWrapper(String, Vec<u8>)</code></pre></div>
|
||
<p>If you need to convert into a tuple of references, consider using the
|
||
<a href="derive.Into.html" title="derive derive_more_impl::Into"><code>Into</code></a> derive with <code>#[into(ref)]</code>.</p>
|
||
<h4 id="skipping"><a class="doc-anchor" href="#skipping">§</a>Skipping</h4>
|
||
<p>Or vice versa: you can exclude a specific field by using <code>#[as_ref(skip)]</code> (or
|
||
<code>#[as_ref(ignore)]</code>). Then, implementations will be generated for non-indicated fields.</p>
|
||
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="attr">#[derive(AsRef)]
|
||
</span><span class="kw">struct </span>MyWrapper {
|
||
<span class="attr">#[as_ref(skip)]
|
||
</span>name: String,
|
||
<span class="attr">#[as_ref(ignore)]
|
||
</span>num: i32,
|
||
valid: bool,
|
||
}</code></pre></div>
|
||
<p>Generates:</p>
|
||
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">impl </span>AsRef<bool> <span class="kw">for </span>MyWrapper {
|
||
<span class="kw">fn </span>as_ref(<span class="kw-2">&</span><span class="self">self</span>) -> <span class="kw-2">&</span>bool {
|
||
<span class="kw-2">&</span><span class="self">self</span>.valid
|
||
}
|
||
}</code></pre></div>
|
||
<h4 id="coherence"><a class="doc-anchor" href="#coherence">§</a>Coherence</h4>
|
||
<p>Note that <code>AsRef<T></code> may only be implemented once for any given type <code>T</code>.
|
||
This means any attempt to mark more than one field of the same type with
|
||
<code>#[as_ref]</code> will result in a compilation error.</p>
|
||
|
||
<div class="example-wrap compile_fail"><a href="#" class="tooltip" title="This example deliberately fails to compile">ⓘ</a><pre class="rust rust-example-rendered"><code><span class="comment">// Error! Conflicting implementations of AsRef<String>
|
||
</span><span class="attr">#[derive(AsRef)]
|
||
</span><span class="kw">struct </span>MyWrapper {
|
||
<span class="attr">#[as_ref]
|
||
</span>str1: String,
|
||
<span class="attr">#[as_ref]
|
||
</span>str2: String,
|
||
}</code></pre></div>
|
||
<p>Similarly, if some field is annotated with <code>#[as_ref(forward)]</code>, no other
|
||
field can be marked.</p>
|
||
|
||
<div class="example-wrap compile_fail"><a href="#" class="tooltip" title="This example deliberately fails to compile">ⓘ</a><pre class="rust rust-example-rendered"><code><span class="comment">// Error! Conflicting implementations of `AsRef<i32>`
|
||
// note: upstream crates may add a new impl of trait `AsRef<i32>`
|
||
// for type `String` in future versions
|
||
</span><span class="attr">#[derive(AsRef)]
|
||
</span><span class="kw">struct </span>ForwardWithOther {
|
||
<span class="attr">#[as_ref(forward)]
|
||
</span>str: String,
|
||
<span class="attr">#[as_ref]
|
||
</span>number: i32,
|
||
}</code></pre></div>
|
||
<p>Multiple forwarded impls with different concrete types, however, can be used.</p>
|
||
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="attr">#[derive(AsRef)]
|
||
</span><span class="kw">struct </span>Types {
|
||
<span class="attr">#[as_ref(str)]
|
||
</span>str: String,
|
||
<span class="attr">#[as_ref([u8]</span>)]
|
||
vec: Vec<u8>,
|
||
}
|
||
|
||
<span class="kw">let </span>item = Types {
|
||
str: <span class="string">"test"</span>.to_owned(),
|
||
vec: <span class="macro">vec!</span>[<span class="number">0u8</span>],
|
||
};
|
||
|
||
<span class="kw">let _</span>: <span class="kw-2">&</span>str = item.as_ref();
|
||
<span class="kw">let _</span>: <span class="kw-2">&</span>[u8] = item.as_ref();</code></pre></div>
|
||
<h3 id="enums"><a class="doc-anchor" href="#enums">§</a>Enums</h3>
|
||
<p>Deriving <code>AsRef</code> for enums is not supported.</p>
|
||
</div></details></section></div></main></body></html> |