pub mod ai_types;
mod types;
pub use types::{ClipboardBackend, Config};
#[allow(unused_imports)]
pub use types::AutocompleteConfig;
#[allow(unused_imports)]
pub use ai_types::{AiConfig, AiProviderType, AnthropicConfig};
#[allow(unused_imports)]
pub use types::TooltipConfig;
use std::fs;
use std::path::PathBuf;
pub struct ConfigResult {
pub config: Config,
pub warning: Option<String>,
}
pub fn load_config() -> ConfigResult {
let config_path = get_config_path();
if !config_path.exists() {
return ConfigResult {
config: Config::default(),
warning: None,
};
}
let contents = match fs::read_to_string(&config_path) {
Ok(contents) => contents,
Err(e) => {
#[cfg(debug_assertions)]
log::error!("Failed to read config file {:?}: {}", config_path, e);
return ConfigResult {
config: Config::default(),
warning: Some(format!("Failed to read config: {}", e)),
};
}
};
match toml::from_str::<Config>(&contents) {
Ok(mut config) => {
config.autocomplete.array_sample_size =
config.autocomplete.array_sample_size.clamp(1, 1000);
ConfigResult {
config,
warning: None,
}
}
Err(e) => {
#[cfg(debug_assertions)]
log::error!("Failed to parse config file {:?}: {}", config_path, e);
ConfigResult {
config: Config::default(),
warning: Some(format!("Invalid config: {}", e)),
}
}
}
}
fn get_config_path() -> PathBuf {
dirs::home_dir()
.unwrap_or_else(|| PathBuf::from("."))
.join(".config")
.join("jiq")
.join("config.toml")
}
#[cfg(test)]
#[path = "config_tests.rs"]
mod config_tests;