Skip to main content

kasl/libs/
pause.rs

1//! The pause model shared by the monitor, the database layer and the views.
2//!
3//! ```rust,no_run
4//! # fn f() -> Result<(), chrono::ParseError> {
5//! use kasl::libs::pause::Pause;
6//! use chrono::{NaiveDateTime, Duration};
7//!
8//! let pause = Pause::detected(
9//!     1,
10//!     NaiveDateTime::parse_from_str("2025-08-11 09:15:00", "%Y-%m-%d %H:%M:%S")?,
11//!     Some(NaiveDateTime::parse_from_str("2025-08-11 09:30:00", "%Y-%m-%d %H:%M:%S")?),
12//!     Some(Duration::minutes(15)),
13//! );
14//! # Ok(())
15//! # }
16//! ```
17
18use chrono::{Duration, prelude::NaiveDateTime};
19
20/// A single break period; `end` and `duration` stay `None` while it is ongoing.
21#[derive(Debug, Clone)]
22pub struct Pause {
23    /// Database primary key.
24    pub id: i32,
25
26    /// When the inactivity threshold was crossed (local time).
27    pub start: NaiveDateTime,
28
29    /// When activity resumed; `None` while the pause is still running.
30    pub end: Option<NaiveDateTime>,
31
32    /// `end - start`, stored by the database layer; `None` while ongoing.
33    pub duration: Option<Duration>,
34
35    /// Whether this pause was entered manually and must be preserved as-is.
36    ///
37    /// Protected pauses are recorded by the user through `kasl pauses add`
38    /// rather than detected by the activity monitor. They are exempt from the
39    /// minimum-duration threshold and are never merged with adjacent pauses,
40    /// so a deliberately short entry (a ten-minute walk the monitor missed)
41    /// survives filtering intact.
42    pub protected: bool,
43}
44
45impl Pause {
46    /// Builds a monitor-detected pause (not protected).
47    ///
48    /// Used when reconstructing pauses from sources that carry no protection
49    /// flag, such as in-memory analysis of activity data.
50    pub fn detected(id: i32, start: NaiveDateTime, end: Option<NaiveDateTime>, duration: Option<Duration>) -> Self {
51        Self {
52            id,
53            start,
54            end,
55            duration,
56            protected: false,
57        }
58    }
59}