diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..ee13052 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,46 @@ +use std::collections::HashMap; +use std::path::PathBuf; +use std::str::FromStr; +use super::Error; + +pub const CFG_DIR: &'static str = ".Playdate"; +pub const CFG_FILENAME: &'static str = "config"; +pub const CFG_KEY_SDK_ROOT: &'static str = "SDKRoot"; + +pub struct SdkCfg(HashMap); + +impl FromStr for SdkCfg { + type Err = Error; + + fn from_str(s: &str) -> Result { + Ok(Self( + s.trim() + .lines() + .filter_map(|line| { + line.split_once("\t") + .map(|(k, v)| (k.to_owned(), v.to_owned())) + }) + .collect(), + )) + } +} + +impl SdkCfg { + pub fn sdk_path(&self) -> Option { + self.0.get(CFG_KEY_SDK_ROOT).map(PathBuf::from) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn parse() { + let path = "/path/PlaydateSDK-dir"; + let cfg: SdkCfg = format!("{k}\t{v}\n", k = CFG_KEY_SDK_ROOT, v = path) + .parse() + .unwrap(); + assert_eq!(cfg.sdk_path(), Some(PathBuf::from(path))); + } +} diff --git a/src/main.rs b/src/main.rs index 4a5212a..0ad5153 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ use anyhow::{anyhow, bail, Error}; use inflector::cases::titlecase::to_title_case; -use log::{info, debug}; +use log::{debug, info}; use serde_derive::Deserialize; use std::{ env, @@ -16,6 +16,8 @@ use zip_extensions::zip_create_from_directory_with_options; #[cfg(unix)] use anyhow::Context; +mod config; + #[cfg(unix)] const GCC_PATH_STR: &'static str = "/usr/local/bin/arm-none-eabi-gcc"; #[cfg(windows)] @@ -44,7 +46,28 @@ const SDK_DIR: &'static str = "Developer"; #[cfg(windows)] const SDK_DIR: &'static str = "Documents"; +fn playdate_sdk_cfg() -> Result { + let cfg_path = dirs::home_dir() + .ok_or(anyhow!("Can't find home dir"))? + .join(config::CFG_DIR) + .join(config::CFG_FILENAME); + fs::read_to_string(cfg_path)?.parse() +} + fn playdate_sdk_path() -> Result { + match playdate_sdk_cfg() { + Err(_) => { + debug!("Unable to read PlaydateSDK config from home dir, so using default."); + playdate_sdk_path_default() + } + Ok(cfg) => cfg.sdk_path().map(|p| Ok(p)).unwrap_or_else(|| { + debug!("Unable to determine PlaydateSDK path by config, so using default."); + playdate_sdk_path_default() + }), + } +} + +fn playdate_sdk_path_default() -> Result { let home_dir = dirs::home_dir().ok_or(anyhow!("Can't find home dir"))?; Ok(home_dir.join(SDK_DIR).join("PlaydateSDK")) }