use std::{env::var, fs::read_to_string, path::PathBuf}; use directories::ProjectDirs; use serde::Deserialize; use crate::{constants::*, errors::McError}; #[allow(dead_code)] #[derive(Debug, Deserialize)] pub struct Config { pub username: String, pub uuid: String, pub version: String, pub java_path: String, pub max_memory_mb: u32, pub data_dir: PathBuf, pub cache_dir: PathBuf, pub config_dir: PathBuf, #[serde(default)] pub jvm_args: Vec, } impl Config { pub fn load() -> Result { let cfg_path = default_config_path()?; let mut cfg: Config = if cfg_path.exists() { let txt = read_to_string(&cfg_path)?; toml::from_str(&txt).map_err(|e| McError::Config(e.to_string()))? } else { Self::default() }; if let Ok(v) = var("MC_USERNAME") { cfg.username = v; } if let Ok(v) = var("MC_VERSION") { cfg.version = v; } if let Ok(v) = var("MC_JAVA_PATH") { cfg.java_path = v; } if let Ok(v) = var("MC_MAX_MEMORY_MB") { cfg.max_memory_mb = v.parse().unwrap_or(cfg.max_memory_mb); } Ok(cfg) } fn default() -> Self { let base = ProjectDirs::from("com", "example", "dml").expect("platform dirs"); Self { username: "Player".into(), uuid: uuid::Uuid::new_v4().to_string(), version: DEFAULT_VERSION.into(), java_path: DEFAULT_JAVA_PATH.into(), max_memory_mb: DEFAULT_MAX_MEMORY_MB, data_dir: base.data_dir().into(), cache_dir: base.cache_dir().into(), config_dir: base.config_dir().into(), jvm_args: vec![], } } } fn default_config_path() -> Result { let base = ProjectDirs::from("com", "example", "dml") .ok_or_else(|| McError::Config("cannot determine config dir".into()))?; Ok(base.config_dir().join("config.toml")) }