diff options
Diffstat (limited to 'vendor/jsonpath_lib/src/ffi/mod.rs')
-rw-r--r-- | vendor/jsonpath_lib/src/ffi/mod.rs | 59 |
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()) +} |