wasm-bindgen/reference/arbitrary-data-with-serde.html

363 lines
31 KiB
HTML

<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Arbitrary Data with Serde - The `wasm-bindgen` Guide</title>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:500" rel="stylesheet" type="text/css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body class="light">
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "../";
var default_theme = "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
document.body.className = theme;
document.querySelector('html').className = theme + ' js';
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="affix"><a href="../introduction.html">Introduction</a></li><li class="spacer"></li><li><a href="../examples/index.html"><strong aria-hidden="true">1.</strong> Examples</a></li><li><ol class="section"><li><a href="../examples/hello-world.html"><strong aria-hidden="true">1.1.</strong> Hello, World!</a></li><li><a href="../examples/console-log.html"><strong aria-hidden="true">1.2.</strong> Using console.log</a></li><li><a href="../examples/add.html"><strong aria-hidden="true">1.3.</strong> Small wasm files</a></li><li><a href="../examples/without-a-bundler.html"><strong aria-hidden="true">1.4.</strong> Without a Bundler</a></li><li><a href="../examples/wasm2js.html"><strong aria-hidden="true">1.5.</strong> Converting WebAssembly to JS</a></li><li><a href="../examples/import-js.html"><strong aria-hidden="true">1.6.</strong> Importing functions from JS</a></li><li><a href="../examples/char.html"><strong aria-hidden="true">1.7.</strong> Working with char</a></li><li><a href="../examples/wasm-in-wasm.html"><strong aria-hidden="true">1.8.</strong> js-sys: WebAssembly in WebAssembly</a></li><li><a href="../examples/dom.html"><strong aria-hidden="true">1.9.</strong> web-sys: DOM hello world</a></li><li><a href="../examples/closures.html"><strong aria-hidden="true">1.10.</strong> web-sys: Closures</a></li><li><a href="../examples/performance.html"><strong aria-hidden="true">1.11.</strong> web-sys: performance.now</a></li><li><a href="../examples/fetch.html"><strong aria-hidden="true">1.12.</strong> web-sys: using fetch</a></li><li><a href="../examples/2d-canvas.html"><strong aria-hidden="true">1.13.</strong> web-sys: canvas hello world</a></li><li><a href="../examples/julia.html"><strong aria-hidden="true">1.14.</strong> web-sys: canvas Julia set</a></li><li><a href="../examples/web-audio.html"><strong aria-hidden="true">1.15.</strong> web-sys: WebAudio</a></li><li><a href="../examples/webgl.html"><strong aria-hidden="true">1.16.</strong> web-sys: WebGL</a></li><li><a href="../examples/websockets.html"><strong aria-hidden="true">1.17.</strong> web-sys: WebSockets</a></li><li><a href="../examples/webrtc_datachannel.html"><strong aria-hidden="true">1.18.</strong> web-sys: WebRTC DataChannel</a></li><li><a href="../examples/request-animation-frame.html"><strong aria-hidden="true">1.19.</strong> web-sys: requestAnimationFrame</a></li><li><a href="../examples/paint.html"><strong aria-hidden="true">1.20.</strong> web-sys: A Simple Paint Program</a></li><li><a href="../examples/raytrace.html"><strong aria-hidden="true">1.21.</strong> Parallel Raytracing</a></li><li><a href="../examples/todomvc.html"><strong aria-hidden="true">1.22.</strong> web-sys: A TODO MVC App</a></li></ol></li><li><a href="../reference/index.html"><strong aria-hidden="true">2.</strong> Reference</a></li><li><ol class="section"><li><a href="../reference/deployment.html"><strong aria-hidden="true">2.1.</strong> Deployment</a></li><li><a href="../reference/js-snippets.html"><strong aria-hidden="true">2.2.</strong> JS snippets</a></li><li><a href="../reference/passing-rust-closures-to-js.html"><strong aria-hidden="true">2.3.</strong> Passing Rust Closures to JS</a></li><li><a href="../reference/receiving-js-closures-in-rust.html"><strong aria-hidden="true">2.4.</strong> Receiving JS Closures in Rust</a></li><li><a href="../reference/js-promises-and-rust-futures.html"><strong aria-hidden="true">2.5.</strong> Promises and Futures</a></li><li><a href="../reference/iterating-over-js-values.html"><strong aria-hidden="true">2.6.</strong> Iterating over JS Values</a></li><li><a href="../reference/arbitrary-data-with-serde.html" class="active"><strong aria-hidden="true">2.7.</strong> Arbitrary Data with Serde</a></li><li><a href="../reference/accessing-properties-of-untyped-js-values.html"><strong aria-hidden="true">2.8.</strong> Accessing Properties of Untyped JS Values</a></li><li><a href="../reference/working-with-duck-typed-interfaces.html"><strong aria-hidden="true">2.9.</strong> Working with Duck-Typed Interfaces</a></li><li><a href="../reference/cli.html"><strong aria-hidden="true">2.10.</strong> Command Line Interface</a></li><li><a href="../reference/optimize-size.html"><strong aria-hidden="true">2.11.</strong> Optimizing for Size</a></li><li><a href="../reference/rust-targets.html"><strong aria-hidden="true">2.12.</strong> Supported Rust Targets</a></li><li><a href="../reference/browser-support.html"><strong aria-hidden="true">2.13.</strong> Supported Browsers</a></li><li><a href="../reference/types.html"><strong aria-hidden="true">2.14.</strong> Supported Types</a></li><li><ol class="section"><li><a href="../reference/types/imported-js-types.html"><strong aria-hidden="true">2.14.1.</strong> Imported JavaScript Types</a></li><li><a href="../reference/types/exported-rust-types.html"><strong aria-hidden="true">2.14.2.</strong> Exported Rust Types</a></li><li><a href="../reference/types/jsvalue.html"><strong aria-hidden="true">2.14.3.</strong> JsValue</a></li><li><a href="../reference/types/boxed-jsvalue-slice.html"><strong aria-hidden="true">2.14.4.</strong> Box&lt;[JsValue]&gt;</a></li><li><a href="../reference/types/pointers.html"><strong aria-hidden="true">2.14.5.</strong> *const T and *mut T</a></li><li><a href="../reference/types/numbers.html"><strong aria-hidden="true">2.14.6.</strong> Numbers</a></li><li><a href="../reference/types/bool.html"><strong aria-hidden="true">2.14.7.</strong> bool</a></li><li><a href="../reference/types/char.html"><strong aria-hidden="true">2.14.8.</strong> char</a></li><li><a href="../reference/types/str.html"><strong aria-hidden="true">2.14.9.</strong> str</a></li><li><a href="../reference/types/string.html"><strong aria-hidden="true">2.14.10.</strong> String</a></li><li><a href="../reference/types/number-slices.html"><strong aria-hidden="true">2.14.11.</strong> Number Slices</a></li><li><a href="../reference/types/boxed-number-slices.html"><strong aria-hidden="true">2.14.12.</strong> Boxed Number Slices</a></li><li><a href="../reference/types/result.html"><strong aria-hidden="true">2.14.13.</strong> Result&lt;T, JsValue&gt;</a></li></ol></li><li><a href="../reference/attributes/index.html"><strong aria-hidden="true">2.15.</strong> #[wasm_bindgen] Attributes</a></li><li><ol class="section"><li><a href="../reference/attributes/on-js-imports/index.html"><strong aria-hidden="true">2.15.1.</strong> On JavaScript Imports</a></li><li><ol class="section"><li><a href="../reference/attributes/on-js-imports/catch.html"><strong aria-hidden="true">2.15.1.1.</strong> catch</a></li><li><a href="../reference/attributes/on-js-imports/constructor.html"><strong aria-hidden="true">2.15.1.2.</strong> constructor</a></li><li><a href="../reference/attributes/on-js-imports/extends.html"><strong aria-hidden="true">2.15.1.3.</strong> extends</a></li><li><a href="../reference/attributes/on-js-imports/getter-and-setter.html"><strong aria-hidden="true">2.15.1.4.</strong> getter and setter</a></li><li><a href="../reference/attributes/on-js-imports/final.html"><strong aria-hidden="true">2.15.1.5.</strong> final</a></li><li><a href="../reference/attributes/on-js-imports/indexing-getter-setter-deleter.html"><strong aria-hidden="true">2.15.1.6.</strong> indexing_getter, indexing_setter, and indexing_deleter</a></li><li><a href="../reference/attributes/on-js-imports/js_class.html"><strong aria-hidden="true">2.15.1.7.</strong> js_class = &quot;Blah&quot;</a></li><li><a href="../reference/attributes/on-js-imports/js_name.html"><strong aria-hidden="true">2.15.1.8.</strong> js_name</a></li><li><a href="../reference/attributes/on-js-imports/js_namespace.html"><strong aria-hidden="true">2.15.1.9.</strong> js_namespace</a></li><li><a href="../reference/attributes/on-js-imports/method.html"><strong aria-hidden="true">2.15.1.10.</strong> method</a></li><li><a href="../reference/attributes/on-js-imports/module.html"><strong aria-hidden="true">2.15.1.11.</strong> module = &quot;blah&quot;</a></li><li><a href="../reference/attributes/on-js-imports/raw_module.html"><strong aria-hidden="true">2.15.1.12.</strong> raw_module = &quot;blah&quot;</a></li><li><a href="../reference/attributes/on-js-imports/static_method_of.html"><strong aria-hidden="true">2.15.1.13.</strong> static_method_of = Blah</a></li><li><a href="../reference/attributes/on-js-imports/structural.html"><strong aria-hidden="true">2.15.1.14.</strong> structural</a></li><li><a href="../reference/attributes/on-js-imports/variadic.html"><strong aria-hidden="true">2.15.1.15.</strong> variadic</a></li><li><a href="../reference/attributes/on-js-imports/vendor_prefix.html"><strong aria-hidden="true">2.15.1.16.</strong> vendor_prefix</a></li></ol></li><li><a href="../reference/attributes/on-rust-exports/index.html"><strong aria-hidden="true">2.15.2.</strong> On Rust Exports</a></li><li><ol class="section"><li><a href="../reference/attributes/on-rust-exports/constructor.html"><strong aria-hidden="true">2.15.2.1.</strong> constructor</a></li><li><a href="../reference/attributes/on-rust-exports/js_name.html"><strong aria-hidden="true">2.15.2.2.</strong> js_name = Blah</a></li><li><a href="../reference/attributes/on-rust-exports/readonly.html"><strong aria-hidden="true">2.15.2.3.</strong> readonly</a></li><li><a href="../reference/attributes/on-rust-exports/skip.html"><strong aria-hidden="true">2.15.2.4.</strong> skip</a></li><li><a href="../reference/attributes/on-rust-exports/start.html"><strong aria-hidden="true">2.15.2.5.</strong> start</a></li><li><a href="../reference/attributes/on-rust-exports/typescript_custom_section.html"><strong aria-hidden="true">2.15.2.6.</strong> typescript_custom_section</a></li><li><a href="../reference/attributes/on-rust-exports/getter-and-setter.html"><strong aria-hidden="true">2.15.2.7.</strong> getter and setter</a></li><li><a href="../reference/attributes/on-rust-exports/inspectable.html"><strong aria-hidden="true">2.15.2.8.</strong> inspectable</a></li><li><a href="../reference/attributes/on-rust-exports/skip_typescript.html"><strong aria-hidden="true">2.15.2.9.</strong> skip_typescript</a></li><li><a href="../reference/attributes/on-rust-exports/typescript_type.html"><strong aria-hidden="true">2.15.2.10.</strong> typescript_type</a></li></ol></li></ol></li></ol></li><li><a href="../web-sys/index.html"><strong aria-hidden="true">3.</strong> web-sys</a></li><li><ol class="section"><li><a href="../web-sys/using-web-sys.html"><strong aria-hidden="true">3.1.</strong> Using web-sys</a></li><li><a href="../web-sys/cargo-features.html"><strong aria-hidden="true">3.2.</strong> Cargo Features</a></li><li><a href="../web-sys/function-overloads.html"><strong aria-hidden="true">3.3.</strong> Function Overloads</a></li><li><a href="../web-sys/type-translations.html"><strong aria-hidden="true">3.4.</strong> Type Translations</a></li><li><a href="../web-sys/inheritance.html"><strong aria-hidden="true">3.5.</strong> Inheritance</a></li><li><a href="../web-sys/unstable-apis.html"><strong aria-hidden="true">3.6.</strong> Unstable APIs</a></li></ol></li><li><a href="../wasm-bindgen-test/index.html"><strong aria-hidden="true">4.</strong> Testing with wasm-bindgen-test</a></li><li><ol class="section"><li><a href="../wasm-bindgen-test/usage.html"><strong aria-hidden="true">4.1.</strong> Usage</a></li><li><a href="../wasm-bindgen-test/asynchronous-tests.html"><strong aria-hidden="true">4.2.</strong> Writing Asynchronous Tests</a></li><li><a href="../wasm-bindgen-test/browsers.html"><strong aria-hidden="true">4.3.</strong> Testing in Headless Browsers</a></li><li><a href="../wasm-bindgen-test/continuous-integration.html"><strong aria-hidden="true">4.4.</strong> Continuous Integration</a></li></ol></li><li><a href="../contributing/index.html"><strong aria-hidden="true">5.</strong> Contributing to wasm-bindgen</a></li><li><ol class="section"><li><a href="../contributing/testing.html"><strong aria-hidden="true">5.1.</strong> Testing</a></li><li><a href="../contributing/design/index.html"><strong aria-hidden="true">5.2.</strong> Internal Design</a></li><li><ol class="section"><li><a href="../contributing/design/js-objects-in-rust.html"><strong aria-hidden="true">5.2.1.</strong> JS Objects in Rust</a></li><li><a href="../contributing/design/exporting-rust.html"><strong aria-hidden="true">5.2.2.</strong> Exporting a function to JS</a></li><li><a href="../contributing/design/exporting-rust-struct.html"><strong aria-hidden="true">5.2.3.</strong> Exporting a struct to JS</a></li><li><a href="../contributing/design/importing-js.html"><strong aria-hidden="true">5.2.4.</strong> Importing a function from JS</a></li><li><a href="../contributing/design/importing-js-struct.html"><strong aria-hidden="true">5.2.5.</strong> Importing a class from JS</a></li><li><a href="../contributing/design/rust-type-conversions.html"><strong aria-hidden="true">5.2.6.</strong> Rust Type conversions</a></li><li><a href="../contributing/design/describe.html"><strong aria-hidden="true">5.2.7.</strong> Types in wasm-bindgen</a></li></ol></li><li><a href="../contributing/js-sys/index.html"><strong aria-hidden="true">5.3.</strong> js-sys</a></li><li><ol class="section"><li><a href="../contributing/js-sys/testing.html"><strong aria-hidden="true">5.3.1.</strong> Testing</a></li><li><a href="../contributing/js-sys/adding-more-apis.html"><strong aria-hidden="true">5.3.2.</strong> Adding More APIs</a></li></ol></li><li><a href="../contributing/web-sys/index.html"><strong aria-hidden="true">5.4.</strong> web-sys</a></li><li><ol class="section"><li><a href="../contributing/web-sys/overview.html"><strong aria-hidden="true">5.4.1.</strong> Overview</a></li><li><a href="../contributing/web-sys/testing.html"><strong aria-hidden="true">5.4.2.</strong> Testing</a></li><li><a href="../contributing/web-sys/logging.html"><strong aria-hidden="true">5.4.3.</strong> Logging</a></li><li><a href="../contributing/web-sys/supporting-more-web-apis.html"><strong aria-hidden="true">5.4.4.</strong> Supporting More Web APIs</a></li></ol></li><li><a href="../contributing/publishing.html"><strong aria-hidden="true">5.5.</strong> Publishing</a></li><li><a href="../contributing/team.html"><strong aria-hidden="true">5.6.</strong> Team</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<style>
header.warning {
background-color: rgb(242, 222, 222);
border-bottom-color: rgb(238, 211, 215);
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-bottom-style: solid;
border-bottom-width: 0.666667px;
border-image-outset: 0 0 0 0;
border-image-repeat: stretch stretch;
border-image-slice: 100% 100% 100% 100%;
border-image-source: none;
border-image-width: 1 1 1 1;
border-left-color: rgb(238, 211, 215);
border-left-style: solid;
border-left-width: 0.666667px;
border-right-color: rgb(238, 211, 215);
border-right-style: solid;
border-right-width: 0.666667px;
border-top-color: rgb(238, 211, 215);
border-top-left-radius: 4px;
border-top-right-radius: 4px;
border-top-style: solid;
border-top-width: 0.666667px;
color: rgb(185, 74, 72);
margin-bottom: 0px;
margin-left: 0px;
margin-right: 0px;
margin-top: 30px;
padding-bottom: 8px;
padding-left: 14px;
padding-right: 35px;
padding-top: 8px;
text-align: center;
}
</style>
<header class='warning'>
This is the <strong>unpublished</strong> documentation of
<code>wasm-bindgen</code>, the published documentation is available
<a href="https://rustwasm.github.io/docs/wasm-bindgen/">
on the main Rust and WebAssembly documentation site
</a>. Features documented here may not be available in released versions of
<code>wasm-bindgen</code>.
</header>
<div id="menu-bar" class="menu-bar">
<div id="menu-bar-sticky-container">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">The `wasm-bindgen` Guide</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
</div>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" name="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1><a class="header" href="#serializing-and-deserializing-arbitrary-data-into-and-from-jsvalue-with-serde" id="serializing-and-deserializing-arbitrary-data-into-and-from-jsvalue-with-serde">Serializing and Deserializing Arbitrary Data Into and From <code>JsValue</code> with Serde</a></h1>
<p>It's possible to pass arbirtrary data from Rust to JavaScript by serializing it
to JSON with <a href="https://github.com/serde-rs/serde">Serde</a>. <code>wasm-bindgen</code> includes
the <code>JsValue</code> type, which streamlines serializing and deserializing.</p>
<h2><a class="header" href="#enable-the-serde-serialize-feature" id="enable-the-serde-serialize-feature">Enable the <code>&quot;serde-serialize&quot;</code> Feature</a></h2>
<p>To enable the <code>&quot;serde-serialize&quot;</code> feature, do two things in <code>Cargo.toml</code>:</p>
<ol>
<li>Add the <code>serde</code> and <code>serde_derive</code> crates to <code>[dependencies]</code>.</li>
<li>Add <code>features = [&quot;serde-serialize&quot;]</code> to the existing <code>wasm-bindgen</code>
dependency.</li>
</ol>
<pre><code class="language-toml">[dependencies]
serde = &quot;^1.0.59&quot;
serde_derive = &quot;^1.0.59&quot;
[dependencies.wasm-bindgen]
version = &quot;^0.2&quot;
features = [&quot;serde-serialize&quot;]
</code></pre>
<h2><a class="header" href="#import-serdes-custom-derive-macros" id="import-serdes-custom-derive-macros">Import Serde's Custom-Derive Macros</a></h2>
<p>In your top-level Rust file (e.g. <code>lib.rs</code> or <code>main.rs</code>), enable the <code>Serialize</code>
and <code>Deserialize</code> custom-derive macros:</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
#[macro_use]
extern crate serde_derive;
#}</code></pre></pre>
<h2><a class="header" href="#derive-the-serialize-and-deserialize-traits" id="derive-the-serialize-and-deserialize-traits">Derive the <code>Serialize</code> and <code>Deserialize</code> Traits</a></h2>
<p>Add <code>#[derive(Serialize, Deserialize)]</code> to your type. All of your type's
members must also be supported by Serde, i.e. their types must also implement
the <code>Serialize</code> and <code>Deserialize</code> traits.</p>
<p>For example, let's say we'd like to pass this <code>struct</code> to JavaScript; doing so
is not possible in <code>wasm-bindgen</code> normally due to the use of <code>HashMap</code>s, arrays,
and nested <code>Vec</code>s. None of those types are supported for sending across the wasm
ABI naively, but all of them implement Serde's <code>Serialize</code> and <code>Deserialize</code>.</p>
<p>Note that we do not need to use the <code>#[wasm_bindgen]</code> macro.</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
#[derive(Serialize)]
pub struct Example {
pub field1: HashMap&lt;u32, String&gt;,
pub field2: Vec&lt;Vec&lt;f32&gt;&gt;,
pub field3: [f32; 4],
}
#}</code></pre></pre>
<h2><a class="header" href="#send-it-to-javascript-with-jsvaluefrom_serde" id="send-it-to-javascript-with-jsvaluefrom_serde">Send it to JavaScript with <code>JsValue::from_serde</code></a></h2>
<p>Here's a function that will pass an <code>Example</code> to JavaScript by serializing it to
<code>JsValue</code>:</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
#[wasm_bindgen]
pub fn send_example_to_js() -&gt; JsValue {
let mut field1 = HashMap::new();
field1.insert(0, String::from(&quot;ex&quot;));
let example = Example {
field1,
field2: vec![vec![1., 2.], vec![3., 4.]],
field3: [1., 2., 3., 4.]
};
JsValue::from_serde(&amp;example).unwrap()
}
#}</code></pre></pre>
<h2><a class="header" href="#receive-it-from-javascript-with-jsvalueinto_serde" id="receive-it-from-javascript-with-jsvalueinto_serde">Receive it from JavaScript with <code>JsValue::into_serde</code></a></h2>
<p>Here's a function that will receive a <code>JsValue</code> parameter from JavaScript and
then deserialize an <code>Example</code> from it:</p>
<pre><pre class="playpen"><code class="language-rust">
# #![allow(unused_variables)]
#fn main() {
#[wasm_bindgen]
pub fn receive_example_from_js(val: &amp;JsValue) {
let example: Example = val.into_serde().unwrap();
...
}
#}</code></pre></pre>
<h2><a class="header" href="#javascript-usage" id="javascript-usage">JavaScript Usage</a></h2>
<p>In the <code>JsValue</code> that JavaScript gets, <code>field1</code> will be an <code>Object</code> (not a
JavaScript <code>Map</code>), <code>field2</code> will be a JavaScript <code>Array</code> whose members are
<code>Array</code>s of numbers, and <code>field3</code> will be an <code>Array</code> of numbers.</p>
<pre><code class="language-js">import { send_example_to_js, receive_example_from_js } from &quot;example&quot;;
// Get the example object from wasm.
let example = send_example_to_js();
// Add another &quot;Vec&quot; element to the end of the &quot;Vec&lt;Vec&lt;f32&gt;&gt;&quot;
example.field2.push([5,6]);
// Send the example object back to wasm.
receive_example_from_js(example);
</code></pre>
<h2><a class="header" href="#an-alternative-approach-serde-wasm-bindgen" id="an-alternative-approach-serde-wasm-bindgen">An Alternative Approach: <code>serde-wasm-bindgen</code></a></h2>
<p><a href="https://github.com/cloudflare/serde-wasm-bindgen">The <code>serde-wasm-bindgen</code>
crate</a> serializes and
deserializes Rust structures directly to <code>JsValue</code>s, without going through
temporary JSON stringification. This approach has both advantages and
disadvantages.</p>
<p>The primary advantage is smaller code size: going through JSON entrenches code
to stringify and parse floating point numbers, which is not a small amount of
code. It also supports more types than JSON does, such as <code>Map</code>, <code>Set</code>, and
array buffers.</p>
<p>There are two primary disadvantages. The first is that it is not always
compatible with the default JSON-based serialization. The second is that it
performs more calls back and forth between JS and Wasm, which has not been fully
optimized in all engines, meaning it can sometimes be a speed
regression. However, in other cases, it is a speed up over the JSON-based
stringification, so — as always — make sure to profile your own use
cases as necessary.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../reference/iterating-over-js-values.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../reference/accessing-properties-of-untyped-js-values.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a href="../reference/iterating-over-js-values.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a href="../reference/accessing-properties-of-untyped-js-values.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>