1mod database;
2
3pub use self::database::Database;
4pub use rusqlite::{
5 self,
6 Connection,
7};
8
9pub type CloseDbResult = Result<(), (Connection, rusqlite::Error)>;
10pub type DbThreadJoinHandle = std::thread::JoinHandle<CloseDbResult>;
11
12pub type BoxedError = Box<dyn std::error::Error + Send + Sync + 'static>;
13
14#[derive(Debug, thiserror::Error)]
16pub enum Error {
17 #[error(transparent)]
19 Rusqlite(#[from] rusqlite::Error),
20
21 #[error(transparent)]
23 TokioJoin(#[from] tokio::task::JoinError),
24
25 #[error("failed to send message to db")]
27 SendMessage,
28
29 #[error("failed to get access response from db")]
31 MissingResponse(#[source] tokio::sync::oneshot::error::RecvError),
32
33 #[error("already joined db")]
35 AlreadyJoined,
36
37 #[error("failed to join thread")]
39 ThreadJoin(SyncWrapper<Box<dyn std::any::Any + Send>>),
40
41 #[error("init func failed")]
43 SetupFunc(#[source] BoxedError),
44
45 #[error("db access panicked")]
47 AccessPanicked(SyncWrapper<Box<dyn std::any::Any + Send>>),
48}
49
50pub struct SyncWrapper<T> {
52 value: T,
53}
54
55unsafe impl<T: Send> Send for SyncWrapper<T> {}
58
59unsafe impl<T> Sync for SyncWrapper<T> {}
62
63impl<T> std::fmt::Debug for SyncWrapper<T> {
64 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65 f.debug_struct("SyncWrapper").finish()
67 }
68}
69
70impl<T> SyncWrapper<T> {
71 pub(crate) fn new(value: T) -> Self {
73 Self { value }
74 }
75
76 pub fn into_inner(self) -> T {
78 self.value
79 }
80}