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

195 lines
18 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="The main derive macro used by `bevy_reflect` for deriving its `Reflect` trait."><title>Reflect in bevy_reflect - 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="bevy_reflect" 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="icon" href="https://bevyengine.org/assets/icon.png"></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><a class="logo-container" href="../bevy_reflect/index.html"><img src="https://bevyengine.org/assets/icon.png" alt=""></a></nav><nav class="sidebar"><div class="sidebar-crate"><a class="logo-container" href="../bevy_reflect/index.html"><img src="https://bevyengine.org/assets/icon.png" alt="logo"></a><h2><a href="../bevy_reflect/index.html">bevy_<wbr>reflect</a><span class="version">0.15.1</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">Reflect</a></h2><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#container-attributes" title="Container Attributes">Container Attributes</a><ul><li><a href="#reflectident" title="`#[reflect(Ident)]`"><code>#[reflect(Ident)]</code></a></li><li><a href="#reflectopaque" title="`#[reflect(opaque)]`"><code>#[reflect(opaque)]</code></a></li><li><a href="#reflectfrom_reflect--false" title="`#[reflect(from_reflect = false)]`"><code>#[reflect(from_reflect = false)]</code></a></li><li><a href="#reflecttype_path--false" title="`#[reflect(type_path = false)]`"><code>#[reflect(type_path = false)]</code></a></li><li><a href="#reflectno_field_bounds" title="`#[reflect(no_field_bounds)]`"><code>#[reflect(no_field_bounds)]</code></a></li><li><a href="#reflectwhere-t-trait-uassoc-trait-" title="`#[reflect(where T: Trait, U::Assoc: Trait, ...)]`"><code>#[reflect(where T: Trait, U::Assoc: Trait, ...)]</code></a></li><li><a href="#reflect" title="`#[reflect(@...)]`"><code>#[reflect(@...)]</code></a></li></ul></li><li><a href="#field-attributes" title="Field Attributes">Field Attributes</a><ul><li><a href="#reflectignore" title="`#[reflect(ignore)]`"><code>#[reflect(ignore)]</code></a></li><li><a href="#reflectskip_serializing" title="`#[reflect(skip_serializing)]`"><code>#[reflect(skip_serializing)]</code></a></li><li><a href="#reflect-1" title="`#[reflect(@...)]`"><code>#[reflect(@...)]</code></a></li></ul></li></ul></section><div id="rustdoc-modnav"><h2 class="in-crate"><a href="index.html">In crate bevy_<wbr>reflect</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">bevy_reflect</a></span><h1>Derive Macro <span class="derive">Reflect</span><button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"></span></div><pre class="rust item-decl"><code>#[derive(Reflect)]
{
<span class="comment">// Attributes available to this derive:</span>
#[reflect]
#[type_path]
#[type_name]
}
</code></pre><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>The main derive macro used by <code>bevy_reflect</code> for deriving its <code>Reflect</code> trait.</p>
<p>This macro can be used on all structs and enums (unions are not supported).
It will automatically generate implementations for <code>Reflect</code>, <code>Typed</code>, <code>GetTypeRegistration</code>, and <code>FromReflect</code>.
And, depending on the items structure, will either implement <code>Struct</code>, <code>TupleStruct</code>, or <code>Enum</code>.</p>
<p>See the <a href="derive.FromReflect.html" title="derive bevy_reflect::FromReflect"><code>FromReflect</code></a> derive macro for more information on how to customize the <code>FromReflect</code> implementation.</p>
<h2 id="container-attributes"><a class="doc-anchor" href="#container-attributes">§</a>Container Attributes</h2>
<p>This macro comes with some helper attributes that can be added to the container item
in order to provide additional functionality or alter the generated implementations.</p>
<p>In addition to those listed, this macro can also use the attributes for <a href="derive.TypePath.html" title="derive bevy_reflect::TypePath"><code>TypePath</code></a> derives.</p>
<h3 id="reflectident"><a class="doc-anchor" href="#reflectident">§</a><code>#[reflect(Ident)]</code></h3>
<p>The <code>#[reflect(Ident)]</code> attribute is used to add type data registrations to the <code>GetTypeRegistration</code>
implementation corresponding to the given identifier, prepended by <code>Reflect</code>.</p>
<p>For example, <code>#[reflect(Foo, Bar)]</code> would add two registrations:
one for <code>ReflectFoo</code> and another for <code>ReflectBar</code>.
This assumes these types are indeed in-scope wherever this macro is called.</p>
<p>This is often used with traits that have been marked by the <a href="attr.reflect_trait.html" title="attr bevy_reflect::reflect_trait"><code>#[reflect_trait]</code></a>
macro in order to register the types implementation of that trait.</p>
<h4 id="default-registrations"><a class="doc-anchor" href="#default-registrations">§</a>Default Registrations</h4>
<p>The following types are automatically registered when deriving <code>Reflect</code>:</p>
<ul>
<li><code>ReflectFromReflect</code> (unless opting out of <code>FromReflect</code>)</li>
<li><code>SerializationData</code></li>
<li><code>ReflectFromPtr</code></li>
</ul>
<h4 id="special-identifiers"><a class="doc-anchor" href="#special-identifiers">§</a>Special Identifiers</h4>
<p>There are a few “special” identifiers that work a bit differently:</p>
<ul>
<li><code>#[reflect(Debug)]</code> will force the implementation of <code>Reflect::reflect_debug</code> to rely on
the types [<code>Debug</code>] implementation.
A custom implementation may be provided using <code>#[reflect(Debug(my_debug_func))]</code> where
<code>my_debug_func</code> is the path to a function matching the signature:
<code>(&amp;self, f: &amp;mut ::std::fmt::Formatter&lt;'_&gt;) -&gt; ::std::fmt::Result</code>.</li>
<li><code>#[reflect(PartialEq)]</code> will force the implementation of <code>Reflect::reflect_partial_eq</code> to rely on
the types [<code>PartialEq</code>] implementation.
A custom implementation may be provided using <code>#[reflect(PartialEq(my_partial_eq_func))]</code> where
<code>my_partial_eq_func</code> is the path to a function matching the signature:
<code>(&amp;self, value: &amp;dyn #bevy_reflect_path::Reflect) -&gt; bool</code>.</li>
<li><code>#[reflect(Hash)]</code> will force the implementation of <code>Reflect::reflect_hash</code> to rely on
the types [<code>Hash</code>] implementation.
A custom implementation may be provided using <code>#[reflect(Hash(my_hash_func))]</code> where
<code>my_hash_func</code> is the path to a function matching the signature: <code>(&amp;self) -&gt; u64</code>.</li>
<li><code>#[reflect(Default)]</code> will register the <code>ReflectDefault</code> type data as normal.
However, it will also affect how certain other operations are performed in order
to improve performance and/or robustness.
An example of where this is used is in the <a href="derive.FromReflect.html" title="derive bevy_reflect::FromReflect"><code>FromReflect</code></a> derive macro,
where adding this attribute will cause the <code>FromReflect</code> implementation to create
a base value using its [<code>Default</code>] implementation avoiding issues with ignored fields
(for structs and tuple structs only).</li>
</ul>
<h3 id="reflectopaque"><a class="doc-anchor" href="#reflectopaque">§</a><code>#[reflect(opaque)]</code></h3>
<p>The <code>#[reflect(opaque)]</code> attribute denotes that the item should implement <code>Reflect</code> as an opaque type,
hiding its structure and fields from the reflection API.
This means that it will forgo implementing <code>Struct</code>, <code>TupleStruct</code>, or <code>Enum</code>.</p>
<p>Furthermore, it requires that the type implements [<code>Clone</code>].
If planning to serialize this type using the reflection serializers,
then the <code>Serialize</code> and <code>Deserialize</code> traits will need to be implemented and registered as well.</p>
<h3 id="reflectfrom_reflect--false"><a class="doc-anchor" href="#reflectfrom_reflect--false">§</a><code>#[reflect(from_reflect = false)]</code></h3>
<p>This attribute will opt-out of the default <code>FromReflect</code> implementation.</p>
<p>This is useful for when a type cant or shouldnt implement <code>FromReflect</code>,
or if a manual implementation is desired.</p>
<p>Note that in the latter case, <code>ReflectFromReflect</code> will no longer be automatically registered.</p>
<h3 id="reflecttype_path--false"><a class="doc-anchor" href="#reflecttype_path--false">§</a><code>#[reflect(type_path = false)]</code></h3>
<p>This attribute will opt-out of the default <code>TypePath</code> implementation.</p>
<p>This is useful for when a type cant or shouldnt implement <code>TypePath</code>,
or if a manual implementation is desired.</p>
<h3 id="reflectno_field_bounds"><a class="doc-anchor" href="#reflectno_field_bounds">§</a><code>#[reflect(no_field_bounds)]</code></h3>
<p>This attribute will opt-out of the default trait bounds added to all field types
for the generated reflection trait impls.</p>
<p>Normally, all fields will have the bounds <code>TypePath</code>, and either <code>FromReflect</code> or <code>Reflect</code>
depending on if <code>#[reflect(from_reflect = false)]</code> is used.
However, this might not always be desirable, and so this attribute may be used to remove those bounds.</p>
<h4 id="example"><a class="doc-anchor" href="#example">§</a>Example</h4>
<p>If a type is recursive the default bounds will cause an overflow error when building:</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="attr">#[derive(Reflect)] </span><span class="comment">// ERROR: overflow evaluating the requirement `Foo: FromReflect`
</span><span class="kw">struct </span>Foo {
foo: Vec&lt;Foo&gt;,
}
<span class="comment">// Generates a where clause like:
// impl bevy_reflect::Reflect for Foo
// where
// Self: Any + Send + Sync,
// Vec&lt;Foo&gt;: FromReflect + TypePath,</span></code></pre></div>
<p>In this case, <code>Foo</code> is given the bounds <code>Vec&lt;Foo&gt;: FromReflect + TypePath</code>,
which requires that <code>Foo</code> implements <code>FromReflect</code>,
which requires that <code>Vec&lt;Foo&gt;</code> implements <code>FromReflect</code>,
and so on, resulting in the error.</p>
<p>To fix this, we can add <code>#[reflect(no_field_bounds)]</code> to <code>Foo</code> to remove the bounds on <code>Vec&lt;Foo&gt;</code>:</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="attr">#[derive(Reflect)]
#[reflect(no_field_bounds)]
</span><span class="kw">struct </span>Foo {
foo: Vec&lt;Foo&gt;,
}
<span class="comment">// Generates a where clause like:
// impl bevy_reflect::Reflect for Foo
// where
// Self: Any + Send + Sync,</span></code></pre></div>
<h3 id="reflectwhere-t-trait-uassoc-trait-"><a class="doc-anchor" href="#reflectwhere-t-trait-uassoc-trait-">§</a><code>#[reflect(where T: Trait, U::Assoc: Trait, ...)]</code></h3>
<p>This attribute can be used to add additional bounds to the generated reflection trait impls.</p>
<p>This is useful for when a type needs certain bounds only applied to the reflection impls
that are not otherwise automatically added by the derive macro.</p>
<h4 id="example-1"><a class="doc-anchor" href="#example-1">§</a>Example</h4>
<p>In the example below, we want to enforce that <code>T::Assoc: List</code> is required in order for
<code>Foo&lt;T&gt;</code> to be reflectable, but we dont want it to prevent <code>Foo&lt;T&gt;</code> from being used
in places where <code>T::Assoc: List</code> is not required.</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">trait </span>Trait {
<span class="kw">type </span>Assoc;
}
<span class="attr">#[derive(Reflect)]
#[reflect(<span class="kw">where </span>T::Assoc: List)]
</span><span class="kw">struct </span>Foo&lt;T: Trait&gt; <span class="kw">where </span>T::Assoc: Default {
value: T::Assoc,
}
<span class="comment">// Generates a where clause like:
//
// impl&lt;T: Trait&gt; bevy_reflect::Reflect for Foo&lt;T&gt;
// where
// Self: Any + Send + Sync,
// T::Assoc: Default,
// T: TypePath,
// T::Assoc: FromReflect + TypePath,
// T::Assoc: List,
// {/* ... */}</span></code></pre></div>
<h3 id="reflect"><a class="doc-anchor" href="#reflect">§</a><code>#[reflect(@...)]</code></h3>
<p>This attribute can be used to register custom attributes to the types <code>TypeInfo</code>.</p>
<p>It accepts any expression after the <code>@</code> symbol that resolves to a value which implements <code>Reflect</code>.</p>
<p>Any number of custom attributes may be registered, however, each the type of each attribute must be unique.
If two attributes of the same type are registered, the last one will overwrite the first.</p>
<h4 id="example-2"><a class="doc-anchor" href="#example-2">§</a>Example</h4>
<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="attr">#[derive(Reflect)]
</span><span class="kw">struct </span>Required;
<span class="attr">#[derive(Reflect)]
</span><span class="kw">struct </span>EditorTooltip(String);
<span class="kw">impl </span>EditorTooltip {
<span class="kw">fn </span>new(text: <span class="kw-2">&amp;</span>str) -&gt; <span class="self">Self </span>{
<span class="self">Self</span>(text.to_string())
}
}
<span class="attr">#[derive(Reflect)]
</span><span class="comment">// Specify a "required" status and tooltip:
</span><span class="attr">#[reflect(@Required, @EditorTooltip::new(<span class="string">"An ID is required!"</span>))]
</span><span class="kw">struct </span>Id(u8);</code></pre></div>
<h2 id="field-attributes"><a class="doc-anchor" href="#field-attributes">§</a>Field Attributes</h2>
<p>Along with the container attributes, this macro comes with some attributes that may be applied
to the contained fields themselves.</p>
<h3 id="reflectignore"><a class="doc-anchor" href="#reflectignore">§</a><code>#[reflect(ignore)]</code></h3>
<p>This attribute simply marks a field to be ignored by the reflection API.</p>
<p>This allows fields to completely opt-out of reflection,
which may be useful for maintaining invariants, keeping certain data private,
or allowing the use of types that do not implement <code>Reflect</code> within the container.</p>
<h3 id="reflectskip_serializing"><a class="doc-anchor" href="#reflectskip_serializing">§</a><code>#[reflect(skip_serializing)]</code></h3>
<p>This works similar to <code>#[reflect(ignore)]</code>, but rather than opting out of <em>all</em> of reflection,
it simply opts the field out of both serialization and deserialization.
This can be useful when a field should be accessible via reflection, but may not make
sense in a serialized form, such as computed data.</p>
<p>What this does is register the <code>SerializationData</code> type within the <code>GetTypeRegistration</code> implementation,
which will be used by the reflection serializers to determine whether or not the field is serializable.</p>
<h3 id="reflect-1"><a class="doc-anchor" href="#reflect-1">§</a><code>#[reflect(@...)]</code></h3>
<p>This attribute can be used to register custom attributes to the fields <code>TypeInfo</code>.</p>
<p>It accepts any expression after the <code>@</code> symbol that resolves to a value which implements <code>Reflect</code>.</p>
<p>Any number of custom attributes may be registered, however, each the type of each attribute must be unique.
If two attributes of the same type are registered, the last one will overwrite the first.</p>
<h4 id="example-3"><a class="doc-anchor" href="#example-3">§</a>Example</h4>
<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="attr">#[derive(Reflect)]
</span><span class="kw">struct </span>EditorTooltip(String);
<span class="kw">impl </span>EditorTooltip {
<span class="kw">fn </span>new(text: <span class="kw-2">&amp;</span>str) -&gt; <span class="self">Self </span>{
<span class="self">Self</span>(text.to_string())
}
}
<span class="attr">#[derive(Reflect)]
</span><span class="kw">struct </span>Slider {
<span class="comment">// Specify a custom range and tooltip:
</span><span class="attr">#[reflect(@<span class="number">0.0</span>..=<span class="number">1.0</span>, @EditorTooltip::new(<span class="string">"Must be between 0 and 1"</span>))]
</span>value: f32,
}</code></pre></div>
</div></details></section></div></main></body></html>