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(
191 PartialEq, Eq, Clone, Debug, Deserialize, Serialize, Display, EnumString, VariantNames,
192)]
193#[strum(ascii_case_insensitive)]
194pub enum Signal {
195 #[strum(serialize = "sigint", serialize = "int", serialize = "2")]
196 SigInt,
197 #[strum(serialize = "sigkill", serialize = "kill", serialize = "9")]
198 SigKill,
199 #[strum(serialize = "sigterm", serialize = "term", serialize = "15")]
200 SigTerm,
201 #[strum(serialize = "sigcont", serialize = "cont", serialize = "18")]
202 SigCont,
203 #[strum(serialize = "sigstop", serialize = "stop", serialize = "19")]
204 SigStop,
205}
206
207#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
208pub struct KillRequest {
209 pub tasks: TaskSelection,
210 pub signal: Option<Signal>,
211}
212impl_into_request!(KillRequest, Request::Kill);
213
214#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
215pub struct SendRequest {
216 pub task_id: usize,
217 pub input: String,
218}
219impl_into_request!(SendRequest, Request::Send);
220
221#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
222pub enum EnvRequest {
223 Set {
224 task_id: usize,
225 key: String,
226 value: String,
227 },
228 Unset {
229 task_id: usize,
230 key: String,
231 },
232}
233impl_into_request!(EnvRequest, Request::Env);
234
235#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
236pub enum GroupRequest {
237 Add {
238 name: String,
239 parallel_tasks: Option<usize>,
240 },
241 Remove(String),
242 List,
243}
244impl_into_request!(GroupRequest, Request::Group);
245
246#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
247pub enum ResetTarget {
248 All,
250 Groups(Vec<String>),
252}
253
254#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
255pub struct ResetRequest {
256 pub target: ResetTarget,
257}
258impl_into_request!(ResetRequest, Request::Reset);
259
260#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
261pub struct CleanRequest {
262 pub successful_only: bool,
263
264 pub group: Option<String>,
265}
266impl_into_request!(CleanRequest, Request::Clean);
267
268#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
270pub enum ShutdownRequest {
271 Emergency,
273 Graceful,
275}
276impl_into_request!(ShutdownRequest, Request::DaemonShutdown);
277
278#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
286pub struct StreamRequest {
287 pub tasks: TaskSelection,
288 pub lines: Option<usize>,
289}
290impl_into_request!(StreamRequest, Request::Stream);
291
292#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
298pub struct LogRequest {
299 pub tasks: TaskSelection,
300 pub send_logs: bool,
301 pub lines: Option<usize>,
302}
303impl_into_request!(LogRequest, Request::Log);
304
305#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
306pub struct ParallelRequest {
307 pub parallel_tasks: usize,
308 pub group: String,
309}
310impl_into_request!(ParallelRequest, Request::Parallel);