switchy_database/
config.rs1use std::{
2 ops::Deref,
3 sync::{Arc, LazyLock, RwLock},
4};
5
6use crate::Database;
7
8#[allow(clippy::type_complexity)]
9static DATABASE: LazyLock<Arc<RwLock<Option<Arc<Box<dyn Database>>>>>> =
10 LazyLock::new(|| Arc::new(RwLock::new(None)));
11
12pub fn init(database: Arc<Box<dyn Database>>) {
16 *DATABASE.write().unwrap() = Some(database);
17}
18
19#[allow(clippy::module_name_repetitions)]
20#[derive(Debug, Clone)]
21pub struct ConfigDatabase {
22 pub database: Arc<Box<dyn Database>>,
23}
24
25impl From<&ConfigDatabase> for Arc<Box<dyn Database>> {
26 fn from(value: &ConfigDatabase) -> Self {
27 value.database.clone()
28 }
29}
30
31impl From<ConfigDatabase> for Arc<Box<dyn Database>> {
32 fn from(value: ConfigDatabase) -> Self {
33 value.database
34 }
35}
36
37impl From<Arc<Box<dyn Database>>> for ConfigDatabase {
38 fn from(value: Arc<Box<dyn Database>>) -> Self {
39 Self { database: value }
40 }
41}
42
43impl<'a> From<&'a ConfigDatabase> for &'a dyn Database {
44 fn from(value: &'a ConfigDatabase) -> Self {
45 &**value.database
46 }
47}
48
49impl Deref for ConfigDatabase {
50 type Target = dyn Database;
51
52 fn deref(&self) -> &Self::Target {
53 &**self.database
54 }
55}
56
57#[cfg(feature = "api")]
58mod api {
59 use actix_web::{FromRequest, HttpRequest, dev::Payload, error::ErrorInternalServerError};
60 use futures::future::{Ready, err, ok};
61
62 use super::DATABASE;
63
64 impl FromRequest for super::ConfigDatabase {
65 type Error = actix_web::Error;
66 type Future = Ready<Result<Self, actix_web::Error>>;
67
68 fn from_request(_req: &HttpRequest, _: &mut Payload) -> Self::Future {
69 let Some(database) = DATABASE.read().unwrap().clone() else {
70 return err(ErrorInternalServerError("Config database not initialized"));
71 };
72
73 ok(Self { database })
74 }
75 }
76}