use serde::{Deserialize, Serialize};
use crate::task::Task;
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "cmd", rename_all = "snake_case")]
pub enum Request {
ListTasks,
AddTask { name: String, duration_minutes: u32 },
RemoveTask { index: usize },
ToggleDone { index: usize },
MarkDone { index: usize },
ClearCompleted,
StartTimer { index: usize },
PauseTimer,
ResumeTimer,
StopTimer,
Status,
Shutdown,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum TimerStatus {
Idle,
Running,
Paused,
Finished,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TimerInfo {
pub state: TimerStatus,
pub task_index: Option<usize>,
pub remaining_secs: u64,
pub total_secs: u64,
}
impl Default for TimerInfo {
fn default() -> Self {
Self {
state: TimerStatus::Idle,
task_index: None,
remaining_secs: 0,
total_secs: 0,
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Response {
pub ok: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tasks: Option<Vec<Task>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub timer: Option<TimerInfo>,
}
impl Response {
pub fn ok() -> Self {
Self {
ok: true,
message: None,
tasks: None,
timer: None,
}
}
pub fn ok_msg(msg: impl Into<String>) -> Self {
Self {
ok: true,
message: Some(msg.into()),
tasks: None,
timer: None,
}
}
pub fn error(msg: impl Into<String>) -> Self {
Self {
ok: false,
message: Some(msg.into()),
tasks: None,
timer: None,
}
}
#[must_use]
pub fn with_tasks(mut self, tasks: Vec<Task>) -> Self {
self.tasks = Some(tasks);
self
}
#[must_use]
pub fn with_timer(mut self, timer: TimerInfo) -> Self {
self.timer = Some(timer);
self
}
}
pub fn socket_path() -> std::path::PathBuf {
if let Some(runtime_dir) = std::env::var_os("XDG_RUNTIME_DIR") {
std::path::PathBuf::from(runtime_dir).join("hyperfocus.sock")
} else {
std::path::PathBuf::from("/tmp").join("hyperfocus.sock")
}
}