use super::err::{new_error, update_last_error};
use crate::haystack::encoding::trio::decode::TrioReader;
use crate::haystack::encoding::trio::encode::TrioWriter;
use crate::haystack::val::Value;
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
#[unsafe(no_mangle)]
pub unsafe extern "C" fn haystack_value_to_trio_string(val: *const Value) -> *const c_char {
match unsafe { val.as_ref() } {
Some(Value::Dict(dict)) => {
let s = TrioWriter::dict_to_trio(dict, None);
match CString::new(s.as_str()) {
Ok(cs) => cs.into_raw(),
Err(err) => {
update_last_error(err);
std::ptr::null()
}
}
}
Some(Value::Grid(grid)) => {
let s = TrioWriter::new().add_grid(grid).to_trio_string();
match CString::new(s.as_str()) {
Ok(cs) => cs.into_raw(),
Err(err) => {
update_last_error(err);
std::ptr::null()
}
}
}
Some(_) => {
new_error("Trio encoding requires a Dict or Grid value");
std::ptr::null()
}
None => {
new_error("Invalid value");
std::ptr::null()
}
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn haystack_value_from_trio_string(
input: *const c_char,
) -> Option<Box<Value>> {
if input.is_null() {
new_error("Invalid null argument(s)");
return None;
}
match unsafe { CStr::from_ptr(input).to_str() } {
Ok(c_str) => match TrioReader::dicts_from_str(c_str) {
Ok(mut dicts) if !dicts.is_empty() => Some(Box::new(Value::from(dicts.remove(0)))),
Ok(_) => {
new_error("No dicts found in Trio input");
None
}
Err(err) => {
update_last_error(err);
None
}
},
Err(err) => {
update_last_error(err);
None
}
}
}