use ini::Ini;
use std::path::PathBuf;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum AccessTokenError {
#[error("Home directory not found")]
HomeDirectoryNotFound,
#[error("Failed to load config file: {0}")]
ConfigLoadError(#[from] ini::Error),
#[error("ACCESS_TOKEN not found in config.ini")]
AccessTokenNotFound,
#[error("Failed to create config directory or file: {0}")]
ConfigCreationError(std::io::Error),
}
pub fn get_config_path() -> Result<PathBuf, AccessTokenError> {
dirs::home_dir()
.ok_or(AccessTokenError::HomeDirectoryNotFound)
.map(|home| home.join(".config").join("fitbit-rs").join("config.ini"))
}
pub fn get_access_token() -> Result<String, AccessTokenError> {
let config_path = get_config_path()?;
let config = Ini::load_from_file(&config_path)?;
config
.get_from(Some("Fitbit"), "ACCESS_TOKEN")
.ok_or(AccessTokenError::AccessTokenNotFound)
.map(String::from)
}
pub fn store_access_token(access_token: &str) -> Result<(), AccessTokenError> {
let config_path = get_config_path()?;
if let Some(parent) = config_path.parent() {
std::fs::create_dir_all(parent).map_err(AccessTokenError::ConfigCreationError)?;
}
let mut config = Ini::load_from_file(&config_path).unwrap_or_else(|_| Ini::new());
config
.with_section(Some("Fitbit"))
.set("ACCESS_TOKEN", access_token);
config
.write_to_file(&config_path)
.map_err(AccessTokenError::ConfigCreationError)?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use std::env;
use std::fs;
use tempfile::tempdir;
#[test]
fn test_store_and_retrieve_access_token() {
let temp_dir = tempdir().unwrap();
let config_dir = temp_dir.path().join(".config").join("lifestats");
fs::create_dir_all(&config_dir).unwrap();
let original_home = env::var("HOME").ok();
unsafe {
env::set_var("HOME", temp_dir.path());
}
let test_token = "test_access_token_123";
store_access_token(test_token).unwrap();
let retrieved_token = get_access_token().unwrap();
assert_eq!(retrieved_token, test_token);
if let Some(home) = original_home {
unsafe {
env::set_var("HOME", home);
}
} else {
unsafe {
env::remove_var("HOME");
}
}
}
}