1use std::{io, 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 MAINTENANCE: &str = "maintenance";
13pub const CHECKPOINT: &str = "checkpoint";
14pub const Z0_REVEALED: &str = "z0_revealed";
15pub const UPLOAD_PATH: &str = "./uploads";
16
17#[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
27impl Settings {
29 pub fn new(key: &str, value: &str) -> Self {
38 Self {
39 id: uuid::Uuid::new_v4().to_string(),
40 settings_key: String::from(key),
41 settings_value: String::from(value),
42 }
43 }
44
45 pub async fn set_settings<T: ToString>(key: &str, value: T) -> Result<Settings, String>
56 {
57 let connection = &mut establish_connection();
58
59 let settings = Settings::new(key, &value.to_string());
60
61 let count = settings::table
62 .filter(settings::settings_key.eq(settings.settings_key.clone()))
63 .count()
64 .first::<i64>(connection)
65 .expect("Failed to count settings");
66
67 if count == 0 {
68 diesel::insert_into(settings::table)
69 .values(settings.clone())
70 .execute(connection)
71 .expect("Failed to insert settings");
72 } else {
73 diesel::update(settings::table)
74 .filter(settings::settings_key.eq(settings.settings_key.clone()))
75 .set(settings::settings_value.eq(settings.settings_value.clone()))
76 .execute(connection)
77 .expect("Failed to update settings");
78 }
79
80 Ok(settings)
81 }
82
83 pub async fn get_settings<T: FromStr>(key: &str) -> Result<T, <T as FromStr>::Err>
93 {
94 let connection = &mut establish_connection();
95
96 let settings = settings::table
97 .filter(settings::settings_key.eq(&key))
98 .first::<Settings>(connection)
99 .expect("Key not found");
100
101 settings.settings_value.parse::<T>()
102 }
103
104 pub async fn init_settings() -> io::Result<()> {
109 let connection = &mut establish_connection();
110
111 let settings = vec![
112 Settings::new(HAS_STARTED, "false"),
113 Settings::new(MAINTENANCE, "false"),
114 Settings::new(CHECKPOINT, ""),
115 Settings::new(Z0_REVEALED, "false"),
116 ];
117
118 for setting in settings {
119 if settings::table
120 .filter(settings::settings_key.eq(&setting.settings_key))
121 .first::<Settings>(connection)
122 .is_ok()
123 {
124 continue;
125 }
126
127 diesel::insert_into(settings::table)
128 .values(&setting)
129 .execute(connection)
130 .expect("Failed to insert setting");
131 }
132
133 Ok(())
134 }
135}