mirror of
https://github.com/fluencelabs/jsonpath
synced 2025-06-12 07:31:25 +00:00
NodeJs native binding 추가
This commit is contained in:
6
nodejs/.gitignore
vendored
Normal file
6
nodejs/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
native/target
|
||||
native/index.node
|
||||
native/artifacts.json
|
||||
**/*~
|
||||
**/node_modules
|
||||
.idea
|
3
nodejs/README.md
Normal file
3
nodejs/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# jsonpath-rs
|
||||
|
||||
JsonPath engine for NodeJs with Rust native implementation.
|
34
nodejs/lib/index.js
Normal file
34
nodejs/lib/index.js
Normal 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
5
nodejs/native/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
.idea/*
|
||||
.vscode
|
||||
!.idea/runConfigurations/
|
||||
/target/
|
||||
Cargo.lock
|
24
nodejs/native/Cargo.toml
Normal file
24
nodejs/native/Cargo.toml
Normal 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
7
nodejs/native/build.rs
Normal 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
126
nodejs/native/src/lib.rs
Normal 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
3172
nodejs/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
20
nodejs/package.json
Normal file
20
nodejs/package.json
Normal 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
30
nodejs/test/index.spec.js
Normal 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();
|
||||
}
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user