You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Trac3r-rust/doc/serde/de/trait.DeserializeSeed.html

155 lines
16 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!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 `DeserializeSeed` trait in crate `serde`."><meta name="keywords" content="rust, rustlang, rust-lang, DeserializeSeed"><title>serde::de::DeserializeSeed - 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 trait"><!--[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='../../serde/index.html'><div class='logo-container'><img src='../../rust-logo.png' alt='logo'></div></a><p class='location'>Trait DeserializeSeed</p><div class="sidebar-elems"><div class="block items"><a class="sidebar-title" href="#associated-types">Associated Types</a><div class="sidebar-links"><a href="#associatedtype.Value">Value</a></div><a class="sidebar-title" href="#required-methods">Required Methods</a><div class="sidebar-links"><a href="#tymethod.deserialize">deserialize</a></div><a class="sidebar-title" href="#foreign-impls">Implementations on Foreign Types</a><div class="sidebar-links"><a href="#impl-DeserializeSeed%3C%27de%3E-for-PhantomData%3CT%3E">PhantomData&lt;T&gt;</a></div><a class="sidebar-title" href="#implementors">Implementors</a></div><p class='location'><a href='../index.html'>serde</a>::<wbr><a href='index.html'>de</a></p><script>window.sidebarCurrent = {name: 'DeserializeSeed', ty: 'trait', relpath: ''};</script><script defer src="sidebar-items.js"></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/serde/de/mod.rs.html#757-766' title='goto source code'>[src]</a></span><span class='in-band'>Trait <a href='../index.html'>serde</a>::<wbr><a href='index.html'>de</a>::<wbr><a class="trait" href=''>DeserializeSeed</a></span></h1><div class="docblock type-decl hidden-by-usual-hider"><pre class='rust trait'>pub trait DeserializeSeed&lt;'de&gt;: <a class="trait" href="https://doc.rust-lang.org/nightly/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> {
type <a href='#associatedtype.Value' class="type">Value</a>;
fn <a href='#tymethod.deserialize' class='fnname'>deserialize</a>&lt;D&gt;(self, deserializer: D) -&gt; <a class="enum" href="https://doc.rust-lang.org/nightly/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;Self::<a class="type" href="../../serde/de/trait.DeserializeSeed.html#associatedtype.Value" title="type serde::de::DeserializeSeed::Value">Value</a>, D::<a class="type" href="../../serde/trait.Deserializer.html#associatedtype.Error" title="type serde::Deserializer::Error">Error</a>&gt;<br>&nbsp;&nbsp;&nbsp; <span class="where">where<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D: <a class="trait" href="../../serde/trait.Deserializer.html" title="trait serde::Deserializer">Deserializer</a>&lt;'de&gt;</span>;
}</pre></div><div class='docblock'><p><code>DeserializeSeed</code> is the stateful form of the <code>Deserialize</code> trait. If you
ever find yourself looking for a way to pass data into a <code>Deserialize</code> impl,
this trait is the way to do it.</p>
<p>As one example of stateful deserialization consider deserializing a JSON
array into an existing buffer. Using the <code>Deserialize</code> trait we could
deserialize a JSON array into a <code>Vec&lt;T&gt;</code> but it would be a freshly allocated
<code>Vec&lt;T&gt;</code>; there is no way for <code>Deserialize</code> to reuse a previously allocated
buffer. Using <code>DeserializeSeed</code> instead makes this possible as in the
example code below.</p>
<p>The canonical API for stateless deserialization looks like this:</p>
<pre><code class="language-edition2018"># use serde::Deserialize;
#
# enum Error {}
#
fn func&lt;'de, T: Deserialize&lt;'de&gt;&gt;() -&gt; Result&lt;T, Error&gt;
# {
# unimplemented!()
# }
</code></pre>
<p>Adjusting an API like this to support stateful deserialization is a matter
of accepting a seed as input:</p>
<pre><code class="language-edition2018"># use serde::de::DeserializeSeed;
#
# enum Error {}
#
fn func_seed&lt;'de, T: DeserializeSeed&lt;'de&gt;&gt;(seed: T) -&gt; Result&lt;T::Value, Error&gt;
# {
# let _ = seed;
# unimplemented!()
# }
</code></pre>
<p>In practice the majority of deserialization is stateless. An API expecting a
seed can be appeased by passing <code>std::marker::PhantomData</code> as a seed in the
case of stateless deserialization.</p>
<h1 id="lifetime" class="section-header"><a href="#lifetime">Lifetime</a></h1>
<p>The <code>'de</code> lifetime of this trait is the lifetime of data that may be
borrowed by <code>Self::Value</code> when deserialized. See the page <a href="https://serde.rs/lifetimes.html">Understanding
deserializer lifetimes</a> for a more detailed explanation of these lifetimes.</p>
<h1 id="example" class="section-header"><a href="#example">Example</a></h1>
<p>Suppose we have JSON that looks like <code>[[1, 2], [3, 4, 5], [6]]</code> and we need
to deserialize it into a flat representation like <code>vec![1, 2, 3, 4, 5, 6]</code>.
Allocating a brand new <code>Vec&lt;T&gt;</code> for each subarray would be slow. Instead we
would like to allocate a single <code>Vec&lt;T&gt;</code> and then deserialize each subarray
into it. This requires stateful deserialization using the <code>DeserializeSeed</code>
trait.</p>
<pre><code class="language-edition2018">use std::fmt;
use std::marker::PhantomData;
use serde::de::{Deserialize, DeserializeSeed, Deserializer, SeqAccess, Visitor};
// A DeserializeSeed implementation that uses stateful deserialization to
// append array elements onto the end of an existing vector. The preexisting
// state (&quot;seed&quot;) in this case is the Vec&lt;T&gt;. The `deserialize` method of
// `ExtendVec` will be traversing the inner arrays of the JSON input and
// appending each integer into the existing Vec.
struct ExtendVec&lt;'a, T: 'a&gt;(&amp;'a mut Vec&lt;T&gt;);
impl&lt;'de, 'a, T&gt; DeserializeSeed&lt;'de&gt; for ExtendVec&lt;'a, T&gt;
where
T: Deserialize&lt;'de&gt;,
{
// The return type of the `deserialize` method. This implementation
// appends onto an existing vector but does not create any new data
// structure, so the return type is ().
type Value = ();
fn deserialize&lt;D&gt;(self, deserializer: D) -&gt; Result&lt;Self::Value, D::Error&gt;
where
D: Deserializer&lt;'de&gt;,
{
// Visitor implementation that will walk an inner array of the JSON
// input.
struct ExtendVecVisitor&lt;'a, T: 'a&gt;(&amp;'a mut Vec&lt;T&gt;);
impl&lt;'de, 'a, T&gt; Visitor&lt;'de&gt; for ExtendVecVisitor&lt;'a, T&gt;
where
T: Deserialize&lt;'de&gt;,
{
type Value = ();
fn expecting(&amp;self, formatter: &amp;mut fmt::Formatter) -&gt; fmt::Result {
write!(formatter, &quot;an array of integers&quot;)
}
fn visit_seq&lt;A&gt;(self, mut seq: A) -&gt; Result&lt;(), A::Error&gt;
where
A: SeqAccess&lt;'de&gt;,
{
// Visit each element in the inner array and push it onto
// the existing vector.
while let Some(elem) = seq.next_element()? {
self.0.push(elem);
}
Ok(())
}
}
deserializer.deserialize_seq(ExtendVecVisitor(self.0))
}
}
// Visitor implementation that will walk the outer array of the JSON input.
struct FlattenedVecVisitor&lt;T&gt;(PhantomData&lt;T&gt;);
impl&lt;'de, T&gt; Visitor&lt;'de&gt; for FlattenedVecVisitor&lt;T&gt;
where
T: Deserialize&lt;'de&gt;,
{
// This Visitor constructs a single Vec&lt;T&gt; to hold the flattened
// contents of the inner arrays.
type Value = Vec&lt;T&gt;;
fn expecting(&amp;self, formatter: &amp;mut fmt::Formatter) -&gt; fmt::Result {
write!(formatter, &quot;an array of arrays&quot;)
}
fn visit_seq&lt;A&gt;(self, mut seq: A) -&gt; Result&lt;Vec&lt;T&gt;, A::Error&gt;
where
A: SeqAccess&lt;'de&gt;,
{
// Create a single Vec to hold the flattened contents.
let mut vec = Vec::new();
// Each iteration through this loop is one inner array.
while let Some(()) = seq.next_element_seed(ExtendVec(&amp;mut vec))? {
// Nothing to do; inner array has been appended into `vec`.
}
// Return the finished vec.
Ok(vec)
}
}
# fn example&lt;'de, D&gt;(deserializer: D) -&gt; Result&lt;(), D::Error&gt;
# where
# D: Deserializer&lt;'de&gt;,
# {
let visitor = FlattenedVecVisitor(PhantomData);
let flattened: Vec&lt;u64&gt; = deserializer.deserialize_seq(visitor)?;
# Ok(())
# }
</code></pre>
</div>
<h2 id='associated-types' class='small-section-header'>Associated Types<a href='#associated-types' class='anchor'></a></h2><div class='methods'><h3 id='associatedtype.Value' class='method'><code id='Value.t'>type <a href='#associatedtype.Value' class="type">Value</a></code></h3><div class='docblock'><p>The type produced by using this seed.</p>
</div></div><span class='loading-content'>Loading content...</span>
<h2 id='required-methods' class='small-section-header'>Required methods<a href='#required-methods' class='anchor'></a></h2><div class='methods'><h3 id='tymethod.deserialize' class='method'><code id='deserialize.v'>fn <a href='#tymethod.deserialize' class='fnname'>deserialize</a>&lt;D&gt;(self, deserializer: D) -&gt; <a class="enum" href="https://doc.rust-lang.org/nightly/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;Self::<a class="type" href="../../serde/de/trait.DeserializeSeed.html#associatedtype.Value" title="type serde::de::DeserializeSeed::Value">Value</a>, D::<a class="type" href="../../serde/trait.Deserializer.html#associatedtype.Error" title="type serde::Deserializer::Error">Error</a>&gt; <span class="where fmt-newline">where<br>&nbsp;&nbsp;&nbsp;&nbsp;D: <a class="trait" href="../../serde/trait.Deserializer.html" title="trait serde::Deserializer">Deserializer</a>&lt;'de&gt;,&nbsp;</span></code></h3><div class='docblock'><p>Equivalent to the more common <code>Deserialize::deserialize</code> method, except
with some initial piece of data (the seed) passed in.</p>
</div></div><span class='loading-content'>Loading content...</span>
<h2 id='foreign-impls' class='small-section-header'>Implementations on Foreign Types<a href='#foreign-impls' class='anchor'></a></h2><h3 id='impl-DeserializeSeed%3C%27de%3E-for-PhantomData%3CT%3E' class='impl'><code class='in-band'>impl&lt;'de, T&gt; <a class="trait" href="../../serde/de/trait.DeserializeSeed.html" title="trait serde::de::DeserializeSeed">DeserializeSeed</a>&lt;'de&gt; for <a class="struct" href="https://doc.rust-lang.org/nightly/core/marker/struct.PhantomData.html" title="struct core::marker::PhantomData">PhantomData</a>&lt;T&gt; <span class="where fmt-newline">where<br>&nbsp;&nbsp;&nbsp;&nbsp;T: <a class="trait" href="../../serde/trait.Deserialize.html" title="trait serde::Deserialize">Deserialize</a>&lt;'de&gt;,&nbsp;</span></code><a href='#impl-DeserializeSeed%3C%27de%3E-for-PhantomData%3CT%3E' class='anchor'></a><a class='srclink' href='../../src/serde/de/mod.rs.html#768-781' title='goto source code'>[src]</a></h3><div class='impl-items'><h4 id='associatedtype.Value-1' class="type"><code id='Value.t-1'>type <a href='#associatedtype.Value' class="type">Value</a> = T</code></h4><h4 id='method.deserialize' class="method hidden"><code id='deserialize.v-1'>fn <a href='#method.deserialize' class='fnname'>deserialize</a>&lt;D&gt;(self, deserializer: D) -&gt; <a class="enum" href="https://doc.rust-lang.org/nightly/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;T, D::<a class="type" href="../../serde/trait.Deserializer.html#associatedtype.Error" title="type serde::Deserializer::Error">Error</a>&gt; <span class="where fmt-newline">where<br>&nbsp;&nbsp;&nbsp;&nbsp;D: <a class="trait" href="../../serde/trait.Deserializer.html" title="trait serde::Deserializer">Deserializer</a>&lt;'de&gt;,&nbsp;</span></code><a class='srclink' href='../../src/serde/de/mod.rs.html#775-780' title='goto source code'>[src]</a></h4></div><span class='loading-content'>Loading content...</span>
<h2 id='implementors' class='small-section-header'>Implementors<a href='#implementors' class='anchor'></a></h2><div class='item-list' id='implementors-list'></div><span class='loading-content'>Loading content...</span><script type="text/javascript">window.inlined_types=new Set([]);</script><script type="text/javascript" async
src="../../implementors/serde/de/trait.DeserializeSeed.js">
</script></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 = "serde";</script><script src="../../aliases.js"></script><script src="../../main.js"></script><script defer src="../../search-index.js"></script></body></html>