use super::err::{new_error, update_last_error};
use crate::haystack::encoding::brio::decode::FromBrio;
use crate::haystack::encoding::brio::encode::ToBrio;
use crate::haystack::val::Value;
use std::io::Cursor;
#[unsafe(no_mangle)]
pub unsafe extern "C" fn haystack_value_to_brio(val: *const Value, out_len: *mut usize) -> *mut u8 {
if out_len.is_null() {
new_error("out_len must not be null");
return std::ptr::null_mut();
}
match unsafe { val.as_ref() } {
Some(val) => match val.to_brio_vec() {
Ok(bytes) => {
let boxed: Box<[u8]> = bytes.into_boxed_slice();
unsafe { *out_len = boxed.len() };
Box::into_raw(boxed) as *mut u8
}
Err(err) => {
update_last_error(err);
std::ptr::null_mut()
}
},
None => {
new_error("Invalid value");
std::ptr::null_mut()
}
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn haystack_value_from_brio(
data: *const u8,
len: usize,
) -> Option<Box<Value>> {
if data.is_null() {
new_error("Invalid null argument(s)");
return None;
}
let bytes = unsafe { std::slice::from_raw_parts(data, len) };
let mut cursor = Cursor::new(bytes);
match Value::from_brio(&mut cursor) {
Ok(val) => Some(Box::new(val)),
Err(err) => {
update_last_error(err);
None
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn haystack_brio_bytes_free(ptr: *mut u8, len: usize) {
if !ptr.is_null() {
drop(unsafe { Box::from_raw(std::ptr::slice_from_raw_parts_mut(ptr, len)) });
}
}