mod database;
pub use self::database::Database;
pub use rusqlite::{
self,
Connection,
};
pub type CloseDbResult = Result<(), (Connection, rusqlite::Error)>;
pub type DbThreadJoinHandle = std::thread::JoinHandle<CloseDbResult>;
pub type BoxedError = Box<dyn std::error::Error + Send + Sync + 'static>;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error(transparent)]
Rusqlite(#[from] rusqlite::Error),
#[error(transparent)]
TokioJoin(#[from] tokio::task::JoinError),
#[error("failed to send message to db")]
SendMessage,
#[error("failed to get access response from db")]
MissingResponse(#[source] tokio::sync::oneshot::error::RecvError),
#[error("already joined db")]
AlreadyJoined,
#[error("failed to join thread")]
ThreadJoin(SyncWrapper<Box<dyn std::any::Any + Send>>),
#[error("init func failed")]
SetupFunc(#[source] BoxedError),
#[error("db access panicked")]
AccessPanicked(SyncWrapper<Box<dyn std::any::Any + Send>>),
}
pub struct SyncWrapper<T> {
value: T,
}
unsafe impl<T: Send> Send for SyncWrapper<T> {}
unsafe impl<T> Sync for SyncWrapper<T> {}
impl<T> std::fmt::Debug for SyncWrapper<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SyncWrapper").finish()
}
}
impl<T> SyncWrapper<T> {
pub(crate) fn new(value: T) -> Self {
Self { value }
}
pub fn into_inner(self) -> T {
self.value
}
}