Skip to main content

recall_cli/
session.rs

1use std::path::PathBuf;
2
3use chrono::{DateTime, Utc};
4
5#[derive(Debug, Clone)]
6pub struct Session {
7    pub id: String,
8    pub provider: String,
9    pub summary: String,
10    pub cwd: String,
11    pub created_at: DateTime<Utc>,
12    pub updated_at: DateTime<Utc>,
13    pub checkpoints: Vec<Checkpoint>,
14    pub user_messages: Vec<String>,
15    pub task_summaries: Vec<String>,
16    pub path: PathBuf,
17}
18
19#[derive(Debug, Clone)]
20pub struct Checkpoint {
21    pub title: String,
22}
23
24pub fn delete_session(session: &Session) -> std::io::Result<()> {
25    if session.path.is_dir() {
26        std::fs::remove_dir_all(&session.path)
27    } else {
28        std::fs::remove_file(&session.path)
29    }
30}
31
32pub fn human_time_ago(dt: &DateTime<Utc>) -> String {
33    let now = Utc::now();
34    let duration = now.signed_duration_since(*dt);
35
36    let minutes = duration.num_minutes();
37    let hours = duration.num_hours();
38    let days = duration.num_days();
39
40    if minutes < 1 {
41        "just now".to_string()
42    } else if minutes < 60 {
43        format!("{minutes}m ago")
44    } else if hours < 24 {
45        format!("{hours}h ago")
46    } else if days < 30 {
47        format!("{days}d ago")
48    } else {
49        dt.format("%b %d, %Y").to_string()
50    }
51}
52
53pub fn truncate(s: &str, max: usize) -> String {
54    if s.chars().count() <= max {
55        s.to_string()
56    } else {
57        let truncated: String = s.chars().take(max).collect();
58        format!("{truncated}…")
59    }
60}