1use std::{collections::HashMap, path::PathBuf};
2
3use chrono::prelude::*;
4use serde::{Deserialize, Serialize};
5use strum::{Display, EnumString, VariantNames};
6
7use crate::message::EditableTask;
8
9macro_rules! impl_into_request {
13 ($inner:ident, $variant:expr) => {
14 impl From<$inner> for Request {
15 fn from(message: $inner) -> Self {
16 $variant(message)
17 }
18 }
19 };
20}
21
22#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
25pub enum Request {
26 Add(AddRequest),
28 Remove(Vec<usize>),
30 Switch(SwitchRequest),
32 Stash(StashRequest),
34 Enqueue(EnqueueRequest),
36
37 Start(StartRequest),
39 Restart(RestartRequest),
41 Pause(PauseRequest),
43 Kill(KillRequest),
45
46 Send(SendRequest),
48
49 EditRequest(Vec<usize>),
52 EditRestore(Vec<usize>),
55 EditedTasks(Vec<EditableTask>),
57
58 Env(EnvRequest),
60
61 Group(GroupRequest),
62
63 Parallel(ParallelRequest),
65
66 Status,
68 Log(LogRequest),
70
71 Stream(StreamRequest),
73
74 Reset(ResetRequest),
76 Clean(CleanRequest),
78 DaemonShutdown(ShutdownRequest),
80}
81
82#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
86pub enum TaskSelection {
87 TaskIds(Vec<usize>),
88 Group(String),
89 All,
90}
91
92#[derive(PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
93pub struct AddRequest {
94 pub command: String,
95 pub path: PathBuf,
96 pub envs: HashMap<String, String>,
97 pub start_immediately: bool,
98 pub stashed: bool,
99 pub group: String,
100 pub enqueue_at: Option<DateTime<Local>>,
101 pub dependencies: Vec<usize>,
102 pub priority: Option<i32>,
103 pub label: Option<String>,
104}
105
106impl std::fmt::Debug for AddRequest {
112 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113 f.debug_struct("Task")
114 .field("command", &self.command)
115 .field("path", &self.path)
116 .field("envs", &"hidden")
117 .field("start_immediately", &self.start_immediately)
118 .field("stashed", &self.stashed)
119 .field("group", &self.group)
120 .field("enqueue_at", &self.enqueue_at)
121 .field("dependencies", &self.dependencies)
122 .field("label", &self.label)
123 .finish()
124 }
125}
126impl_into_request!(AddRequest, Request::Add);
127
128#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
129pub struct SwitchRequest {
130 pub task_id_1: usize,
131 pub task_id_2: usize,
132}
133impl_into_request!(SwitchRequest, Request::Switch);
134
135#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
136pub struct StashRequest {
137 pub tasks: TaskSelection,
138 pub enqueue_at: Option<DateTime<Local>>,
139}
140impl_into_request!(StashRequest, Request::Stash);
141
142#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
143pub struct EnqueueRequest {
144 pub tasks: TaskSelection,
145 pub enqueue_at: Option<DateTime<Local>>,
146}
147impl_into_request!(EnqueueRequest, Request::Enqueue);
148
149#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
150pub struct StartRequest {
151 pub tasks: TaskSelection,
152}
153impl_into_request!(StartRequest, Request::Start);
154
155#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
158pub struct RestartRequest {
159 pub tasks: Vec<TaskToRestart>,
160 pub start_immediately: bool,
161 pub stashed: bool,
162}
163impl_into_request!(RestartRequest, Request::Restart);
164
165#[derive(PartialEq, Eq, Clone, Debug, Default, Deserialize, Serialize)]
166pub struct TaskToRestart {
167 pub task_id: usize,
168 pub original_command: String,
170 pub path: PathBuf,
172 pub label: Option<String>,
174 pub priority: i32,
176}
177
178#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
179pub struct PauseRequest {
180 pub tasks: TaskSelection,
181 pub wait: bool,
182}
183impl_into_request!(PauseRequest, Request::Pause);
184
185#[derive(
190 PartialEq, Eq, Clone, Debug, Deserialize, Serialize, Display, EnumString, VariantNames,
191)]
192#[strum(ascii_case_insensitive)]
193pub enum Signal {
194 #[strum(serialize = "sigint", serialize = "int", serialize = "2")]
195 SigInt,
196 #[strum(serialize = "sigkill", serialize = "kill", serialize = "9")]
197 SigKill,
198 #[strum(serialize = "sigterm", serialize = "term", serialize = "15")]
199 SigTerm,
200 #[strum(serialize = "sigcont", serialize = "cont", serialize = "18")]
201 SigCont,
202 #[strum(serialize = "sigstop", serialize = "stop", serialize = "19")]
203 SigStop,
204}
205
206#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
207pub struct KillRequest {
208 pub tasks: TaskSelection,
209 pub signal: Option<Signal>,
210}
211impl_into_request!(KillRequest, Request::Kill);
212
213#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
214pub struct SendRequest {
215 pub task_id: usize,
216 pub input: String,
217}
218impl_into_request!(SendRequest, Request::Send);
219
220#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
221pub enum EnvRequest {
222 Set {
223 task_id: usize,
224 key: String,
225 value: String,
226 },
227 Unset {
228 task_id: usize,
229 key: String,
230 },
231}
232impl_into_request!(EnvRequest, Request::Env);
233
234#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
235pub enum GroupRequest {
236 Add {
237 name: String,
238 parallel_tasks: Option<usize>,
239 },
240 Remove(String),
241 List,
242}
243impl_into_request!(GroupRequest, Request::Group);
244
245#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
246pub enum ResetTarget {
247 All,
249 Groups(Vec<String>),
251}
252
253#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
254pub struct ResetRequest {
255 pub target: ResetTarget,
256}
257impl_into_request!(ResetRequest, Request::Reset);
258
259#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
260pub struct CleanRequest {
261 pub successful_only: bool,
262
263 pub group: Option<String>,
264}
265impl_into_request!(CleanRequest, Request::Clean);
266
267#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
269pub enum ShutdownRequest {
270 Emergency,
272 Graceful,
274}
275impl_into_request!(ShutdownRequest, Request::DaemonShutdown);
276
277#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
285pub struct StreamRequest {
286 pub tasks: TaskSelection,
287 pub lines: Option<usize>,
288}
289impl_into_request!(StreamRequest, Request::Stream);
290
291#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
297pub struct LogRequest {
298 pub tasks: TaskSelection,
299 pub send_logs: bool,
300 pub lines: Option<usize>,
301}
302impl_into_request!(LogRequest, Request::Log);
303
304#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
305pub struct ParallelRequest {
306 pub parallel_tasks: usize,
307 pub group: String,
308}
309impl_into_request!(ParallelRequest, Request::Parallel);