diff --git a/support/sier-codec-js/Cargo.toml b/support/sier-codec-js/Cargo.toml new file mode 100644 index 00000000..d943e601 --- /dev/null +++ b/support/sier-codec-js/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "sier-codec-js" +version = "0.1.0" +authors = ["Antoni Dikov ; + corge :Corge; +}`; + +const FOO = +{ + "bar": 42, + "baz": "abc", + "qux": [4, 2], + "corge": { + "gz": 42, + "op": true + } +}; +console.log(FOO); + +let sier = pkg.serialize(FOO, JSON_STRUCT_DEF, "Foo"); +console.log(sier); +let json = pkg.deserialize(sier, JSON_STRUCT_DEF); +console.log(json); diff --git a/support/sier-codec-js/js-test/package.json b/support/sier-codec-js/js-test/package.json new file mode 100644 index 00000000..56d8e5f1 --- /dev/null +++ b/support/sier-codec-js/js-test/package.json @@ -0,0 +1,8 @@ +{ + "name": "sier-codec-js-test", + "version": "1.0.0", + "main": "index.js", + "author": "Antoni Dikov", + "license": "MIT", + "type": "module" + } diff --git a/support/sier-codec-js/src/lib.rs b/support/sier-codec-js/src/lib.rs new file mode 100644 index 00000000..f39f14af --- /dev/null +++ b/support/sier-codec-js/src/lib.rs @@ -0,0 +1,60 @@ +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(&e.to_string()); + }); + + let def = parser.struct_def(struct_def).unwrap_or_else(|| { + wasm_bindgen::throw_str( + &format!( + "Could not find struct {0} in provided definitions.", + struct_def + ), + ); + }); + + let obj = parser.json_str(json.as_str(), def).unwrap_or_else(|e| { + wasm_bindgen::throw_str(&e.to_string()); + }); + + 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)); + }); + + let obj = parser.parse(&sier.to_vec()).unwrap_or_else(|e| { + wasm_bindgen::throw_str(&format!("Parse failed - {0}", e)); + }); + + let json = sier_codec::json::transform_sier_obj(&obj).unwrap_or_else(|e| { + wasm_bindgen::throw_str(&format!("Transforming sier object failed - {0}", e)); + }); + + JsValue::from_serde(&json).unwrap_or_else(|e| { + wasm_bindgen::throw_str(&format!( + "Serde Value to Wasm JsValue parsing failed - {0}", + e + )); + }) +} diff --git a/support/sier-codec-js/tests/web.rs b/support/sier-codec-js/tests/web.rs new file mode 100644 index 00000000..6dca226b --- /dev/null +++ b/support/sier-codec-js/tests/web.rs @@ -0,0 +1,64 @@ +//! 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; + 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, 42, 0, 0, 0, 0, 0, 0, 0, 1 + ] + ); +} diff --git a/support/sier-codec/src/object.rs b/support/sier-codec/src/object.rs index 618616de..ad0e583c 100644 --- a/support/sier-codec/src/object.rs +++ b/support/sier-codec/src/object.rs @@ -23,6 +23,7 @@ impl<'s> Object<'s> { result.extend(self.serialize_as_child()); result } + fn serialize_as_child(&self) -> Vec { let mut result = Vec::new(); for value in &self.values { @@ -185,7 +186,6 @@ impl<'s> Value<'s> { .chain(item_bytes) .collect() } - Value::Struct(obj) => obj.serialize_as_child(), } }