use crate::error::ApiError;
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use std::time::SystemTime;
pub fn resolve_prompt_path(path: &str, base_dir: &Path) -> Result<PathBuf, ApiError> {
if path.starts_with('/') {
return Ok(PathBuf::from(path));
}
if path.starts_with("~/") {
let home =
std::env::var("HOME").map_err(|_| ApiError::ConfigError("HOME not set".to_string()))?;
return Ok(PathBuf::from(home).join(&path[2..]));
}
if path.starts_with("./") {
let current_dir = std::env::current_dir().map_err(|e| {
ApiError::ConfigError(format!("Failed to get current directory: {}", e))
})?;
return Ok(current_dir.join(&path[2..]));
}
Ok(base_dir.join(path))
}
pub struct PromptCache {
cache: HashMap<PathBuf, (String, SystemTime)>,
}
impl PromptCache {
pub fn new() -> Self {
Self {
cache: HashMap::new(),
}
}
pub fn load_prompt(&mut self, path: &Path) -> Result<String, ApiError> {
let metadata = std::fs::metadata(path).map_err(|e| {
ApiError::ConfigError(format!(
"Failed to read prompt file {}: {}",
path.display(),
e
))
})?;
let mtime = metadata.modified().map_err(|e| {
ApiError::ConfigError(format!(
"Failed to get modification time for {}: {}",
path.display(),
e
))
})?;
if let Some((cached_content, cached_mtime)) = self.cache.get(path) {
if *cached_mtime == mtime {
return Ok(cached_content.clone());
}
}
let content = std::fs::read_to_string(path).map_err(|e| {
ApiError::ConfigError(format!(
"Failed to read prompt file {}: {}",
path.display(),
e
))
})?;
if content.trim().is_empty() {
return Err(ApiError::ConfigError(format!(
"Prompt file {} is empty",
path.display()
)));
}
self.cache
.insert(path.to_path_buf(), (content.clone(), mtime));
Ok(content)
}
}
impl Default for PromptCache {
fn default() -> Self {
Self::new()
}
}