1use crate::errors::AppError;
2use crate::i18n::validacao;
3use directories::ProjectDirs;
4use std::path::PathBuf;
5
6#[derive(Debug)]
7pub struct AppPaths {
8 pub db: PathBuf,
9 pub models: PathBuf,
10}
11
12impl AppPaths {
13 pub fn resolve(db_override: Option<&str>) -> Result<Self, AppError> {
14 let proj = ProjectDirs::from("", "", "sqlite-graphrag").ok_or_else(|| {
15 AppError::Io(std::io::Error::other("cannot determine home directory"))
16 })?;
17
18 let cache_root = if let Some(override_dir) = std::env::var_os("SQLITE_GRAPHRAG_CACHE_DIR") {
19 PathBuf::from(override_dir)
20 } else {
21 proj.cache_dir().to_path_buf()
22 };
23
24 let db = if let Some(p) = db_override {
25 validate_path(p)?;
26 PathBuf::from(p)
27 } else if let Ok(env_path) = std::env::var("SQLITE_GRAPHRAG_DB_PATH") {
28 validate_path(&env_path)?;
29 PathBuf::from(env_path)
30 } else {
31 std::env::current_dir()
32 .map_err(AppError::Io)?
33 .join("graphrag.sqlite")
34 };
35
36 Ok(Self {
37 db,
38 models: cache_root.join("models"),
39 })
40 }
41
42 pub fn ensure_dirs(&self) -> Result<(), AppError> {
43 for dir in [self.db.parent().unwrap(), &self.models] {
44 std::fs::create_dir_all(dir)?;
45 }
46 Ok(())
47 }
48}
49
50fn validate_path(p: &str) -> Result<(), AppError> {
51 if p.contains("..") {
52 return Err(AppError::Validation(validacao::path_traversal(p)));
53 }
54 Ok(())
55}