#serialization #serde

serde-wasm-bindgen

针对wasm-bindgen的原生Serde适配器

19个版本

0.6.5 2024年2月27日
0.6.3 2023年12月10日
0.6.1 2023年10月25日
0.5.0 2023年3月6日
0.1.3 2019年5月16日

#1 in WebAssembly

Download history 152072/week @ 2024-05-01 135834/week @ 2024-05-08 163991/week @ 2024-05-15 174104/week @ 2024-05-22 214710/week @ 2024-05-29 249898/week @ 2024-06-05 244004/week @ 2024-06-12 223306/week @ 2024-06-19 261437/week @ 2024-06-26 214935/week @ 2024-07-03 265732/week @ 2024-07-10 276082/week @ 2024-07-17 248456/week @ 2024-07-24 272951/week @ 2024-07-31 270969/week @ 2024-08-07 180619/week @ 2024-08-14

1,028,475 每月下载量
用于 923 个Crate (299个直接使用)

MIT 许可证

60KB
1K SLoC

Crates.io docs.rs GitHub Sponsors

这是Serde与wasm-bindgen的本地集成。它允许将Rust数据类型转换为原生JavaScript类型,反之亦然。

最初,这个库是在为@Cloudflare工作期间作为JSON基于Serde支持的替代实现时创建的,但现在serde-wasm-bindgen是官方推荐的方法。它比JSON提供更小的代码大小开销,并且在大多数常见情况下,还提供了更快的序列化和反序列化速度。

使用方法

几乎直接从wasm-bindgen指南复制

添加依赖项

要使用serde-wasm-bindgen,您首先需要在您的Cargo.toml中将其添加为依赖项。您还需要具有serdecrate,并启用derive功能,以便使用Serde对您的类型进行序列化和反序列化。

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

派生SerializeDeserialize特质

#[derive(Serialize, Deserialize)]添加到您的类型中。您的类型成员也必须由Serde支持,即它们的类型也必须实现SerializeDeserialize特质。

请注意,您不需要使用#[wasm_bindgen]宏。

use serde::{Serialize, Deserialize};

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

使用serde_wasm_bindgen::to_value将其发送到JavaScript

#[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)?)
}

通过 JavaScript 使用 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 使用方法

在 JavaScript 获取的 JsValue 中,field1 将是一个 Map<number, string>field2 将是一个 Array<Array<number>>,而 field3 将是一个 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);

支持的类型

注意,尽管这通常是情况,但默认情况下,该库并不尝试严格兼容 JSON,而是优先考虑与常见的 JavaScript 习惯用法和表示的更好兼容性。

如果您需要 JSON 兼容性(例如,您希望将 HashMap<String, > 序列化为普通对象而不是 JavaScript Map 实例),请使用 Serializer::json_compatible() 预设。

默认情况下,serde-wasm-bindgen 中的 Rust ⬄ JavaScript 转换遵循以下表格

Rust JavaScript 也支持在 from_value
()Option<T>::None undefined null
bool boolean
f32, f64 number
u8, i8,……,u32, i32 number安全整数 范围内
u64, i64, usize, isize number安全整数 范围内 bigint
u128, i128 bigint
String string
char 单码点 string
Enum::Variant{……} 如 Serde 中配置
HashMap<K, V>BTreeMap 等。 Map<K, V> 任何可迭代的 [K, V]
Struct{key1:value1,……} { key1: value1,} 对象
元组,Vec<T>HashSet 等。 T[] 数组 任何可迭代的 T
serde_bytes 字节缓冲区 Uint8Array ArrayBufferArray

前两列显示了Rust和JavaScript两边的惯用表示,而第三列显示了在从JavaScript反序列化为Rust类型时,哪些JavaScript值被额外支持。

序列化配置选项

您可以通过设置Serializer::new()实例(所有默认为false)来自定义从Rust到JavaScript的序列化。

  • .serialize_missing_as_null(true):将空结构体和Option::None序列化为null,而不是undefined
  • .serialize_maps_as_objects(true):将映射序列化为普通的JavaScript对象,而不是ES2015映射。
  • .serialize_large_number_types_as_bigints(true):将u64i64usizeisize序列化为bigint,而不是尝试将它们放入安全整数 number或失败。
  • .serialize_bytes_as_arrays(true):将字节序列化为普通的JavaScript数组,而不是ES2015 Uint8Arrays。

您还可以使用Serializer::json_compatible()预设来创建一个兼容JSON的序列化器。它底层启用了serialize_missing_as_nullserialize_maps_as_objectsserialize_bytes_as_arrays

保留JavaScript值

有时您想要保留原始JavaScript值而不是将其转换为Rust类型。这对于无法不丢失数据而转换的类型特别有用,例如DateRegExp或第三方类型。

serde_wasm_bindgen::preserve允许您做到这一点

#[derive(Serialize, Deserialize)]
pub struct Example {
    pub regular_field: i32,

    #[serde(with = "serde_wasm_bindgen::preserve")]
    pub preserved_date: js_sys::Date,

    #[serde(with = "serde_wasm_bindgen::preserve")]
    pub preserved_arbitrary_value: JsValue,
}

TypeScript支持

该crate没有内置的类型生成,但您可以使用带有js功能的tsify来与serde-wasm-bindgen集成。除了生成结构化类型定义外,它还允许您推导出IntoWasmAbi / FromWasmAbi,这样您就不必手动编写from_value / to_value

许可证

在MIT许可证下发布。有关详细信息,请参阅LICENSE文件。

依赖关系

~1–1.9MB
~36K SLoC