1 | use std::ffi::{CStr, CString}; |
2 | use std::os::raw::{c_char, c_void}; |
3 | |
4 | use {parser, select, select_as_str}; |
5 | |
6 | const INVALID_PATH: &str = "invalid path" ; |
7 | const INVALID_JSON: &str = "invalud json" ; |
8 | |
9 | fn to_str(v: *const c_char, err_msg: &str) -> &str { |
10 | unsafe { CStr::from_ptr(v) }.to_str().expect(err_msg) |
11 | } |
12 | |
13 | fn to_char_ptr(v: &str) -> *const c_char { |
14 | let s: CString = CString::new(v).unwrap_or_else(|_| panic!("invalid string: {}" , v)); |
15 | let ptr: *const i8 = s.as_ptr(); |
16 | std::mem::forget(s); |
17 | ptr |
18 | } |
19 | |
20 | #[no_mangle ] |
21 | pub extern "C" fn ffi_select(json_str: *const c_char, path: *const c_char) -> *const c_char { |
22 | let json_str: &str = to_str(v:json_str, INVALID_JSON); |
23 | let path: &str = to_str(v:path, INVALID_PATH); |
24 | match select_as_str(json_str, path) { |
25 | Ok(v: String) => to_char_ptr(v.as_str()), |
26 | Err(e: JsonPathError) => { |
27 | panic!(" {:?}" , e); |
28 | } |
29 | } |
30 | } |
31 | |
32 | #[no_mangle ] |
33 | #[allow (clippy::forget_copy)] |
34 | pub extern "C" fn ffi_path_compile(path: *const c_char) -> *mut c_void { |
35 | let path: &str = to_str(v:path, INVALID_PATH); |
36 | let ref_node: *mut Node = Box::into_raw(Box::new(parser::Parser::compile(input:path).unwrap())); |
37 | let ptr: *mut c_void = ref_node as *mut c_void; |
38 | std::mem::forget(ref_node); |
39 | ptr |
40 | } |
41 | |
42 | #[no_mangle ] |
43 | pub extern "C" fn ffi_select_with_compiled_path( |
44 | path_ptr: *mut c_void, |
45 | json_ptr: *const c_char, |
46 | ) -> *const c_char { |
47 | let node: Box = unsafe { Box::from_raw(path_ptr as *mut parser::Node) }; |
48 | let json_str: &str = to_str(v:json_ptr, INVALID_JSON); |
49 | let json: Value = serde_json::from_str(json_str) |
50 | .unwrap_or_else(|_| panic!("invalid json string: {}" , json_str)); |
51 | |
52 | let mut selector: Selector<'_, '_> = select::Selector::default(); |
53 | let found: Vec<&Value> = selector.compiled_path(&node).value(&json).select().unwrap(); |
54 | std::mem::forget(node); |
55 | |
56 | let result: String = serde_json::to_string(&found) |
57 | .unwrap_or_else(|_| panic!("json serialize error: {:?}" , found)); |
58 | to_char_ptr(result.as_str()) |
59 | } |
60 | |