summaryrefslogtreecommitdiffstats
path: root/vendor/jsonpath_lib/src/ffi/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/jsonpath_lib/src/ffi/mod.rs')
-rw-r--r--vendor/jsonpath_lib/src/ffi/mod.rs59
1 files changed, 59 insertions, 0 deletions
diff --git a/vendor/jsonpath_lib/src/ffi/mod.rs b/vendor/jsonpath_lib/src/ffi/mod.rs
new file mode 100644
index 000000000..2ad259b5c
--- /dev/null
+++ b/vendor/jsonpath_lib/src/ffi/mod.rs
@@ -0,0 +1,59 @@
+use std::ffi::{CStr, CString};
+use std::os::raw::{c_char, c_void};
+
+use {parser, select, select_as_str};
+
+const INVALID_PATH: &str = "invalid path";
+const INVALID_JSON: &str = "invalud json";
+
+fn to_str(v: *const c_char, err_msg: &str) -> &str {
+ unsafe { CStr::from_ptr(v) }.to_str().expect(err_msg)
+}
+
+fn to_char_ptr(v: &str) -> *const c_char {
+ let s = CString::new(v).unwrap_or_else(|_| panic!("invalid string: {}", v));
+ let ptr = s.as_ptr();
+ std::mem::forget(s);
+ ptr
+}
+
+#[no_mangle]
+pub extern "C" fn ffi_select(json_str: *const c_char, path: *const c_char) -> *const c_char {
+ let json_str = to_str(json_str, INVALID_JSON);
+ let path = to_str(path, INVALID_PATH);
+ match select_as_str(json_str, path) {
+ Ok(v) => to_char_ptr(v.as_str()),
+ Err(e) => {
+ panic!("{:?}", e);
+ }
+ }
+}
+
+#[no_mangle]
+#[allow(clippy::forget_copy)]
+pub extern "C" fn ffi_path_compile(path: *const c_char) -> *mut c_void {
+ let path = to_str(path, INVALID_PATH);
+ let ref_node = Box::into_raw(Box::new(parser::Parser::compile(path).unwrap()));
+ let ptr = ref_node as *mut c_void;
+ std::mem::forget(ref_node);
+ ptr
+}
+
+#[no_mangle]
+pub extern "C" fn ffi_select_with_compiled_path(
+ path_ptr: *mut c_void,
+ json_ptr: *const c_char,
+) -> *const c_char {
+ let node = unsafe { Box::from_raw(path_ptr as *mut parser::Node) };
+ let json_str = to_str(json_ptr, INVALID_JSON);
+ let json = serde_json::from_str(json_str)
+ .unwrap_or_else(|_| panic!("invalid json string: {}", json_str));
+
+ let mut selector = select::Selector::default();
+ let found = selector.compiled_path(&node).value(&json).select().unwrap();
+ std::mem::forget(node);
+
+ let result = serde_json::to_string(&found)
+ .unwrap_or_else(|_| panic!("json serialize error: {:?}", found));
+ to_char_ptr(result.as_str())
+}