use crate::ffi;
use std::ffi::c_int;
#[doc(hidden)]
pub unsafe fn sqlite3_last_error(retval: i32, database: *mut ffi::sqlite3) -> crate::error::Error {
use std::borrow::Cow;
use std::ffi::CStr;
let error = ffi::sqlite3_errstr(retval);
let mut message = match error.is_null() {
true => Cow::Borrowed("Unknown"),
false => CStr::from_ptr(error).to_string_lossy(),
};
if !database.is_null() {
let error = ffi::sqlite3_errmsg(database);
let message_ = CStr::from_ptr(error).to_string_lossy();
message = Cow::Owned(format!("{message} ({message_})"));
}
crate::err!("SQLite error: {message}")
}
#[doc(hidden)]
#[inline]
pub unsafe fn sqlite3_check_result(retval: i32, database: *mut ffi::sqlite3) -> Result<(), crate::error::Error> {
match retval {
ffi::SQLITE_OK => Ok(()),
_ => Err(sqlite3_last_error(retval, database)),
}
}
#[derive(Debug)]
pub struct PointerMut<T> {
ptr: *mut T,
on_drop: unsafe extern "C" fn(*mut T) -> c_int,
}
impl<T> PointerMut<T> {
pub fn new(ptr: *mut T, on_drop: unsafe extern "C" fn(*mut T) -> c_int) -> Self {
assert!(!ptr.is_null(), "cannot create an owned NULL pointer");
Self { ptr, on_drop }
}
pub const fn as_ptr(&self) -> *mut T {
self.ptr
}
}
impl<T> Drop for PointerMut<T> {
fn drop(&mut self) {
unsafe { (self.on_drop)(self.ptr) };
}
}
#[derive(Debug)]
pub enum PointerMutFlex<'a, T> {
Borrowed(&'a mut PointerMut<T>),
Owned(PointerMut<T>),
}
impl<T> PointerMutFlex<'_, T> {
pub const fn as_ptr(&self) -> *mut T {
match self {
PointerMutFlex::Borrowed(pointer_ref) => pointer_ref.as_ptr(),
PointerMutFlex::Owned(pointer_mut) => pointer_mut.as_ptr(),
}
}
}