NodeJs native binding 추가

This commit is contained in:
freestrings
2019-03-14 22:30:42 +09:00
parent 1a3104c5db
commit 47e120f66d
69 changed files with 4967 additions and 1424 deletions

6
nodejs/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
native/target
native/index.node
native/artifacts.json
**/*~
**/node_modules
.idea

3
nodejs/README.md Normal file
View File

@ -0,0 +1,3 @@
# jsonpath-rs
JsonPath engine for NodeJs with Rust native implementation.

34
nodejs/lib/index.js Normal file
View File

@ -0,0 +1,34 @@
const { Compile, Selector, selectStr } = require('../native');
function compile(path) {
let compile = new Compile(path);
return (json) => {
if(typeof json != 'string') {
json = JSON.stringify(json)
}
return compile.template(json);
};
}
function selector(json) {
if(typeof json != 'string') {
json = JSON.stringify(json)
}
let selector = new Selector(json);
return (path) => {
return selector.selector(path);
}
}
function select(json, path) {
if(typeof json != 'string') {
json = JSON.stringify(json)
}
return selectStr(json, path);
}
module.exports = {
compile,
selector,
select
};

5
nodejs/native/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.idea/*
.vscode
!.idea/runConfigurations/
/target/
Cargo.lock

24
nodejs/native/Cargo.toml Normal file
View File

@ -0,0 +1,24 @@
[package]
name = "jsonpath-rs"
version = "0.1.0"
authors = ["Changseok Han <freestrings@gmail.com>"]
description = "JsonPath engine for NodeJs with Rust native implementation."
keywords = ["library", "jsonpath", "json"]
repository = "https://github.com/freestrings/jsonpath"
license = "MIT"
build = "build.rs"
exclude = ["artifacts.json", "index.node"]
[build-dependencies]
neon-build = "0.2.0"
[dependencies]
jsonpath_lib = { path = "../../" }
neon = "0.2.0"
neon-serde = "0.1.1"
serde_json = { version = "1.0", features = ["preserve_order"] }
[lib]
name = "jsonpath_rs"
crate-type = ["dylib"]

7
nodejs/native/build.rs Normal file
View File

@ -0,0 +1,7 @@
extern crate neon_build;
fn main() {
neon_build::setup(); // must be called in build.rs
// add project-specific build logic here...
}

126
nodejs/native/src/lib.rs Normal file
View File

@ -0,0 +1,126 @@
extern crate jsonpath_lib as jsonpath;
#[macro_use]
extern crate neon;
extern crate neon_serde;
extern crate serde_json;
use jsonpath::prelude::*;
use neon::prelude::*;
use serde_json::Value;
///
/// `neon_serde::from_value` has very poor performance.
///
fn select(mut ctx: FunctionContext) -> JsResult<JsValue> {
let json_val = ctx.argument::<JsValue>(0)?;
let json: Value = neon_serde::from_value(&mut ctx, json_val)?;
let path = ctx.argument::<JsString>(1)?.value();
match jsonpath::select(&json, path.as_str()) {
Ok(value) => Ok(neon_serde::to_value(&mut ctx, &value)?),
Err(e) => panic!("{:?}", e)
}
}
fn select_str(mut ctx: FunctionContext) -> JsResult<JsValue> {
let json_val = ctx.argument::<JsString>(0)?.value();
let json: Value = match serde_json::from_str(json_val.as_str()) {
Ok(json) => json,
Err(e) => panic!("{:?}", e)
};
let path = ctx.argument::<JsString>(1)?.value();
match jsonpath::select(&json, path.as_str()) {
Ok(value) => Ok(neon_serde::to_value(&mut ctx, &value)?),
Err(e) => panic!("{:?}", e)
}
}
pub struct Compile {
node: Node
}
pub struct Selector {
json: RefValueWrapper
}
declare_types! {
pub class JsCompile for Compile {
init(mut ctx) {
let path = ctx.argument::<JsString>(0)?.value();
let mut parser = Parser::new(path.as_str());
let node = match parser.compile() {
Ok(node) => node,
Err(e) => panic!("{:?}", e)
};
Ok(Compile { node })
}
method template(mut ctx) {
let this = ctx.this();
let node = {
let guard = ctx.lock();
let this = this.borrow(&guard);
this.node.clone()
};
// let o = ctx.argument::<JsValue>(0)?;
// let json: Value = neon_serde::from_value(&mut ctx, o)?;
let json_str = ctx.argument::<JsString>(0)?.value();
let json: Value = match serde_json::from_str(&json_str) {
Ok(json) => json,
Err(e) => panic!("{:?}", e)
};
let mut jf = JsonValueFilter::new_from_value((&json).into());
jf.visit(node);
let v = jf.take_value().into_value();
Ok(neon_serde::to_value(&mut ctx, &v)?)
}
}
pub class JsSelector for Selector {
init(mut ctx) {
// let o = ctx.argument::<JsValue>(0)?;
// let json: Value = neon_serde::from_value(&mut ctx, o)?;
let json_str = ctx.argument::<JsString>(0)?.value();
let json: Value = match serde_json::from_str(&json_str) {
Ok(json) => json,
Err(e) => panic!("{:?}", e)
};
Ok(Selector { json: (&json).into() })
}
method selector(mut ctx) {
let this = ctx.this();
let json = {
let guard = ctx.lock();
let this = this.borrow(&guard);
this.json.clone()
};
let path = ctx.argument::<JsString>(0)?.value();
let mut parser = Parser::new(path.as_str());
let node = match parser.compile() {
Ok(node) => node,
Err(e) => panic!("{:?}", e)
};
let mut jf = JsonValueFilter::new_from_value(json);
jf.visit(node);
let v = jf.take_value().into_value();
Ok(neon_serde::to_value(&mut ctx, &v)?)
}
}
}
register_module!(mut m, {
m.export_class::<JsCompile>("Compile").expect("Compile class error");
m.export_class::<JsSelector>("Selector").expect("Selector class error");
m.export_function("select", select)?;
m.export_function("selectStr", select_str)?;
Ok(())
});

3172
nodejs/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

20
nodejs/package.json Normal file
View File

@ -0,0 +1,20 @@
{
"name": "jsonpath-rs",
"version": "0.1.0",
"description": "JsonPath engine for NodeJs with Rust native implementation.",
"author": "Changseok Han <freestrings@gmail.com>",
"repository": "git+https://github.com/freestrings/jsonpath",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"neon-cli": "^0.2.0",
"node-pre-gyp": "0.6"
},
"scripts": {
"install": "neon build --release",
"test": "mocha"
},
"devDependencies": {
"mocha": "^6.0.2"
}
}

30
nodejs/test/index.spec.js Normal file
View File

@ -0,0 +1,30 @@
const jsonpath = require('../lib/index.js');
describe('compile test', () => {
it('basic', (done) => {
let template = jsonpath.compile('$.a');
let result = template({'a': 1});
if (result == 1) {
done();
}
});
});
describe('selector test', () => {
it('basic', (done) => {
let selector = jsonpath.selector({'a': 1});
let result = selector('$.a');
if (result == 1) {
done();
}
});
});
describe('select test', () => {
it('basic', (done) => {
let result = jsonpath.select({'a': 1}, '$.a');
if (result == 1) {
done();
}
});
});