use crate::errors::AppError;
use crate::i18n::validacao;
use serde::Serialize;
use std::path::Path;
#[derive(Debug, Clone, Copy, Serialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum NamespaceSource {
ExplicitFlag,
Environment,
Default,
}
#[derive(Debug, Clone, Serialize)]
pub struct NamespaceResolution {
pub namespace: String,
pub source: NamespaceSource,
pub cwd: String,
}
pub fn resolve_namespace(explicit: Option<&str>) -> Result<String, AppError> {
Ok(detect_namespace(explicit)?.namespace)
}
pub fn detect_namespace(explicit: Option<&str>) -> Result<NamespaceResolution, AppError> {
let cwd = std::env::current_dir().map_err(AppError::Io)?;
let cwd_display = normalize_path(&cwd);
if let Some(ns) = explicit {
validate_namespace(ns)?;
return Ok(NamespaceResolution {
namespace: ns.to_owned(),
source: NamespaceSource::ExplicitFlag,
cwd: cwd_display,
});
}
if let Ok(ns) = std::env::var("SQLITE_GRAPHRAG_NAMESPACE") {
if !ns.is_empty() {
validate_namespace(&ns)?;
return Ok(NamespaceResolution {
namespace: ns,
source: NamespaceSource::Environment,
cwd: cwd_display,
});
}
}
Ok(NamespaceResolution {
namespace: "global".to_owned(),
source: NamespaceSource::Default,
cwd: cwd_display,
})
}
fn validate_namespace(ns: &str) -> Result<(), AppError> {
if ns.is_empty() || ns.len() > 80 {
return Err(AppError::Validation(validacao::namespace_comprimento()));
}
if !ns
.chars()
.all(|c| c.is_alphanumeric() || c == '-' || c == '_')
{
return Err(AppError::Validation(validacao::namespace_formato()));
}
Ok(())
}
fn normalize_path(path: &Path) -> String {
path.canonicalize()
.unwrap_or_else(|_| path.to_path_buf())
.display()
.to_string()
}