mirror of
https://github.com/fluencelabs/jsonpath
synced 2025-04-25 09:22:19 +00:00
123 lines
3.6 KiB
Rust
123 lines
3.6 KiB
Rust
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 path = ctx.argument::<JsString>(1)?.value();
|
|
match jsonpath::select_str(&json_val, path.as_str()) {
|
|
Ok(value) => Ok(JsString::new(&mut ctx, &value).upcast()),
|
|
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 json_str = ctx.argument::<JsString>(0)?.value();
|
|
let ref_value: RefValue = match serde_json::from_str(&json_str) {
|
|
Ok(ref_value) => ref_value,
|
|
Err(e) => panic!("{:?}", e)
|
|
};
|
|
|
|
let mut jf = JsonValueFilter::new_from_value(ref_value.into());
|
|
jf.visit(node);
|
|
match serde_json::to_string(&jf.take_value()) {
|
|
Ok(json_str) => Ok(JsString::new(&mut ctx, &json_str).upcast()),
|
|
Err(e) => panic!("{:?}", e)
|
|
}
|
|
}
|
|
}
|
|
|
|
pub class JsSelector for Selector {
|
|
init(mut ctx) {
|
|
let json_str = ctx.argument::<JsString>(0)?.value();
|
|
let ref_value: RefValue = match serde_json::from_str(&json_str) {
|
|
Ok(ref_value) => ref_value,
|
|
Err(e) => panic!("{:?}", e)
|
|
};
|
|
|
|
Ok(Selector { json: ref_value.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);
|
|
match serde_json::to_string(&jf.take_value()) {
|
|
Ok(json_str) => Ok(JsString::new(&mut ctx, &json_str).upcast()),
|
|
Err(e) => panic!("{:?}", e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
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(())
|
|
}); |