mentat/serde/de/trait.DeserializeSeed.html
2018-08-22 17:04:13 +00:00

281 lines
No EOL
24 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="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="../../main.css" id="themeStyle">
<script src="../../storage.js"></script>
</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>
<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">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">
<input class="search-input" name="search"
autocomplete="off"
placeholder="Click or press S to search, ? for more options…"
type="search">
</div>
</form>
</nav>
<section id='main' class="content">
<h1 class='fqn'><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><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#756-765' title='goto source code'>[src]</a></span></h1>
<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 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 class="rust rust-example-rendered">
<span class="kw">fn</span> <span class="ident">func</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span>, <span class="ident">T</span>: <span class="ident">Deserialize</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span><span class="op">&gt;&gt;</span>() <span class="op">-&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">Error</span><span class="op">&gt;</span></pre>
<p>Adjusting an API like this to support stateful deserialization is a matter
of accepting a seed as input:</p>
<pre class="rust rust-example-rendered">
<span class="kw">fn</span> <span class="ident">func_seed</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span>, <span class="ident">T</span>: <span class="ident">DeserializeSeed</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span><span class="op">&gt;&gt;</span>(<span class="ident">seed</span>: <span class="ident">T</span>) <span class="op">-&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">T</span>::<span class="ident">Value</span>, <span class="ident">Error</span><span class="op">&gt;</span></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 class="rust rust-example-rendered">
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">fmt</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">marker</span>::<span class="ident">PhantomData</span>;
<span class="kw">use</span> <span class="ident">serde</span>::<span class="ident">de</span>::{<span class="ident">Deserialize</span>, <span class="ident">DeserializeSeed</span>, <span class="ident">Deserializer</span>, <span class="ident">SeqAccess</span>, <span class="ident">Visitor</span>};
<span class="comment">// A DeserializeSeed implementation that uses stateful deserialization to</span>
<span class="comment">// append array elements onto the end of an existing vector. The preexisting</span>
<span class="comment">// state (&quot;seed&quot;) in this case is the Vec&lt;T&gt;. The `deserialize` method of</span>
<span class="comment">// `ExtendVec` will be traversing the inner arrays of the JSON input and</span>
<span class="comment">// appending each integer into the existing Vec.</span>
<span class="kw">struct</span> <span class="ident">ExtendVec</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span>, <span class="ident">T</span>: <span class="lifetime">&#39;a</span><span class="op">&gt;</span>(<span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> <span class="kw-2">mut</span> <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>);
<span class="kw">impl</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span>, <span class="lifetime">&#39;a</span>, <span class="ident">T</span><span class="op">&gt;</span> <span class="ident">DeserializeSeed</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span><span class="op">&gt;</span> <span class="kw">for</span> <span class="ident">ExtendVec</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span>, <span class="ident">T</span><span class="op">&gt;</span>
<span class="kw">where</span>
<span class="ident">T</span>: <span class="ident">Deserialize</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span><span class="op">&gt;</span>,
{
<span class="comment">// The return type of the `deserialize` method. This implementation</span>
<span class="comment">// appends onto an existing vector but does not create any new data</span>
<span class="comment">// structure, so the return type is ().</span>
<span class="kw">type</span> <span class="ident">Value</span> <span class="op">=</span> ();
<span class="kw">fn</span> <span class="ident">deserialize</span><span class="op">&lt;</span><span class="ident">D</span><span class="op">&gt;</span>(<span class="self">self</span>, <span class="ident">deserializer</span>: <span class="ident">D</span>) <span class="op">-&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="self">Self</span>::<span class="ident">Value</span>, <span class="ident">D</span>::<span class="ident">Error</span><span class="op">&gt;</span>
<span class="kw">where</span>
<span class="ident">D</span>: <span class="ident">Deserializer</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span><span class="op">&gt;</span>,
{
<span class="comment">// Visitor implementation that will walk an inner array of the JSON</span>
<span class="comment">// input.</span>
<span class="kw">struct</span> <span class="ident">ExtendVecVisitor</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span>, <span class="ident">T</span>: <span class="lifetime">&#39;a</span><span class="op">&gt;</span>(<span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> <span class="kw-2">mut</span> <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>);
<span class="kw">impl</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span>, <span class="lifetime">&#39;a</span>, <span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Visitor</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span><span class="op">&gt;</span> <span class="kw">for</span> <span class="ident">ExtendVecVisitor</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span>, <span class="ident">T</span><span class="op">&gt;</span>
<span class="kw">where</span>
<span class="ident">T</span>: <span class="ident">Deserialize</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span><span class="op">&gt;</span>,
{
<span class="kw">type</span> <span class="ident">Value</span> <span class="op">=</span> ();
<span class="kw">fn</span> <span class="ident">expecting</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">formatter</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">fmt</span>::<span class="ident">Formatter</span>) <span class="op">-&gt;</span> <span class="ident">fmt</span>::<span class="prelude-ty">Result</span> {
<span class="macro">write</span><span class="macro">!</span>(<span class="ident">formatter</span>, <span class="string">&quot;an array of integers&quot;</span>)
}
<span class="kw">fn</span> <span class="ident">visit_seq</span><span class="op">&lt;</span><span class="ident">A</span><span class="op">&gt;</span>(<span class="self">self</span>, <span class="kw-2">mut</span> <span class="ident">seq</span>: <span class="ident">A</span>) <span class="op">-&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">A</span>::<span class="ident">Error</span><span class="op">&gt;</span>
<span class="kw">where</span>
<span class="ident">A</span>: <span class="ident">SeqAccess</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span><span class="op">&gt;</span>,
{
<span class="comment">// Visit each element in the inner array and push it onto</span>
<span class="comment">// the existing vector.</span>
<span class="kw">while</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">elem</span>) <span class="op">=</span> <span class="ident">seq</span>.<span class="ident">next_element</span>()<span class="question-mark">?</span> {
<span class="self">self</span>.<span class="number">0</span>.<span class="ident">push</span>(<span class="ident">elem</span>);
}
<span class="prelude-val">Ok</span>(())
}
}
<span class="ident">deserializer</span>.<span class="ident">deserialize_seq</span>(<span class="ident">ExtendVecVisitor</span>(<span class="self">self</span>.<span class="number">0</span>))
}
}
<span class="comment">// Visitor implementation that will walk the outer array of the JSON input.</span>
<span class="kw">struct</span> <span class="ident">FlattenedVecVisitor</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>(<span class="ident">PhantomData</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>);
<span class="kw">impl</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span>, <span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Visitor</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span><span class="op">&gt;</span> <span class="kw">for</span> <span class="ident">FlattenedVecVisitor</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>
<span class="kw">where</span>
<span class="ident">T</span>: <span class="ident">Deserialize</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span><span class="op">&gt;</span>,
{
<span class="comment">// This Visitor constructs a single Vec&lt;T&gt; to hold the flattened</span>
<span class="comment">// contents of the inner arrays.</span>
<span class="kw">type</span> <span class="ident">Value</span> <span class="op">=</span> <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>;
<span class="kw">fn</span> <span class="ident">expecting</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">formatter</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">fmt</span>::<span class="ident">Formatter</span>) <span class="op">-&gt;</span> <span class="ident">fmt</span>::<span class="prelude-ty">Result</span> {
<span class="macro">write</span><span class="macro">!</span>(<span class="ident">formatter</span>, <span class="string">&quot;an array of arrays&quot;</span>)
}
<span class="kw">fn</span> <span class="ident">visit_seq</span><span class="op">&lt;</span><span class="ident">A</span><span class="op">&gt;</span>(<span class="self">self</span>, <span class="kw-2">mut</span> <span class="ident">seq</span>: <span class="ident">A</span>) <span class="op">-&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>, <span class="ident">A</span>::<span class="ident">Error</span><span class="op">&gt;</span>
<span class="kw">where</span>
<span class="ident">A</span>: <span class="ident">SeqAccess</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span><span class="op">&gt;</span>,
{
<span class="comment">// Create a single Vec to hold the flattened contents.</span>
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">vec</span> <span class="op">=</span> <span class="ident">Vec</span>::<span class="ident">new</span>();
<span class="comment">// Each iteration through this loop is one inner array.</span>
<span class="kw">while</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(()) <span class="op">=</span> <span class="ident">seq</span>.<span class="ident">next_element_seed</span>(<span class="ident">ExtendVec</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">vec</span>))<span class="question-mark">?</span> {
<span class="comment">// Nothing to do; inner array has been appended into `vec`.</span>
}
<span class="comment">// Return the finished vec.</span>
<span class="prelude-val">Ok</span>(<span class="ident">vec</span>)
}
}
<span class="kw">let</span> <span class="ident">visitor</span> <span class="op">=</span> <span class="ident">FlattenedVecVisitor</span>(<span class="ident">PhantomData</span>);
<span class="kw">let</span> <span class="ident">flattened</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">u64</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">deserializer</span>.<span class="ident">deserialize_seq</span>(<span class="ident">visitor</span>)<span class="question-mark">?</span>;</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'><span id='Value.t' class='invisible'><code>type <a href='#associatedtype.Value' class="type">Value</a></code></span></h3><div class='docblock'><p>The type produced by using this seed.</p>
</div></div>
<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'><span id='deserialize.v' class='invisible'><code>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></span></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>
<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' class='impl'><span class='in-band'><code>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' class='anchor'></a></span><span class='out-of-band'><div class='ghost'></div><a class='srclink' href='../../src/serde/de/mod.rs.html#767-780' title='goto source code'>[src]</a></span></h3>
<span class='docblock autohide'><div class='impl-items'><h4 id='associatedtype.Value-1' class="type"><span id='Value.t-1' class='invisible'><code>type <a href='#associatedtype.Value' class="type">Value</a> = T</code></span></h4>
<h4 id='method.deserialize' class="method"><span id='deserialize.v-1' class='invisible'><code>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></span><span class='out-of-band'><div class='ghost'></div><a class='srclink' href='../../src/serde/de/mod.rs.html#774-779' title='goto source code'>[src]</a></span></h4>
</div></span>
<h2 id='implementors' class='small-section-header'>
Implementors<a href='#implementors' class='anchor'></a>
</h2>
<ul class='item-list' id='implementors-list'>
</ul><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>
</div>
</div>
</aside>
<script>
window.rootPath = "../../";
window.currentCrate = "serde";
</script>
<script src="../../main.js"></script>
<script defer src="../../search-index.js"></script>
</body>
</html>