async_rusqlite/
lib.rs

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/// Error
15#[derive(Debug, thiserror::Error)]
16pub enum Error {
17    /// Rusqlite error
18    #[error(transparent)]
19    Rusqlite(#[from] rusqlite::Error),
20
21    /// Tokio Join Error
22    #[error(transparent)]
23    TokioJoin(#[from] tokio::task::JoinError),
24
25    /// Failed to send message to db
26    #[error("failed to send message to db")]
27    SendMessage,
28
29    /// Failed to get result from db
30    #[error("failed to get access response from db")]
31    MissingResponse(#[source] tokio::sync::oneshot::error::RecvError),
32
33    /// This database was already joined
34    #[error("already joined db")]
35    AlreadyJoined,
36
37    /// Bad thread join
38    #[error("failed to join thread")]
39    ThreadJoin(SyncWrapper<Box<dyn std::any::Any + Send>>),
40
41    /// Setup failed to run
42    #[error("init func failed")]
43    SetupFunc(#[source] BoxedError),
44
45    /// A db access panicked
46    #[error("db access panicked")]
47    AccessPanicked(SyncWrapper<Box<dyn std::any::Any + Send>>),
48}
49
50/// Copied from tokio
51pub struct SyncWrapper<T> {
52    value: T,
53}
54
55// safety: The SyncWrapper being send allows you to send the inner value across
56// thread boundaries.
57unsafe impl<T: Send> Send for SyncWrapper<T> {}
58
59// safety: An immutable reference to a SyncWrapper is useless, so moving such an
60// immutable reference across threads is safe.
61unsafe 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        // TODO: Add debug bound to impl?
66        f.debug_struct("SyncWrapper").finish()
67    }
68}
69
70impl<T> SyncWrapper<T> {
71    /// Make a new [`SyncWrapper`] around a type T
72    pub(crate) fn new(value: T) -> Self {
73        Self { value }
74    }
75
76    /// Get the inner value
77    pub fn into_inner(self) -> T {
78        self.value
79    }
80}