use std::collections::{BTreeMap, HashMap};
use std::path::PathBuf;
use chrono::prelude::*;
use serde_derive::{Deserialize, Serialize};
use strum_macros::{Display, EnumString};
use crate::state::{Group, State};
use crate::task::Task;
macro_rules! impl_into_message {
($inner:ident, $variant:expr) => {
impl From<$inner> for Message {
fn from(message: $inner) -> Self {
$variant(message)
}
}
};
}
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub enum Message {
Add(AddMessage),
Remove(Vec<usize>),
Switch(SwitchMessage),
Stash(Vec<usize>),
Enqueue(EnqueueMessage),
Start(StartMessage),
Restart(RestartMessage),
Pause(PauseMessage),
Kill(KillMessage),
Send(SendMessage),
EditRequest(usize),
EditRestore(usize),
EditResponse(EditResponseMessage),
Edit(EditMessage),
Group(GroupMessage),
GroupResponse(GroupResponseMessage),
Status,
StatusResponse(Box<State>),
Log(LogRequestMessage),
LogResponse(BTreeMap<usize, TaskLogMessage>),
StreamRequest(StreamRequestMessage),
Stream(String),
Reset(ResetMessage),
Clean(CleanMessage),
DaemonShutdown(Shutdown),
Success(String),
Failure(String),
Close,
Parallel(ParallelMessage),
}
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub enum TaskSelection {
TaskIds(Vec<usize>),
Group(String),
All,
}
#[derive(PartialEq, Eq, Clone, Deserialize, Serialize)]
pub struct AddMessage {
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>,
pub print_task_id: bool,
}
impl std::fmt::Debug for AddMessage {
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)
.field("print_task_id", &self.print_task_id)
.finish()
}
}
impl_into_message!(AddMessage, Message::Add);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct SwitchMessage {
pub task_id_1: usize,
pub task_id_2: usize,
}
impl_into_message!(SwitchMessage, Message::Switch);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct EnqueueMessage {
pub task_ids: Vec<usize>,
pub enqueue_at: Option<DateTime<Local>>,
}
impl_into_message!(EnqueueMessage, Message::Enqueue);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct StartMessage {
pub tasks: TaskSelection,
}
impl_into_message!(StartMessage, Message::Start);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct RestartMessage {
pub tasks: Vec<TaskToRestart>,
pub start_immediately: bool,
pub stashed: bool,
}
impl_into_message!(RestartMessage, Message::Restart);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct TaskToRestart {
pub task_id: usize,
pub command: Option<String>,
pub path: Option<PathBuf>,
pub label: Option<String>,
pub delete_label: bool,
pub priority: Option<i32>,
}
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct PauseMessage {
pub tasks: TaskSelection,
pub wait: bool,
}
impl_into_message!(PauseMessage, Message::Pause);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize, Display, EnumString)]
#[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 KillMessage {
pub tasks: TaskSelection,
pub signal: Option<Signal>,
}
impl_into_message!(KillMessage, Message::Kill);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct SendMessage {
pub task_id: usize,
pub input: String,
}
impl_into_message!(SendMessage, Message::Send);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct EditResponseMessage {
pub task_id: usize,
pub command: String,
pub path: PathBuf,
pub label: Option<String>,
pub priority: i32,
}
impl_into_message!(EditResponseMessage, Message::EditResponse);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct EditMessage {
pub task_id: usize,
pub command: Option<String>,
pub path: Option<PathBuf>,
pub label: Option<String>,
pub delete_label: bool,
pub priority: Option<i32>,
}
impl_into_message!(EditMessage, Message::Edit);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub enum GroupMessage {
Add {
name: String,
parallel_tasks: Option<usize>,
},
Remove(String),
List,
}
impl_into_message!(GroupMessage, Message::Group);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct GroupResponseMessage {
pub groups: BTreeMap<String, Group>,
}
impl_into_message!(GroupResponseMessage, Message::GroupResponse);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct ResetMessage {}
impl_into_message!(ResetMessage, Message::Reset);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct CleanMessage {
#[serde(default = "bool::default")]
pub successful_only: bool,
#[serde(default = "Option::default")]
pub group: Option<String>,
}
impl_into_message!(CleanMessage, Message::Clean);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub enum Shutdown {
Emergency,
Graceful,
}
impl_into_message!(Shutdown, Message::DaemonShutdown);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct StreamRequestMessage {
pub task_id: Option<usize>,
pub lines: Option<usize>,
}
impl_into_message!(StreamRequestMessage, Message::StreamRequest);
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct LogRequestMessage {
pub task_ids: Vec<usize>,
pub send_logs: bool,
pub lines: Option<usize>,
}
impl_into_message!(LogRequestMessage, Message::Log);
#[derive(PartialEq, Eq, Clone, Deserialize, Serialize)]
pub struct TaskLogMessage {
pub task: Task,
#[serde(default = "bool::default")]
pub output_complete: bool,
pub output: Option<Vec<u8>>,
}
impl std::fmt::Debug for TaskLogMessage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("TaskLogMessage")
.field("task", &self.task)
.field("output_complete", &self.output_complete)
.field("output", &"hidden")
.finish()
}
}
#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
pub struct ParallelMessage {
pub parallel_tasks: usize,
pub group: String,
}
impl_into_message!(ParallelMessage, Message::Parallel);
pub fn create_success_message<T: ToString>(text: T) -> Message {
Message::Success(text.to_string())
}
pub fn create_failure_message<T: ToString>(text: T) -> Message {
Message::Failure(text.to_string())
}