use serde::{Deserialize, Serialize};
use std::path::Path;
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "lowercase")]
pub enum EmbedBackend {
#[default]
Fastembed,
OpenAI,
Ollama,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "lowercase")]
pub enum StoreBackend {
#[default]
Usearch,
Qdrant,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct EmbedConfig {
#[serde(default)]
pub backend: EmbedBackend,
pub model: Option<String>,
pub url: Option<String>,
pub api_key: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct StoreConfig {
#[serde(default)]
pub backend: StoreBackend,
pub url: Option<String>,
pub collection: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct SemtreeConfig {
#[serde(default)]
pub embed: EmbedConfig,
#[serde(default)]
pub store: StoreConfig,
#[serde(default = "default_index_dir")]
pub index_dir: String,
}
fn default_index_dir() -> String {
".semtree".to_string()
}
impl SemtreeConfig {
pub fn load(dir: &Path) -> Self {
let path = dir.join(".semtree.toml");
if let Ok(raw) = std::fs::read_to_string(&path) {
toml::from_str(&raw).unwrap_or_else(|e| {
eprintln!("Warning: invalid .semtree.toml: {e}");
Self::default()
})
} else {
Self::default()
}
}
pub fn save(&self, dir: &Path) -> std::io::Result<()> {
let path = dir.join(".semtree.toml");
let raw = toml::to_string_pretty(self).expect("serializable");
std::fs::write(path, raw)
}
}