Webassembly 기본

This commit is contained in:
freestrings
2019-03-03 00:33:27 +09:00
parent 7bf3bb59b0
commit 9c0d2f8689
41 changed files with 5949 additions and 38 deletions

View File

@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="filter_all" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package rs-jsonpath --lib jsonpath::json_filter::tests" />
<option name="command" value="test --package jsonpath --lib jsonpath::json_filter::tests" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="true" />
<option name="backtrace" value="NO" />

View File

@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="filter_array - trace" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package rs-jsonpath --lib jsonpath::json_filter::tests::array -- --exact" />
<option name="command" value="test --package jsonpath --lib jsonpath::json_filter::tests::array -- --exact" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="true" />
<option name="backtrace" value="NO" />

View File

@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="filter_example- trace" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package rs-jsonpath --lib jsonpath::json_filter::tests::example -- --exact" />
<option name="command" value="test --package jsonpath --lib jsonpath::json_filter::tests::example -- --exact" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="true" />
<option name="backtrace" value="NO" />

View File

@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="filter_op - trace" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package rs-jsonpath --lib jsonpath::json_filter::tests::op -- --exact" />
<option name="command" value="test --package jsonpath --lib jsonpath::json_filter::tests::op -- --exact" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="true" />
<option name="backtrace" value="NO" />

View File

@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="filter_return_type - trace" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package rs-jsonpath --lib jsonpath::json_filter::tests::return_type -- --exact" />
<option name="command" value="test --package jsonpath --lib jsonpath::json_filter::tests::return_type -- --exact" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="true" />
<option name="backtrace" value="NO" />

View File

@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="filter_step_in- trace" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package rs-jsonpath --lib jsonpath::json_filter::tests::step_in -- --exact" />
<option name="command" value="test --package jsonpath --lib jsonpath::json_filter::tests::step_in -- --exact" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="true" />
<option name="backtrace" value="NO" />

View File

@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="parse_array" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package rs-jsonpath --lib jsonpath::parser::tests::parse_array -- --exact" />
<option name="command" value="test --package jsonpath --lib jsonpath::parser::tests::parse_array -- --exact" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="true" />
<option name="backtrace" value="NO" />

View File

@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="parse_array - trace" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package rs-jsonpath --lib jsonpath::parser::tests::parse_array -- --exact" />
<option name="command" value="test --package jsonpath --lib jsonpath::parser::tests::parse_array -- --exact" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="true" />
<option name="backtrace" value="NO" />

View File

@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="parse_array_float" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package rs-jsonpath --lib jsonpath::parser::tests::parse_array_float -- --exact" />
<option name="command" value="test --package jsonpath --lib jsonpath::parser::tests::parse_array_float -- --exact" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="true" />
<option name="backtrace" value="NO" />

View File

@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="parse_array_float - trace" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package rs-jsonpath --lib jsonpath::parser::tests::parse_array_float -- --exact" />
<option name="command" value="test --package jsonpath --lib jsonpath::parser::tests::parse_array_float -- --exact" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="true" />
<option name="backtrace" value="NO" />

View File

@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="parse_path" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package rs-jsonpath --lib jsonpath::parser::tests::parse_path -- --exact" />
<option name="command" value="test --package jsonpath --lib jsonpath::parser::tests::parse_path -- --exact" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="true" />
<option name="backtrace" value="NO" />

View File

@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="parse_path - trace" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package rs-jsonpath --lib jsonpath::parser::tests::parse_path -- --exact" />
<option name="command" value="test --package jsonpath --lib jsonpath::parser::tests::parse_path -- --exact" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="true" />
<option name="backtrace" value="NO" />

View File

@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="parser_all" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package rs-jsonpath --lib jsonpath::parser::tests" />
<option name="command" value="test --package jsonpath --lib jsonpath::parser::tests" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="true" />
<option name="backtrace" value="NO" />

View File

@ -1,5 +1,5 @@
[package]
name = "rs-jsonpath"
name = "jsonpath"
version = "0.1.0"
authors = ["freestrings <freestrings@gmail.com>"]

View File

@ -3,6 +3,8 @@ mod term;
pub mod value_filter;
mod value_wrapper;
use super::parser::*;
#[cfg(test)]
mod tests {
extern crate env_logger;
@ -10,7 +12,7 @@ mod tests {
use std::io::Read;
use std::sync::{Once, ONCE_INIT};
use jsonpath::parser::Parser;
use super::parser::Parser;
use serde_json::Value;

View File

@ -5,7 +5,7 @@ use std::result;
use serde_json::Value;
use jsonpath::parser::*;
use super::parser::*;
use super::term::*;
use super::value_wrapper::*;
@ -257,21 +257,16 @@ impl JsonValueFilter {
pub fn new(json: &str) -> result::Result<Self, String> {
let json: Value = serde_json::from_str(json)
.map_err(|e| e.description().to_string())?;
Ok(JsonValueFilter {
json: Rc::new(Box::new(json)),
filter_stack: Vec::new(),
token_stack: Vec::new(),
term_stack: Vec::new(),
})
Ok(JsonValueFilter::new_from_value(json))
}
pub fn new_from_value(json: Value) -> result::Result<Self, String> {
Ok(JsonValueFilter {
pub fn new_from_value(json: Value) -> Self{
JsonValueFilter {
json: Rc::new(Box::new(json)),
filter_stack: Vec::new(),
token_stack: Vec::new(),
term_stack: Vec::new(),
})
}
}
fn is_peek_token_array(&self) -> bool {

View File

@ -1,4 +0,0 @@
mod path_reader;
mod tokenizer;
pub mod parser;
pub mod json_filter;

View File

@ -7,10 +7,11 @@ extern crate serde_json;
extern crate core;
extern crate indexmap;
mod jsonpath;
pub mod parser;
pub mod filter;
use jsonpath::parser::*;
use jsonpath::json_filter::value_filter::*;
use parser::parser::*;
use filter::value_filter::*;
use std::result;
use serde_json::Value;
@ -23,7 +24,7 @@ pub fn compile<'a>(path: &'a str) -> impl FnMut(Value) -> Result + 'a {
move |json| {
match &node {
Ok(n) => {
let mut jf = JsonValueFilter::new_from_value(json)?;
let mut jf = JsonValueFilter::new_from_value(json);
jf.visit(n.clone());
Ok(jf.take_value())
},
@ -32,8 +33,17 @@ pub fn compile<'a>(path: &'a str) -> impl FnMut(Value) -> Result + 'a {
}
}
pub fn filter(json: Value, path: &str) -> Result {
let mut jf = JsonValueFilter::new_from_value(json)?;
pub fn reader(json: Value) -> impl FnMut(&str) -> Result {
let mut jf = JsonValueFilter::new_from_value(json);
move |path: &str| {
let mut parser = Parser::new(path);
parser.parse(&mut jf)?;
Ok(jf.take_value())
}
}
pub fn read(json: Value, path: &str) -> Result {
let mut jf = JsonValueFilter::new_from_value(json);
let mut parser = Parser::new(path);
parser.parse(&mut jf)?;
Ok(jf.take_value())

3
src/parser/mod.rs Normal file
View File

@ -0,0 +1,3 @@
mod path_reader;
mod tokenizer;
pub mod parser;

View File

@ -1,7 +1,7 @@
use std::result;
use std::io::Write;
use jsonpath::path_reader::{
use super::path_reader::{
ReaderError,
PathReader,
};
@ -361,7 +361,7 @@ impl<'a> PreloadedTokenizer<'a> {
#[cfg(test)]
mod tests {
use super::TokenError;
use jsonpath::tokenizer::{
use super::{
Token,
Tokenizer,
PreloadedTokenizer,

11
wasm/.appveyor.yml Normal file
View File

@ -0,0 +1,11 @@
install:
- appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
- if not defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
- rustc -V
- cargo -V
build: false
test_script:
- cargo test --locked

6
wasm/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
/target
**/*.rs.bk
Cargo.lock
bin/
pkg/
wasm-pack.log

69
wasm/.travis.yml Normal file
View File

@ -0,0 +1,69 @@
language: rust
sudo: false
cache: cargo
matrix:
include:
# Builds with wasm-pack.
- rust: beta
env: RUST_BACKTRACE=1
addons:
firefox: latest
chrome: stable
before_script:
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
- (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate)
- cargo install-update -a
- curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f
script:
- cargo generate --git . --name testing
# Having a broken Cargo.toml (in that it has curlies in fields) anywhere
# in any of our parent dirs is problematic.
- mv Cargo.toml Cargo.toml.tmpl
- cd testing
- wasm-pack build
- wasm-pack test --chrome --firefox --headless
# Builds on nightly.
- rust: nightly
env: RUST_BACKTRACE=1
before_script:
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
- (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate)
- cargo install-update -a
- rustup target add wasm32-unknown-unknown
script:
- cargo generate --git . --name testing
- mv Cargo.toml Cargo.toml.tmpl
- cd testing
- cargo check
- cargo check --target wasm32-unknown-unknown
- cargo check --no-default-features
- cargo check --target wasm32-unknown-unknown --no-default-features
- cargo check --no-default-features --features console_error_panic_hook
- cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook
- cargo check --no-default-features --features "console_error_panic_hook wee_alloc"
- cargo check --target wasm32-unknown-unknown --no-default-features --features "console_error_panic_hook wee_alloc"
# Builds on beta.
- rust: beta
env: RUST_BACKTRACE=1
before_script:
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
- (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate)
- cargo install-update -a
- rustup target add wasm32-unknown-unknown
script:
- cargo generate --git . --name testing
- mv Cargo.toml Cargo.toml.tmpl
- cd testing
- cargo check
- cargo check --target wasm32-unknown-unknown
- cargo check --no-default-features
- cargo check --target wasm32-unknown-unknown --no-default-features
- cargo check --no-default-features --features console_error_panic_hook
- cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook
# Note: no enabling the `wee_alloc` feature here because it requires
# nightly for now.

25
wasm/Cargo.toml Normal file
View File

@ -0,0 +1,25 @@
[package]
name = "wasm"
version = "0.1.0"
authors = ["freestrings <freestrings@gmail.com>"]
[lib]
crate-type = ["cdylib", "rlib"]
[features]
default = ["console_error_panic_hook"]
[dependencies]
cfg-if = "0.1.2"
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }
console_error_panic_hook = { version = "0.1.1", optional = true }
wee_alloc = { version = "0.4.2", optional = true }
jsonpath = {path = "../"}
serde_json = { version = "1.0", features = ["preserve_order"] }
[dev-dependencies]
wasm-bindgen-test = "0.2"
[profile.release]
opt-level = "s"

11
wasm/build.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
set -e
cd ./www && \
rm -rf dist && \
rm -rf node_modules && \
npm install && \
cd .. && \
wasm-pack build --target=$1 --out-dir=www/node_modules/rs-jsonpath

94
wasm/src/lib.rs Normal file
View File

@ -0,0 +1,94 @@
extern crate cfg_if;
extern crate wasm_bindgen;
extern crate serde_json;
extern crate jsonpath;
mod utils;
use cfg_if::cfg_if;
use wasm_bindgen::prelude::*;
use std::result::Result;
use serde_json::Value;
use jsonpath::parser::parser::*;
use jsonpath::filter::value_filter::*;
cfg_if! {
if #[cfg(feature = "wee_alloc")] {
extern crate wee_alloc;
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
}
}
fn filter_value(json: Value, node: Node) -> JsValue {
let mut jf = JsonValueFilter::new_from_value(json);
jf.visit(node);
let taken = jf.take_value();
match JsValue::from_serde(&taken) {
Ok(js_value) => js_value,
Err(e) => JsValue::from_str(&format!("Json deserialize error: {:?}", e))
}
}
fn into_value(js_value: &JsValue) -> Result<Value, String> {
if js_value.is_string() {
match serde_json::from_str(js_value.as_string().unwrap().as_str()) {
Ok(json) => Ok(json),
Err(e) => Err(format!("{:?}", e))
}
} else {
match js_value.into_serde() {
Ok(json) => Ok(json),
Err(e) => Err(format!("{:?}", e))
}
}
}
fn into_js_value(js_value: &JsValue, node: Node) -> JsValue {
match into_value(js_value) {
Ok(json) => filter_value(json, node),
Err(e) => JsValue::from_str(&format!("Json serialize error: {}", e))
}
}
#[wasm_bindgen]
pub fn compile(path: &str) -> JsValue {
let mut parser = Parser::new(path);
let node = parser.compile();
let cb = Closure::wrap(Box::new(move |js_value: JsValue| {
match &node {
Ok(node) => into_js_value(&js_value, node.clone()),
Err(e) => JsValue::from_str(&format!("Json path error: {:?}", e))
}
}) as Box<Fn(JsValue) -> JsValue>);
let ret = cb.as_ref().clone();
cb.forget();
ret
}
#[wasm_bindgen]
pub fn reader(js_value: JsValue) -> JsValue {
let cb = Closure::wrap(Box::new(move |path: String| {
let mut parser = Parser::new(path.as_str());
match parser.compile() {
Ok(node) => into_js_value(&js_value, node),
Err(e) => return JsValue::from_str(e.as_str())
}
}) as Box<Fn(String) -> JsValue>);
let ret = cb.as_ref().clone();
cb.forget();
ret
}
#[wasm_bindgen]
pub fn read(js_value: JsValue, path: &str) -> JsValue {
let mut parser = Parser::new(path);
match parser.compile() {
Ok(node) => into_js_value(&js_value, node),
Err(e) => return JsValue::from_str(e.as_str())
}
}

11
wasm/src/utils.rs Normal file
View File

@ -0,0 +1,11 @@
use cfg_if::cfg_if;
cfg_if! {
if #[cfg(feature = "console_error_panic_hook")] {
extern crate console_error_panic_hook;
pub use self::console_error_panic_hook::set_once as set_panic_hook;
} else {
#[inline]
pub fn set_panic_hook() {}
}
}

13
wasm/tests/web.rs Normal file
View File

@ -0,0 +1,13 @@
//! Test suite for the Web and headless browsers.
#![cfg(target_arch = "wasm32")]
extern crate wasm_bindgen_test;
use wasm_bindgen_test::*;
wasm_bindgen_test_configure!(run_in_browser);
#[wasm_bindgen_test]
fn pass() {
assert_eq!(1 + 1, 2);
}

2
wasm/www/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules
dist

5
wasm/www/.travis.yml Normal file
View File

@ -0,0 +1,5 @@
language: node_js
node_js: "10"
script:
- ./node_modules/.bin/webpack

5
wasm/www/bootstrap.js vendored Normal file
View File

@ -0,0 +1,5 @@
// A dependency graph that contains any wasm must all be imported
// asynchronously. This `bootstrap.js` file does the single async import, so
// that no one else needs to worry about it again.
import("./index.js")
.catch(e => console.error("Error importing `index.js`:", e));

10
wasm/www/index.html Normal file
View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JsonPath Evaluator</title>
</head>
<body>
<script src="./bootstrap.js"></script>
</body>
</html>

16
wasm/www/index.js Normal file
View File

@ -0,0 +1,16 @@
import * as jsonpath from "rs-jsonpath";
let jsonString = "{\"a\" : 1}";
let template = jsonpath.compile("$.a");
console.log(template(jsonString));
console.log(template(JSON.parse(jsonString)));
let reader1 = jsonpath.reader(jsonString);
console.log(reader1("$.a"));
let reader2 = jsonpath.reader(JSON.parse(jsonString));
console.log(reader2("$.a"));
console.log(jsonpath.read(JSON.parse(jsonString), "$.a"));
console.log(jsonpath.read(jsonString, "$.a"));

5582
wasm/www/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

31
wasm/www/package.json Normal file
View File

@ -0,0 +1,31 @@
{
"name": "rs-jsonpath",
"version": "0.1.0",
"main": "index.js",
"scripts": {
"build": "webpack --config webpack.config.js",
"start": "webpack-dev-server"
},
"repository": {
"type": "git",
"url": "git+https://github.com/freestrings/jsonpath.git"
},
"keywords": [
"webassembly",
"wasm",
"rust",
"webpack"
],
"author": "Changseok Han <freestrings@gmail.com>",
"license": "(MIT OR Apache-2.0)",
"bugs": {
"url": "https://github.com/freestrings/jsonpath/issues"
},
"homepage": "https://github.com/freestrings/jsonpath#readme",
"devDependencies": {
"copy-webpack-plugin": "^5.0.0",
"webpack": "^4.29.6",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.5"
}
}

View File

@ -0,0 +1,14 @@
const CopyWebpackPlugin = require("copy-webpack-plugin");
const path = require('path');
module.exports = {
entry: "./bootstrap.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "bootstrap.js",
},
mode: "development",
plugins: [
new CopyWebpackPlugin(['index.html'])
]
};