use std::{collections::HashMap, path::PathBuf};
use chrono::prelude::*;
use serde::{Deserialize, Serialize};
use strum::{Display, EnumString, VariantNames};
use crate::message::EditableTask;
macro_rules! impl_into_request {
($inner:ident, $variant:expr) => {
impl From<$inner> for Request {
fn from(message: $inner) -> Self {
$variant(message)
}
}
};
}
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub enum Request {
Add(AddRequest),
Remove(Vec<usize>),
Switch(SwitchRequest),
Stash(StashRequest),
Enqueue(EnqueueRequest),
Start(StartRequest),
Restart(RestartRequest),
Pause(PauseRequest),
Kill(KillRequest),
Send(SendRequest),
EditRequest(Vec<usize>),
EditRestore(Vec<usize>),
EditedTasks(Vec<EditableTask>),
Env(EnvRequest),
Group(GroupRequest),
Parallel(ParallelRequest),
Status,
Log(LogRequest),
Stream(StreamRequest),
Reset(ResetRequest),
Clean(CleanRequest),
DaemonShutdown(ShutdownRequest),
}
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub enum TaskSelection {
TaskIds(Vec<usize>),
Group(String),
All,
}
#[derive(PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
pub struct AddRequest {
pub command: String,
pub path: PathBuf,
pub envs: HashMap<String, String>,
pub start_immediately: bool,
pub stashed: bool,
pub group: String,
pub enqueue_at: Option<DateTime<Local>>,
pub dependencies: Vec<usize>,
pub priority: Option<i32>,
pub label: Option<String>,
}
impl std::fmt::Debug for AddRequest {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Task")
.field("command", &self.command)
.field("path", &self.path)
.field("envs", &"hidden")
.field("start_immediately", &self.start_immediately)
.field("stashed", &self.stashed)
.field("group", &self.group)
.field("enqueue_at", &self.enqueue_at)
.field("dependencies", &self.dependencies)
.field("label", &self.label)
.finish()
}
}
impl_into_request!(AddRequest, Request::Add);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct SwitchRequest {
pub task_id_1: usize,
pub task_id_2: usize,
}
impl_into_request!(SwitchRequest, Request::Switch);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct StashRequest {
pub tasks: TaskSelection,
pub enqueue_at: Option<DateTime<Local>>,
}
impl_into_request!(StashRequest, Request::Stash);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct EnqueueRequest {
pub tasks: TaskSelection,
pub enqueue_at: Option<DateTime<Local>>,
}
impl_into_request!(EnqueueRequest, Request::Enqueue);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct StartRequest {
pub tasks: TaskSelection,
}
impl_into_request!(StartRequest, Request::Start);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct RestartRequest {
pub tasks: Vec<TaskToRestart>,
pub start_immediately: bool,
pub stashed: bool,
}
impl_into_request!(RestartRequest, Request::Restart);
#[derive(PartialEq, Eq, Clone, Debug, Default, Deserialize, Serialize)]
pub struct TaskToRestart {
pub task_id: usize,
pub original_command: String,
pub path: PathBuf,
pub label: Option<String>,
pub priority: i32,
}
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct PauseRequest {
pub tasks: TaskSelection,
pub wait: bool,
}
impl_into_request!(PauseRequest, Request::Pause);
#[derive(
PartialEq, Eq, Clone, Debug, Deserialize, Serialize, Display, EnumString, VariantNames,
)]
#[strum(ascii_case_insensitive)]
pub enum Signal {
#[strum(serialize = "sigint", serialize = "int", serialize = "2")]
SigInt,
#[strum(serialize = "sigkill", serialize = "kill", serialize = "9")]
SigKill,
#[strum(serialize = "sigterm", serialize = "term", serialize = "15")]
SigTerm,
#[strum(serialize = "sigcont", serialize = "cont", serialize = "18")]
SigCont,
#[strum(serialize = "sigstop", serialize = "stop", serialize = "19")]
SigStop,
}
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct KillRequest {
pub tasks: TaskSelection,
pub signal: Option<Signal>,
}
impl_into_request!(KillRequest, Request::Kill);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct SendRequest {
pub task_id: usize,
pub input: String,
}
impl_into_request!(SendRequest, Request::Send);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub enum EnvRequest {
Set {
task_id: usize,
key: String,
value: String,
},
Unset {
task_id: usize,
key: String,
},
}
impl_into_request!(EnvRequest, Request::Env);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub enum GroupRequest {
Add {
name: String,
parallel_tasks: Option<usize>,
},
Remove(String),
List,
}
impl_into_request!(GroupRequest, Request::Group);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub enum ResetTarget {
All,
Groups(Vec<String>),
}
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct ResetRequest {
pub target: ResetTarget,
}
impl_into_request!(ResetRequest, Request::Reset);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct CleanRequest {
pub successful_only: bool,
pub group: Option<String>,
}
impl_into_request!(CleanRequest, Request::Clean);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub enum ShutdownRequest {
Emergency,
Graceful,
}
impl_into_request!(ShutdownRequest, Request::DaemonShutdown);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct StreamRequest {
pub tasks: TaskSelection,
pub lines: Option<usize>,
}
impl_into_request!(StreamRequest, Request::Stream);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct LogRequest {
pub tasks: TaskSelection,
pub send_logs: bool,
pub lines: Option<usize>,
}
impl_into_request!(LogRequest, Request::Log);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct ParallelRequest {
pub parallel_tasks: usize,
pub group: String,
}
impl_into_request!(ParallelRequest, Request::Parallel);