use std::collections::HashMap;
use std::ffi::{c_char, CStr};
use crate::core::{Key, Row};
#[unsafe(no_mangle)]
pub extern "C" fn row_free(val: *mut Row) {
if !val.is_null() {
unsafe { let _ = Box::from_raw(val); }
}
}
#[unsafe(no_mangle)]
pub extern "C" fn row_new(c_name: *const c_char) -> *mut Row {
if c_name.is_null() {
return std::ptr::null_mut()
}
let name = unsafe { CStr::from_ptr(c_name) };
let name = match name.to_str() {
Ok(s) => s,
Err(_) => return std::ptr::null_mut(),
};
Box::into_raw(Box::new(Row::new(name.to_string(), HashMap::new())))
}
#[unsafe(no_mangle)]
pub extern "C" fn row_keys_len(row: *mut Row) -> usize {
if row.is_null() {
return 0
}
unsafe {
(&*row).keys.len()
}
}
#[unsafe(no_mangle)]
pub extern "C" fn row_insert_key(row: *mut Row, to_insert: *mut Key) -> bool {
if row.is_null() || to_insert.is_null() {
return false;
}
unsafe {
let row_ref = &mut *row;
let map = &mut row_ref.keys;
let insert_this: Box<Key> = Box::from_raw(to_insert);
map.insert(insert_this.name.clone(), *insert_this);
true
}
}
#[unsafe(no_mangle)]
pub extern "C" fn row_remove_key(row: *mut Row, name: *const c_char) -> bool {
if row.is_null() || name.is_null() {
return false;
}
unsafe {
let row_ref = &mut *row;
let map = &mut row_ref.keys;
let c_str = match CStr::from_ptr(name).to_str() {
Ok(s) => s,
Err(_) => return false,
};
map.remove(c_str);
true
}
}
#[unsafe(no_mangle)]
pub extern "C" fn row_get_key(row: *mut Row, name: *const c_char) -> *mut Key {
if row.is_null() || name.is_null() {
return std::ptr::null_mut();
}
unsafe {
let row_ref = &mut *row;
let map = &mut row_ref.keys;
let c_str = match CStr::from_ptr(name).to_str() {
Ok(s) => s,
Err(_) => return std::ptr::null_mut(),
};
if let Some(row) = map.get_mut(c_str) {
row as *mut Key
} else {
std::ptr::null_mut()
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn row_as_buffer(row: *mut Row) -> *const u8 {
if row.is_null() {
return std::ptr::null();
}
unsafe {
match (&*row).encode() {
Ok(buff) => {
let boxed = buff.into_boxed_slice();
let ptr = boxed.as_ptr();
std::mem::forget(boxed);
ptr
}
Err(_) => std::ptr::null(),
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn row_from_buffer(buff: *const u8, len: usize) -> *mut Row {
if buff.is_null() || len == 0 {
return std::ptr::null_mut();
}
unsafe {
let slice = std::slice::from_raw_parts(buff, len);
let vec = slice.to_vec();
match Row::decode(vec) {
Ok(buff) => Box::into_raw(Box::new(buff)),
Err(_) => std::ptr::null_mut(),
}
}
}