Rust Wasm 格式化 JSON

2 minute read Published: 2022-03-11

本文代码

查看效果

依赖工具

cargo install wasm-pack

Cargo.toml

[package]
name = "wasm-bindgen-record"
version = "0.1.0"
authors = ["Li Lei <this.lilei@gmail.com>"]
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
anyhow = "1.0.56"
wasm-bindgen = "0.2.79"
serde_json = "1.0.79"

src/lib.rs

use anyhow::Result;
use serde_json::{from_str, to_string, to_string_pretty, Value};
use wasm_bindgen::prelude::wasm_bindgen;

#[wasm_bindgen]
extern "C" {
    fn alert(s: &str);

    #[wasm_bindgen(js_namespace = console)]
    fn log(s: &str);
}

#[wasm_bindgen]
pub fn expand(s: &str) -> String {
    expand_json(s).unwrap()
}

#[wasm_bindgen]
pub fn collapse(s: &str) -> String {
    collapse_json(s).unwrap()
}

fn expand_json(s: &str) -> Result<String> {
    Ok(to_string_pretty(&from_str::<Value>(s)?)?)
}

fn collapse_json(s: &str) -> Result<String> {
    Ok(to_string(&from_str::<Value>(s)?)?)
}

#[wasm_bindgen(start)]
pub fn start() {
    log("Wasm");
}

#[test]
fn test() -> Result<()> {
    const COLLAPSE: &str = r#"{"key":"value"}"#;
    const EXPAND: &str = r#"{
  "key": "value"
}"#;
    assert_eq!(expand_json(COLLAPSE)?, EXPAND);
    assert_eq!(collapse_json(EXPAND)?, COLLAPSE);
    Ok(())
}

index.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <title>Wasm</title>
    <style>
        html, body {
            height: 100%;
        }

        textarea {
            width: 100%;
            height: 50%;
        }

        button {
            font-size: 2rem;
        }
    </style>
</head>
<body>
<label>
    <textarea id="text">{"key":"value"}</textarea>
</label>
<button id="expand">expand</button>
<button id="collapse">collapse</button>
<script type="module">
    import init, {expand, collapse} from './pkg/wasm_bindgen_record.js'

    const expandButton = document.getElementById('expand')
    const collapseButton = document.getElementById('collapse')
    const text = document.getElementById('text')

    init().then(() => {
        expandButton.onclick = () => text.value = expand(text.value)
        collapseButton.onclick = () => text.value = collapse(text.value)
    })
</script>
</body>
</html>

发布至浏览器

wasm-pack build --release --target web