use std::net::Ipv4Addr; use std::path::PathBuf; use serde::{Serialize, Deserialize}; use sqlx::SqlitePool; use crate::errors::*; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct AppConfig { pub db_path: PathBuf, pub listen_addr: Ipv4Addr, pub listen_port: u16, pub rehide_ms: u64, } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct DbAppConfig { listen_addr: Option, listen_port: Option, rehide_ms: Option, } impl Default for AppConfig { fn default() -> Self { AppConfig { db_path: get_or_create_db_path(), listen_addr: Ipv4Addr::LOCALHOST, listen_port: listen_port(), rehide_ms: 1000, } } } impl From for AppConfig { fn from(db_config: DbAppConfig) -> Self { AppConfig { db_path: get_or_create_db_path(), listen_addr: db_config.listen_addr.unwrap_or(Ipv4Addr::LOCALHOST), listen_port: db_config.listen_port.unwrap_or_else(|| listen_port()), rehide_ms: db_config.rehide_ms.unwrap_or(1000), } } } pub async fn load(pool: &SqlitePool) -> Result { let res = sqlx::query!("SELECT * from config where name = 'main'") .fetch_optional(pool) .await?; let row = match res { Some(row) => row, None => return Ok(AppConfig::default()), }; let db_config: DbAppConfig = serde_json::from_str(&row.data)?; Ok(AppConfig::from(db_config)) } fn listen_port() -> u16 { if cfg!(debug_assertions) { 12_345 } else { 19_923 } } pub fn get_or_create_db_path() -> PathBuf { if cfg!(debug_assertions) { return PathBuf::from("./creddy.db"); } let mut parent = std::env::var("HOME") .map(|h| { let mut p = PathBuf::from(h); p.push(".config"); p }) .unwrap_or(PathBuf::from(".")); parent.push("creddy.db"); parent }