Skip to main content

hvz/
settings.rs

1use std::str::FromStr;
2
3use diesel::{
4    ExpressionMethods, QueryDsl, RunQueryDsl, Selectable,
5    prelude::{Insertable, Queryable},
6};
7use serde::{Deserialize, Serialize};
8
9use crate::{establish_connection, schema::settings};
10
11pub const HAS_STARTED: &str = "has_started";
12pub const CHECKPOINT_AVAILABLE: &str = "checkpoint_available";
13pub const CHECKPOINT: &str = "checkpoint";
14pub const Z0_REVEALED: &str = "z0_revealed";
15pub const UPLOAD_PATH: &str = "./uploads";
16
17/// Settings struct
18#[derive(Clone, Debug, Serialize, Deserialize, Selectable, Queryable, Insertable)]
19#[diesel(table_name = crate::schema::settings)]
20#[diesel(check_for_backend(diesel::mysql::Mysql))]
21pub struct Settings {
22    pub id: String,
23    pub settings_key: String,
24    pub settings_value: String,
25}
26
27/// Implementation of the Settings struct
28impl Settings {
29    /// Set a settings
30    ///
31    /// It uses a generic type to set the value of the setting
32    ///
33    /// # Arguments
34    /// * `key` - The key of the setting to set
35    /// * `value` - The value of the setting to set
36    ///
37    /// # Returns
38    /// * `Result<Settings, String>` - The updated settings or an error message
39    pub async fn set_settings<T>(key: &str, value: T) -> Result<Settings, String>
40    where
41        String: From<T>,
42    {
43        let connection = &mut establish_connection();
44
45        let settings = Settings {
46            id: uuid::Uuid::new_v4().to_string(),
47            settings_key: key.to_string(),
48            settings_value: String::from(value),
49        };
50
51        let count = settings::table
52            .filter(settings::settings_key.eq(settings.settings_key.clone()))
53            .count()
54            .first::<i64>(connection)
55            .expect("Failed to count settings");
56
57        if count == 0 {
58            diesel::insert_into(settings::table)
59                .values(settings.clone())
60                .execute(connection)
61                .expect("Failed to insert settings");
62        } else {
63            diesel::update(settings::table)
64                .filter(settings::settings_key.eq(settings.settings_key.clone()))
65                .set(settings::settings_value.eq(settings.settings_value.clone()))
66                .execute(connection)
67                .expect("Failed to update settings");
68        }
69
70        Ok(settings)
71    }
72
73    /// Get a setting
74    ///
75    /// It uses a generic type to get the value of the setting
76    ///
77    /// # Arguments
78    /// * `key` - The key of the setting to get
79    ///
80    /// # Returns
81    /// * `Result<T, <T as FromStr>::Err>` - The value of the setting or an error message
82    pub async fn get_settings<T>(key: &str) -> Result<T, <T as FromStr>::Err>
83    where
84        T: FromStr,
85    {
86        let connection = &mut establish_connection();
87
88        let settings = settings::table
89            .filter(settings::settings_key.eq(&key))
90            .first::<Settings>(connection)
91            .expect("Key not found");
92
93        settings.settings_value.parse::<T>()
94    }
95}