git_iris/companion/
session.rs1use chrono::{DateTime, Utc};
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8use std::path::PathBuf;
9use uuid::Uuid;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct FileActivity {
14 pub path: PathBuf,
16 pub first_touched: DateTime<Utc>,
18 pub last_touched: DateTime<Utc>,
20 pub touch_count: u32,
22}
23
24impl FileActivity {
25 pub fn new(path: PathBuf) -> Self {
27 let now = Utc::now();
28 Self {
29 path,
30 first_touched: now,
31 last_touched: now,
32 touch_count: 1,
33 }
34 }
35
36 pub fn touch(&mut self) {
38 self.last_touched = Utc::now();
39 self.touch_count += 1;
40 }
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize)]
45pub struct SessionState {
46 pub session_id: Uuid,
48 pub repo_path: PathBuf,
50 pub branch: String,
52 pub started_at: DateTime<Utc>,
54 pub last_activity: DateTime<Utc>,
56 pub files_touched: HashMap<PathBuf, FileActivity>,
58 pub commits_made: Vec<String>,
60}
61
62impl SessionState {
63 pub fn new(repo_path: PathBuf, branch: String) -> Self {
65 let now = Utc::now();
66 Self {
67 session_id: Uuid::new_v4(),
68 repo_path,
69 branch,
70 started_at: now,
71 last_activity: now,
72 files_touched: HashMap::new(),
73 commits_made: Vec::new(),
74 }
75 }
76
77 pub fn touch_file(&mut self, path: PathBuf) {
79 self.last_activity = Utc::now();
80 self.files_touched
81 .entry(path.clone())
82 .and_modify(FileActivity::touch)
83 .or_insert_with(|| FileActivity::new(path));
84 }
85
86 pub fn record_commit(&mut self, hash: String) {
88 self.last_activity = Utc::now();
89 self.commits_made.push(hash);
90 }
91
92 pub fn duration(&self) -> chrono::Duration {
94 Utc::now() - self.started_at
95 }
96
97 pub fn files_count(&self) -> usize {
99 self.files_touched.len()
100 }
101
102 pub fn recent_files(&self) -> Vec<&FileActivity> {
104 let mut files: Vec<_> = self.files_touched.values().collect();
105 files.sort_by(|a, b| b.last_touched.cmp(&a.last_touched));
106 files
107 }
108
109 pub fn time_since_last_commit(&self) -> Option<chrono::Duration> {
111 if self.commits_made.is_empty() {
112 None
113 } else {
114 Some(Utc::now() - self.last_activity)
115 }
116 }
117
118 pub fn set_branch(&mut self, branch: String) {
120 self.branch = branch;
121 self.last_activity = Utc::now();
122 }
123}