use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileFocus {
pub path: PathBuf,
pub line: usize,
pub timestamp: DateTime<Utc>,
}
impl FileFocus {
#[must_use]
pub fn new(path: PathBuf, line: usize) -> Self {
Self {
path,
line,
timestamp: Utc::now(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BranchMemory {
pub branch_name: String,
pub created_at: DateTime<Utc>,
pub last_visited: DateTime<Utc>,
pub last_focus: Option<FileFocus>,
pub notes: Vec<String>,
pub session_count: u32,
pub total_commits: u32,
}
impl BranchMemory {
#[must_use]
pub fn new(branch_name: String) -> Self {
let now = Utc::now();
Self {
branch_name,
created_at: now,
last_visited: now,
last_focus: None,
notes: Vec::new(),
session_count: 0,
total_commits: 0,
}
}
pub fn record_visit(&mut self) {
self.last_visited = Utc::now();
self.session_count += 1;
}
pub fn set_focus(&mut self, path: PathBuf, line: usize) {
self.last_focus = Some(FileFocus::new(path, line));
}
pub fn clear_focus(&mut self) {
self.last_focus = None;
}
pub fn add_note(&mut self, note: String) {
self.notes.push(note);
}
pub fn record_commit(&mut self) {
self.total_commits += 1;
}
#[must_use]
pub fn time_since_last_visit(&self) -> chrono::Duration {
Utc::now() - self.last_visited
}
#[must_use]
pub fn is_returning_visit(&self) -> bool {
self.session_count > 0 && self.time_since_last_visit() > chrono::Duration::minutes(5)
}
#[must_use]
pub fn welcome_message(&self) -> Option<String> {
if !self.is_returning_visit() {
return None;
}
let duration = self.time_since_last_visit();
let time_str = if duration.num_days() > 0 {
format!("{} days ago", duration.num_days())
} else if duration.num_hours() > 0 {
format!("{} hours ago", duration.num_hours())
} else {
format!("{} minutes ago", duration.num_minutes())
};
Some(format!(
"Welcome back to {}! Last here {}",
self.branch_name, time_str
))
}
}