pueue_lib/message/
response.rs

1use std::collections::BTreeMap;
2
3use chrono::prelude::*;
4use serde::{Deserialize, Serialize};
5
6use crate::{
7    message::EditableTask,
8    state::{Group, State},
9    task::Task,
10};
11
12/// Macro to simplify creating success_messages
13#[macro_export]
14macro_rules! success_msg {
15    ($($arg:tt)*) => {{
16        create_success_response(format!($($arg)*))
17    }}
18}
19
20/// Macro to simplify creating failure_messages
21#[macro_export]
22macro_rules! failure_msg {
23    ($($arg:tt)*) => {{
24        create_failure_response(format!($($arg)*))
25    }}
26}
27
28pub fn create_success_response<T: ToString>(text: T) -> Response {
29    Response::Success(text.to_string())
30}
31
32pub fn create_failure_response<T: ToString>(text: T) -> Response {
33    Response::Failure(text.to_string())
34}
35
36/// Macro to simplify creating [From] implementations for each variant-contained
37/// Response; e.g. `impl_into_response!(AddRequest, Response::Add)` to implement
38/// use `AddedTaskResponse::into()` and get a [Response::AddedTask] value.
39macro_rules! impl_into_response {
40    ($inner:ty, $variant:expr) => {
41        impl From<$inner> for Response {
42            fn from(message: $inner) -> Self {
43                $variant(message)
44            }
45        }
46    };
47}
48
49/// This is the message for messages sent **to** the daemon. \
50/// Everything that's send by the client is represented using by this enum.
51#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
52pub enum Response {
53    AddedTask(AddedTaskResponse),
54
55    /// The daemon locked the tasks and responds with the tasks' details.
56    Edit(Vec<EditableTask>),
57
58    Status(Box<State>),
59
60    /// The log returned from the daemon for a bunch of [`Task`]s
61    /// This is the response to [`super::Request::Log`]
62    Log(BTreeMap<usize, TaskLogResponse>),
63
64    Group(GroupResponse),
65
66    /// The next chunk of output, that's send to the client.
67    Stream(StreamResponse),
68
69    Success(String),
70    Failure(String),
71
72    /// Simply notify the client that the connection is now closed.
73    /// This is used to, for instance, close a `follow` stream if the task finished.
74    Close,
75}
76
77impl Response {
78    pub fn success(&self) -> bool {
79        matches!(&self, Self::AddedTask(_) | Self::Success(_))
80    }
81}
82
83#[derive(PartialEq, Eq, Clone, Debug, Default, Deserialize, Serialize)]
84pub struct AddedTaskResponse {
85    pub task_id: usize,
86    pub enqueue_at: Option<DateTime<Local>>,
87    pub group_is_paused: bool,
88}
89impl_into_response!(AddedTaskResponse, Response::AddedTask);
90
91/// Helper struct for sending tasks and their log output to the client.
92#[derive(PartialEq, Eq, Clone, Deserialize, Serialize)]
93pub struct TaskLogResponse {
94    pub task: Task,
95    /// Indicates whether the log output has been truncated or not.
96    pub output_complete: bool,
97    pub output: Option<Vec<u8>>,
98}
99impl_into_response!(BTreeMap<usize, TaskLogResponse>, Response::Log);
100
101/// We use a custom `Debug` implementation for [TaskLogResponse], as the `output` field
102/// has too much info in it and renders log output unreadable.
103impl std::fmt::Debug for TaskLogResponse {
104    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105        f.debug_struct("TaskLogResponse")
106            .field("task", &self.task)
107            .field("output_complete", &self.output_complete)
108            .field("output", &"hidden")
109            .finish()
110    }
111}
112
113/// Group info send by the daemon.
114#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
115pub struct GroupResponse {
116    pub groups: BTreeMap<String, Group>,
117}
118impl_into_response!(GroupResponse, Response::Group);
119
120/// Live log output returned by the daemon.
121///
122/// The logs are ordered by task id.
123#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
124pub struct StreamResponse {
125    pub logs: BTreeMap<usize, String>,
126}
127impl_into_response!(StreamResponse, Response::Stream);