libhaystack/c_api/json.rs
1// Copyright (C) 2020 - 2022, J2 Innovations
2
3//!
4//! C API for working JSON encoding.
5//!
6
7use super::err::{new_error, update_last_error};
8use std::ffi::{CStr, CString};
9use std::os::raw::c_char;
10
11use crate::haystack::val::Value;
12
13/// Encodes a [Value](crate::val::Value) to a JSON string
14/// # Arguments
15/// - val Value to encode as a JSON string
16/// # Return
17/// a `C string` with the JSON encoded value
18/// or `null` if there was an error, in which case the [last_error_message](super::err::last_error_message)
19/// can be called to get the error message.
20/// # Safety
21/// Panics on invalid input data
22#[unsafe(no_mangle)]
23pub unsafe extern "C" fn haystack_value_to_json_string(val: *const Value) -> *const c_char {
24 match unsafe { val.as_ref() } {
25 Some(val) => match serde_json::to_string(val) {
26 Ok(str) => match CString::new(str.as_str()) {
27 Ok(str) => str.into_raw(),
28 Err(err) => {
29 update_last_error(err);
30 std::ptr::null()
31 }
32 },
33 Err(err) => {
34 update_last_error(err);
35 std::ptr::null()
36 }
37 },
38 None => {
39 new_error("Invalid value");
40 std::ptr::null()
41 }
42 }
43}
44
45/// Decodes a [Value](crate::val::Value) from a JSON string
46/// # Arguments
47/// - val `C string` with the JSON encoded value
48/// # Return
49/// the decoded [Value](crate::val::Value) or `null` if there was an error,
50/// in which case the [last_error_message](super::err::last_error_message)
51/// can be called to get the error message.
52/// # Safety
53/// Panics on invalid input data
54#[unsafe(no_mangle)]
55pub unsafe extern "C" fn haystack_value_from_json_string(
56 input: *const c_char,
57) -> Option<Box<Value>> {
58 if input.is_null() {
59 new_error("Invalid null argument(s)");
60 return None;
61 }
62 match unsafe { CStr::from_ptr(input).to_str() } {
63 Ok(c_str) => match serde_json::from_str::<Value>(c_str) {
64 Ok(val) => Some(Box::new(val)),
65 Err(err) => {
66 update_last_error(err);
67 None
68 }
69 },
70 Err(err) => {
71 new_error(&format!("Invalid C string. {err}"));
72 None
73 }
74 }
75}