Skip to content
This repository has been archived by the owner on Jan 11, 2024. It is now read-only.

Commit

Permalink
Sier codec wasm binding.
Browse files Browse the repository at this point in the history
  • Loading branch information
melatron committed Apr 7, 2022
1 parent 9dc607b commit 0dafc81
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 0 deletions.
18 changes: 18 additions & 0 deletions support/sier-codec-js/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "sier-codec-js"
version = "0.1.0"
authors = ["Antoni Dikov <[email protected]"]
edition = "2021"

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

[dependencies]
wasm-bindgen = { version = "0.2.79", features = ["serde-serialize"] }

sier-codec = { path="../sier-codec" }
serde_json = "1.0.79"
js-sys = "0.3.56"

[dev-dependencies]
wasm-bindgen-test = "0.3.29"
32 changes: 32 additions & 0 deletions support/sier-codec-js/js-test/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//TODO(melatron): Remove js-test folder
import pkg from '../pkg/sier_codec_js.js';

const JSON_STRUCT_DEF = `
struct Corge {
gz :u64;
op :bool;
}
struct Foo {
bar :u64;
baz :string;
qux :List<u64>;
corge :Corge;
}`;

const FOO =
{
"bar": 42,
"baz": "abc",
"qux": [4, 2],
"corge": {
"gz": 42,
"op": true
}
};
console.log(FOO);

let sier = pkg.serialize(JSON.stringify(FOO), JSON_STRUCT_DEF, "Foo");
console.log(sier);
let json = pkg.deserialize(sier, JSON_STRUCT_DEF);
console.log(json);
8 changes: 8 additions & 0 deletions support/sier-codec-js/js-test/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "sier-codec-js-test",
"version": "1.0.0",
"main": "index.js",
"author": "Antoni Dikov",
"license": "MIT",
"type": "module"
}
54 changes: 54 additions & 0 deletions support/sier-codec-js/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use sier_codec::Parser;
use wasm_bindgen::prelude::*;
//TODO(melatron): Create a JS Class that holds the file_defs inside and
// serialize/deserialize are methods of this class.
#[wasm_bindgen]
pub fn serialize(js_object: JsValue, file_defs: &str, struct_def: &str) -> js_sys::Uint8Array {
if !js_object.is_object() {
wasm_bindgen::throw_str("Provided argument is not a JS Object.");
}

let json = js_sys::JSON::stringify(&js_object).unwrap_or_else(|e| {
wasm_bindgen::throw_val(e);
});
let json = json
.as_string()
.expect("Parsed as string from JSON::stringify");

let mut parser = Parser::default();
parser.add_file_defs(file_defs).unwrap_or_else(|e| {
wasm_bindgen::throw_str(format!("Wrong file definitions provided {0}", e).as_str());
});

let def = parser.struct_def(struct_def).unwrap_or_else(|| {
wasm_bindgen::throw_str("Wrong struct_def provided");
});

let obj = parser.json_str(json.as_str(), def).unwrap_or_else(|e| {
wasm_bindgen::throw_str(format!("Wrong JSON provided - {0}", e).as_str());
});

js_sys::Uint8Array::from(&obj.serialize()[..])
}

#[wasm_bindgen]
pub fn deserialize(sier: js_sys::Uint8Array, file_defs: &str) -> JsValue {
let mut parser = Parser::default();
parser.add_file_defs(file_defs).unwrap_or_else(|e| {
wasm_bindgen::throw_str(format!("Wrong file definitions provided {0}", e).as_str());
});

let obj = parser.parse(&sier.to_vec()).unwrap_or_else(|e| {
wasm_bindgen::throw_str(format!("Parse failed - {0}", e).as_str());
});

let json = sier_codec::json::transform_sier_obj(&obj).unwrap_or_else(|e| {
wasm_bindgen::throw_str(format!("Transforming sier object failed - {0}", e).as_str());
});

JsValue::from_serde(&json).unwrap_or_else(|e| {
wasm_bindgen::throw_str(
format!("Serde Value to Wasm JsValue parsing failed - {0}", e).as_str(),
);
})
}
65 changes: 65 additions & 0 deletions support/sier-codec-js/tests/web.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//! Test suite for the Web and headless browsers.
#![cfg(target_arch = "wasm32")]

extern crate wasm_bindgen_test;
use wasm_bindgen_test::*;

use wasm_bindgen::prelude::*;

use sier_codec_js;

const JSON_STRUCT_DEF: &'static str = r#"
struct Corge {
gz :u64;
op :bool;
}
struct Foo {
bar :u64;
baz :string;
qux :List<u64>;
corge :Corge;
}
"#;

const JSON: &'static str = r#"
{
"bar": 42,
"baz": "abc",
"qux": [4, 2],
"corge": {
"gz": 42,
"op": true
}
}
"#;

#[wasm_bindgen_test]
fn deserialize() {
let json = js_sys::JSON::parse(JSON).unwrap();
let sier = sier_codec_js::serialize(json, JSON_STRUCT_DEF, "Foo");
let deserialized_json = sier_codec_js::deserialize(sier, JSON_STRUCT_DEF);
let str_json = js_sys::JSON::stringify(&deserialized_json).unwrap();
let left: String = str_json.into();

assert_eq!(
left,
"{\"bar\":42,\"baz\":\"abc\",\"corge\":{\"gz\":42,\"op\":true},\"qux\":[4,2]}"
);
}

#[wasm_bindgen_test]
fn serialize() {
let json = js_sys::JSON::parse(JSON).unwrap();
let sier = sier_codec_js::serialize(json, JSON_STRUCT_DEF, "Foo");

assert_eq!(
sier.to_vec(),
vec![
206, 206, 22, 230, 245, 223, 67, 43, 42, 0, 0, 0, 0, 0, 0, 0, 3, 97, 98, 99, 16, 4, 0,
0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 115, 196, 212, 210, 235, 7, 68, 87, 42, 0, 0,
0, 0, 0, 0, 0, 1
]
);
}

0 comments on commit 0dafc81

Please sign in to comment.