#![allow(clippy::not_unsafe_ptr_arg_deref)]
pub use types::*;
mod ext_fns;
mod types;
use std::ffi::c_char;
use std::mem::size_of;
use std::pin::Pin;
use std::ptr::copy_nonoverlapping;
use std::slice;
use libc::{calloc, malloc, size_t};
use super::*;
impl AsRef<[u8]> for PossumBuf {
fn as_ref(&self) -> &[u8] {
let ptr = self.ptr as *const u8;
unsafe { slice::from_raw_parts(ptr, self.size) }
}
}
impl PossumBuf {
fn as_mut_slice(&mut self) -> &mut [u8] {
let ptr = self.ptr as *mut u8;
unsafe { slice::from_raw_parts_mut(ptr, self.size) }
}
}
enum PossumValue {
ReaderValue(Value),
SnapshotValue(SnapshotValue<Value>),
}
struct PossumReader {
rust_reader: Option<Reader<'static>>,
values: Vec<Pin<Box<PossumValue>>>,
}
type PossumValueWriter = *mut ValueWriter;
use crate::c_api::PossumError::{AnyhowError, IoError, SqliteError};
impl<V> From<V> for PossumStat
where
V: AsRef<Value>,
{
fn from(value: V) -> Self {
let value = value.as_ref();
Self {
size: value.length(),
last_used: value.last_used().into(),
}
}
}
impl From<Timestamp> for PossumTimestamp {
fn from(value: Timestamp) -> Self {
Self {
secs: value.timestamp(),
nanos: value.timestamp_subsec_nanos(),
}
}
}
fn items_list_to_c(
key_prefix_size: size_t,
items: Vec<Item>,
out_list: *mut *mut PossumItem,
out_list_len: *mut size_t,
) {
unsafe {
*out_list = calloc(size_of::<PossumItem>(), items.len()) as *mut PossumItem;
*out_list_len = items.len();
}
for (index, item) in items.iter().enumerate() {
let key_size = item.key.len() - key_prefix_size;
let c_item = PossumItem {
key: PossumBuf {
ptr: unsafe { malloc(key_size) } as *const c_char,
size: key_size,
},
stat: PossumStat {
last_used: item.value.last_used().into(),
size: item.value.length(),
},
};
unsafe {
copy_nonoverlapping(
item.key[key_prefix_size..].as_ptr(),
c_item.key.ptr as *mut u8,
key_size,
)
};
let dest = unsafe { (*out_list).add(index) };
unsafe { *dest = c_item };
}
}
use PossumError::*;
use crate::item::Item;
impl From<Error> for PossumError {
fn from(value: Error) -> Self {
match value {
Error::NoSuchKey => NoSuchKey,
Error::Sqlite(_) => SqliteError,
Error::Io(_) => IoError,
Error::Anyhow(_) => AnyhowError,
}
}
}
impl From<rusqlite::Error> for PossumError {
fn from(_value: rusqlite::Error) -> Self {
SqliteError
}
}
impl From<io::Error> for PossumError {
fn from(_value: io::Error) -> Self {
IoError
}
}
impl From<anyhow::Error> for PossumError {
fn from(_value: anyhow::Error) -> Self {
AnyhowError
}
}
fn with_residual<E>(f: impl FnOnce() -> Result<(), E>) -> PossumError
where
E: Into<crate::Error>,
{
match f() {
Ok(()) => NoError,
Err(err) => {
let err = err.into();
warn!("converting rust error into enum: {:#?}", err);
err.into()
}
}
}
impl Into<handle::Limits> for PossumLimits {
fn into(self) -> handle::Limits {
handle::Limits {
max_value_length_sum: match self.max_value_length_sum {
u64::MAX => None,
otherwise => Some(otherwise),
},
}
}
}