use std::path::PathBuf;
#[derive(Debug, Clone, Default)]
#[cfg_attr(
any(feature = "config", feature = "download"),
derive(serde::Serialize, serde::Deserialize)
)]
pub struct PackConfig {
#[cfg_attr(any(feature = "config", feature = "download"), serde(default))]
pub cache_dir: Option<PathBuf>,
#[cfg_attr(any(feature = "config", feature = "download"), serde(default))]
pub languages: Option<Vec<String>>,
#[cfg_attr(any(feature = "config", feature = "download"), serde(default))]
pub groups: Option<Vec<String>>,
}
impl PackConfig {
#[cfg(feature = "config")]
pub fn from_toml_file(path: &std::path::Path) -> Result<Self, crate::error::Error> {
let content = std::fs::read_to_string(path)?;
toml::from_str(&content)
.map_err(|e| crate::error::Error::Config(format!("Failed to parse {}: {e}", path.display())))
}
#[cfg(all(feature = "config", feature = "download"))]
pub fn discover() -> Option<Self> {
if let Ok(cwd) = std::env::current_dir() {
let mut dir: &std::path::Path = cwd.as_path();
for _ in 0..10 {
let candidate = dir.join("language-pack.toml");
if candidate.exists() {
return Self::from_toml_file(&candidate).ok();
}
match dir.parent() {
Some(parent) => dir = parent,
None => break,
}
}
}
if let Some(config_dir) = dirs::config_dir() {
let candidate = config_dir.join("tree-sitter-language-pack").join("config.toml");
if candidate.exists() {
return Self::from_toml_file(&candidate).ok();
}
}
None
}
}