shell_compose/
command.rs

1use crate::{DispatcherError, Job, JobId, LogLine, ProcInfo};
2use clap::{Parser, Subcommand};
3use serde::{Deserialize, Serialize};
4
5#[derive(Parser, Debug)]
6#[command(version, about, long_about = None)]
7pub struct Cli;
8
9/// Shared commands with background service
10#[derive(Subcommand, Debug, Serialize, Deserialize)]
11pub enum ExecCommand {
12    /// Execute command
13    Run {
14        /// Command arguments
15        args: Vec<String>,
16    },
17    /// Execute command with cron schedule
18    Runat {
19        /// Cron expression
20        at: String,
21        /// Command arguments
22        args: Vec<String>,
23    },
24    /// Start service
25    Start {
26        /// Service name
27        service: String,
28    },
29    /// Start service group
30    Up {
31        /// Service group name
32        group: String,
33    },
34}
35
36/// Additional commands
37#[derive(Subcommand, Debug, Serialize, Deserialize)]
38pub enum CliCommand {
39    /// Stop service group
40    Down {
41        /// Service group name
42        group: String,
43    },
44    /// Stop job
45    Stop {
46        /// Job id
47        job_id: JobId,
48    },
49    /// List processes
50    Ps,
51    /// List active jobs
52    Jobs,
53    /// Show process logs
54    Logs {
55        /// Job id or service name
56        job_or_service: Option<String>,
57        // --tail: Option<usize>,
58    },
59    /// Stop all processes
60    Exit,
61}
62
63/// IPC messages
64#[derive(Debug, Serialize, Deserialize)]
65pub enum Message {
66    // cli <-> Listener
67    Connect,
68    // cli -> Listener
69    ExecCommand(ExecCommand),
70    CliCommand(CliCommand),
71    // cli <- Listener
72    PsInfo(Vec<ProcInfo>),
73    JobInfo(Vec<Job>),
74    LogLine(LogLine),
75    Ok,
76    JobsStarted(Vec<JobId>),
77    Err(String),
78}
79
80impl From<ExecCommand> for Message {
81    fn from(cmd: ExecCommand) -> Self {
82        Message::ExecCommand(cmd)
83    }
84}
85
86impl From<CliCommand> for Message {
87    fn from(cmd: CliCommand) -> Self {
88        Message::CliCommand(cmd)
89    }
90}
91
92/// Convert execution result into response message
93impl From<Result<(), DispatcherError>> for Message {
94    fn from(res: Result<(), DispatcherError>) -> Self {
95        if let Err(e) = res {
96            Message::Err(format!("{e}"))
97        } else {
98            Message::Ok
99        }
100    }
101}