ai_session/
session_cache.rs1use crate::core::{SessionConfig, SessionId};
4use anyhow::Result;
5use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7use std::fs;
8use std::path::PathBuf;
9
10#[derive(Debug, Serialize, Deserialize)]
11pub struct SessionInfo {
12 pub id: SessionId,
13 pub name: Option<String>,
14 pub config: SessionConfig,
15 pub created_at: chrono::DateTime<chrono::Utc>,
16 pub pid: Option<u32>,
17}
18
19pub struct SessionCache {
20 cache_file: PathBuf,
21 sessions: HashMap<SessionId, SessionInfo>,
22}
23
24impl SessionCache {
25 pub fn new() -> Result<Self> {
26 let cache_dir = dirs::cache_dir()
27 .ok_or_else(|| anyhow::anyhow!("Could not determine cache directory"))?
28 .join("ai-session");
29
30 fs::create_dir_all(&cache_dir)?;
31
32 let cache_file = cache_dir.join("sessions.json");
33 let mut cache = Self {
34 cache_file,
35 sessions: HashMap::new(),
36 };
37
38 cache.load()?;
39 Ok(cache)
40 }
41
42 pub fn add_session(&mut self, info: SessionInfo) -> Result<()> {
43 self.sessions.insert(info.id.clone(), info);
44 self.save()
45 }
46
47 pub fn get_session(&self, id: &SessionId) -> Option<&SessionInfo> {
48 self.sessions.get(id)
49 }
50
51 pub fn list_sessions(&self) -> Vec<&SessionInfo> {
52 let mut sessions: Vec<_> = self.sessions.values().collect();
53 sessions.sort_by(|a, b| b.created_at.cmp(&a.created_at));
54 sessions
55 }
56
57 pub fn remove_session(&mut self, id: &SessionId) -> Result<()> {
58 self.sessions.remove(id);
59 self.save()
60 }
61
62 fn load(&mut self) -> Result<()> {
63 if self.cache_file.exists() {
64 let content = fs::read_to_string(&self.cache_file)?;
65 if !content.is_empty() {
66 self.sessions = serde_json::from_str(&content)?;
67 }
68 }
69 Ok(())
70 }
71
72 fn save(&self) -> Result<()> {
73 let json = serde_json::to_string_pretty(&self.sessions)?;
74 fs::write(&self.cache_file, json)?;
75 Ok(())
76 }
77}