• Stars
    star
    438
  • Rank 99,453 (Top 2 %)
  • Language
    Rust
  • Created over 5 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Native integration of Serde with wasm-bindgen

This is a native integration of Serde with wasm-bindgen. It allows to convert Rust data types into native JavaScript types and vice versa.

Initially this library was created as an alternative implementation to the JSON-based Serde support built into the wasm-bindgen but, as of recently serde-wasm-bindgen is the officially preferred approach. It provides much smaller code size overhead than JSON, and, in most common cases, provides much faster serialization/deserialization as well.

Usage

Copied almost verbatim from the wasm-bindgen guide:

Add dependencies

To use serde-wasm-bindgen, you first have to add it as a dependency in your Cargo.toml. You also need the serde crate, with the derive feature enabled, to allow your types to be serialized and deserialized with Serde.

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde-wasm-bindgen = "0.4"

Derive the Serialize and Deserialize Traits

Add #[derive(Serialize, Deserialize)] to your type. All of your type members must also be supported by Serde, i.e. their types must also implement the Serialize and Deserialize traits.

Note that you don't need to use the #[wasm_bindgen] macro.

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
pub struct Example {
    pub field1: HashMap<u32, String>,
    pub field2: Vec<Vec<f32>>,
    pub field3: [f32; 4],
}

Send it to JavaScript with serde_wasm_bindgen::to_value

#[wasm_bindgen]
pub fn send_example_to_js() -> Result<JsValue, JsValue> {
    let mut field1 = HashMap::new();
    field1.insert(0, String::from("ex"));

    let example = Example {
        field1,
        field2: vec![vec![1., 2.], vec![3., 4.]],
        field3: [1., 2., 3., 4.]
    };

    Ok(serde_wasm_bindgen::to_value(&example)?)
}

Receive it from JavaScript with serde_wasm_bindgen::from_value

#[wasm_bindgen]
pub fn receive_example_from_js(val: JsValue) -> Result<(), JsValue> {
    let example: Example = serde_wasm_bindgen::from_value(val)?;
    /* …do something with `example`… */
    Ok(())
}

JavaScript Usage

In the JsValue that JavaScript gets, field1 will be a Map<number, string>, field2 will be an Array<Array<number>>, and field3 will be an Array<number>.

import { send_example_to_js, receive_example_from_js } from "example";

// Get the example object from wasm.
let example = send_example_to_js();

// Add another "Vec" element to the end of the "Vec<Vec<f32>>"
example.field2.push([5, 6]);

// Send the example object back to wasm.
receive_example_from_js(example);

Supported Types

Note that, even though it might often be the case, by default this library doesn't attempt to be strictly compatible with JSON, instead prioritising better compatibility with common JavaScript idioms and representations.

If you need JSON compatibility (e.g. you want to serialize HashMap<String, …> as plain objects instead of JavaScript Map instances), use the Serializer::json_compatible() preset.

By default, Rust ⬄ JavaScript conversions in serde-wasm-bindgen follow this table:

Rust JavaScript Also supported in from_value
() and Option<T>::None undefined null
bool boolean
f32, f64 number
u8, i8, …, u32, i32 number in the safe integer range
u64, i64, usize, isize number in the safe integer range bigint
u128, i128 bigint
String string
char single-codepoint string
Enum::Variant { … } as configured in Serde
HashMap<K, V>, BTreeMap, etc. Map<K, V> any iterable over [K, V]
Struct { key1: value1, … } { key1: value1, … } object
tuple, Vec<T>, HashSet, etc. T[] array any iterable over T
serde_bytes byte buffer Uint8Array ArrayBuffer, Array

The first two columns show idiomatic representations on Rust and JavaScript sides, while the 3rd column shows which JavaScript values are additionally supported when deserializing from JavaScript to the Rust type.

Serializer configuration options

You can customize serialization from Rust to JavaScript by setting the following options on the Serializer::new() instance (all default to false):

  • .serialize_missing_as_null(true): Serialize (), unit structs and Option::None to null instead of undefined.
  • .serialize_maps_as_objects(true): Serialize maps into plain JavaScript objects instead of ES2015 Maps.
  • .serialize_large_number_types_as_bigints(true): Serialize u64, i64, usize and isize to bigints instead of attempting to fit them into the safe integer number or failing.
  • .serialize_bytes_as_arrays(true): Serialize bytes into plain JavaScript arrays instead of ES2015 Uint8Arrays.

You can also use the Serializer::json_compatible() preset to create a JSON compatible serializer. It enables serialize_missing_as_null, serialize_maps_as_objects, and serialize_bytes_as_arrays under the hood.

License

Licensed under the MIT license. See the LICENSE file for details.

More Repositories

1

mpegts

Javascript HTTP Live Streaming realtime converter and player
JavaScript
840
star
2

WiFi-Password

People ask you for the Wi-Fi password. Answer quickly.
PowerShell
574
star
3

serde-xml-rs

xml-rs based deserializer for Serde (compatible with 1.0+)
Rust
250
star
4

better-log

console.log wrapper for a bit more readable output in Node.js
JavaScript
206
star
5

cow-utils-rs

Copy-on-write string utilities for Rust
Rust
148
star
6

github-editorconfig

Browser extension that provides EditorConfig support for GitHub
JavaScript
128
star
7

xmatch

Simple pattern matching for ES6
JavaScript
104
star
8

babel-plugin-asm-js

Compile JavaScript + Flow into asm.js (WIP)
JavaScript
66
star
9

babel-plugin-uglify

UglifyJS integration for Babel
JavaScript
47
star
10

pure-cjs

Pure minimalistic CommonJS builder
JavaScript
44
star
11

babel-plugin-hello-world

Extended plugin sample for Babel
JavaScript
44
star
12

tasks.js

Convenient task scheduler for JavaScript using Web Workers.
JavaScript
33
star
13

stack-displayname

Show custom function names in error stack traces of V8 (Node.js)
JavaScript
32
star
14

serialize-js

Object serialization for JavaScript - readable & JS-compatible
JavaScript
29
star
15

gh2ost

Convert Github readmes into Ghost blog posts
JavaScript
25
star
16

jsx-transpiler

Parses and compiles JSX code to JavaScript AST or code.
JavaScript
23
star
17

gulp-wrap-js

Gulp plugin for templating JavaScript code with source maps support.
JavaScript
20
star
18

typescript-estree

TypeScript => ESTree AST converter (WIP)
JavaScript
20
star
19

serdebug

Serde-based replacement for #[derive(Debug)]
Rust
19
star
20

when-traverse

Asynchronously traverse tree of mixed promises and values
JavaScript
19
star
21

estraverse-fb

Drop-in for estraverse that enables traversal over React's JSX nodes.
JavaScript
17
star
22

compile2js

Bootstrap package for easier creating compilers to JavaScript
JavaScript
12
star
23

vscode-llvm

LLVM syntax highlight extension for VS Code
12
star
24

astexplorer-syn

Rust
11
star
25

asmjs-experiments

Nothing to see here, just playing with asm.js
Rust
10
star
26

esmod

Fast in-place import/export transpiler
JavaScript
10
star
27

jBinary.Hex

Hex viewer based on jBinary
JavaScript
10
star
28

hubot-skype4com

.NET Skype adapter for Hubot under Windows
C#
9
star
29

esmozy

Rust
8
star
30

derex

Derivatives-based regexp to DFA compiler
TypeScript
7
star
31

buffer-utf8-length

Fastest implementation of counting UTF-8 byte sequences in a Buffer
JavaScript
7
star
32

es-borrowed-props

Borrowed Properties Proposal for ES7
7
star
33

serde-ndim

Serde support for n-dimensional arrays from self-describing formats
Rust
6
star
34

libwebp2

C++
6
star
35

wasm-stats

Rust
6
star
36

emnapi

[WIP] N-API implementation for Emscripten
C
5
star
37

eos-remote-web

Web Bluetooth remote for Canon EOS cameras
HTML
5
star
38

proxyfill

ES6 Proxy + Reflect polyfill with limited surface
JavaScript
4
star
39

uwp-chrome

Experimental chrome API shim for Universal Windows Platform (UWP / WinRT)
TypeScript
4
star
40

010-editor-templates

Personal templates (binary format descriptions) for 010 Editor.
4
star
41

ascom-alpaca-rs

Cross-platform Rust library for the ASCOM Alpaca API for astronomy devices
Rust
4
star
42

PingPong

PingPong in browser with Augmented Reality
JavaScript
3
star
43

gpgpu

Just playing with code I found on internet
JavaScript
3
star
44

ws-proxy

Simple WebSocket reverse proxy for debugging purposes
JavaScript
3
star
45

TSX

Child of TypeScript and JSX [WIP]
JavaScript
3
star
46

winremote

HTML5+Node.js remote desktop for Windows (FB Hackathon 2012)
JavaScript
2
star
47

grunt-pure-cjs

Grunt plugin for Pure CommonJS builder
JavaScript
2
star
48

acorn-csp

Builder for Acorn that precompiles predicates in order to satisfy CSP.
JavaScript
2
star
49

ragel

Ragel State Machine Compiler
C++
2
star
50

lutz

Rust
2
star
51

parallel-demo

Demo for my talk about parallelization
JavaScript
2
star
52

biscript

010 Editor's binary scripts on top of JavaScrpit
JavaScript
2
star
53

override-hosts

Small shared library utility to temporarily override list of hosts to specific target
C
2
star
54

JSPiano

Piano simulator written using only JavaScript (Mozilla Audio Data API) and some math knowledge :)
JavaScript
2
star
55

OdessaJS-2014

Code sample from OdessaJS-2014 workshop.
JavaScript
2
star
56

js-ragel

Playing with implementing JS lexer in Ragel
Ragel in Ruby Host
1
star
57

bt-parser

JS Parser for 010 Editor Binary Templates
JavaScript
1
star
58

RReverser

1
star
59

ada-wbg

Rust
1
star
60

BMPImage

HTML5 File API and XMLHttpRequest2 based BMP image parser and renderer
JavaScript
1
star
61

odessajs-2016

Presentation for Odessa.js (2016)
JavaScript
1
star
62

cfg

TypeScript
1
star
63

AndroidMouse

Using Android device compass and gyroscope for manipulating computer's mouse (client + server).
C#
1
star
64

SharpScript

Course work - proof-of-concept of C# <script /> executor that runs in context of built-in browser and can communicate with JavaScript on the same page.
C#
1
star
65

apartjs

Apart is a library for easy parallelism in JavaScript. It's name can be treated as "executing block *apart* from the main thread" as well as shortening for words "asynchronous part - APart".
JavaScript
1
star