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