#![cfg(feature = "cli")]
use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::fs;
use std::io::Write;
use std::path::PathBuf;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserConfig {
pub session: String,
#[serde(default)]
pub telemetry: TelemetryConfig,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TelemetryConfig {
pub uuid: String,
pub enabled: bool,
pub level: String,
pub stats: bool,
}
impl Default for UserConfig {
fn default() -> Self {
Self {
session: String::new(),
telemetry: TelemetryConfig::default(),
}
}
}
impl Default for TelemetryConfig {
fn default() -> Self {
Self {
uuid: uuid::Uuid::new_v4().to_string(),
enabled: false,
level: "basic".to_string(),
stats: false,
}
}
}
pub fn get_home_dir() -> Option<PathBuf> {
dirs::home_dir()
}
pub fn get_devalang_homedir() -> PathBuf {
if let Some(home_dir) = get_home_dir() {
home_dir.join(".devalang")
} else {
PathBuf::from("~/.devalang")
}
}
pub fn get_user_config_path() -> PathBuf {
get_devalang_homedir().join("config.json")
}
pub fn get_user_config() -> Option<UserConfig> {
let config_path = get_user_config_path();
if !config_path.exists() {
return None;
}
let file = fs::File::open(config_path).ok()?;
serde_json::from_reader(file).ok()
}
pub fn write_user_config(config: &UserConfig) -> Result<()> {
let config_path = get_user_config_path();
if let Some(parent) = config_path.parent() {
fs::create_dir_all(parent)?;
}
let tmp_path = config_path.with_extension("json.tmp");
let config_json = serde_json::to_string_pretty(config)?;
let mut tmp_file = fs::File::create(&tmp_path)?;
tmp_file.write_all(config_json.as_bytes())?;
tmp_file.sync_all()?;
fs::rename(&tmp_path, config_path)?;
Ok(())
}
pub fn ensure_user_config_exists() -> Result<()> {
let config_path = get_user_config_path();
if !config_path.exists() {
let config = UserConfig::default();
write_user_config(&config)?;
}
Ok(())
}
pub fn set_session_token(token: String) -> Result<()> {
let mut config = get_user_config().unwrap_or_default();
config.session = token;
write_user_config(&config)?;
Ok(())
}
pub fn get_session_token() -> Option<String> {
get_user_config().and_then(|cfg| {
let token = cfg.session.trim();
if token.is_empty() {
None
} else {
Some(token.to_string())
}
})
}
pub fn clear_session_token() -> Result<()> {
let mut config = get_user_config().unwrap_or_default();
config.session = String::new();
write_user_config(&config)?;
Ok(())
}