use crate::{Row, Key};
use std::ffi::CStr;
use std::ptr;
#[unsafe(no_mangle)]
pub extern "C" fn row_new(name: *const i8, keys: *const *mut Key, keys_len: usize) -> *mut Row {
unsafe {
if name.is_null() { return ptr::null_mut(); }
let cstr = match CStr::from_ptr(name).to_str() { Ok(s) => s, Err(_) => return ptr::null_mut() };
let mut keys_vec = Vec::with_capacity(keys_len);
if !keys.is_null() {
for i in 0..keys_len {
let key_ptr = *keys.add(i);
if !key_ptr.is_null() {
keys_vec.push((*key_ptr).clone());
}
}
}
Box::into_raw(Box::new(Row::new(cstr, keys_vec)))
}
}
#[unsafe(no_mangle)]
pub extern "C" fn row_free(row: *mut Row) {
unsafe { if !row.is_null() { let _ = Box::from_raw(row); } }
}
#[unsafe(no_mangle)]
pub extern "C" fn row_insert_key(row: *mut Row, key: *mut Key) {
unsafe {
if row.is_null() || key.is_null() { return; }
let row = &mut *row;
let key = &*key;
row.keys.insert(key.name.clone(), key.clone());
}
}
#[unsafe(no_mangle)]
pub extern "C" fn row_remove_key(row: *mut Row, name: *const i8) -> *mut Key {
unsafe {
if row.is_null() || name.is_null() { return ptr::null_mut(); }
let cstr = match CStr::from_ptr(name).to_str() { Ok(s) => s, Err(_) => return ptr::null_mut() };
match (*row).keys.remove(cstr) {
Some(key) => Box::into_raw(Box::new(key)),
None => ptr::null_mut(),
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn row_serialize(row: *const Row, out_bytes: *mut u8, max_len: usize) -> usize {
unsafe {
if row.is_null() || out_bytes.is_null() { return 0; }
let row = &*row;
match row.serialize() {
Ok(vec) => {
let len = vec.len().min(max_len);
ptr::copy_nonoverlapping(vec.as_ptr(), out_bytes, len);
len
}
Err(_) => 0,
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn row_deserialize(bytes: *const u8, len: usize) -> *mut Row {
unsafe {
if bytes.is_null() || len == 0 { return ptr::null_mut(); }
let vec = std::slice::from_raw_parts(bytes, len).to_vec();
match Row::deserialize(vec) {
Ok(row) => Box::into_raw(Box::new(row)),
Err(_) => ptr::null_mut(),
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn row_key_count(row: *const Row) -> usize {
unsafe {
if row.is_null() { return 0; }
(*row).keys.len()
}
}