1use crate::Result;
2use crate::daemon::{Daemon, RunOptions};
3use crate::daemon_id::DaemonId;
4use crate::env;
5use interprocess::local_socket::{GenericFilePath, Name, ToFsName};
6use miette::{Context, IntoDiagnostic};
7use std::path::PathBuf;
8
9pub(crate) mod batch;
10pub(crate) mod client;
11pub(crate) mod server;
12
13#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, strum::Display, strum::EnumIs)]
28#[allow(clippy::large_enum_variant)]
29pub enum IpcRequest {
30 Connect,
31 Clean,
32 Stop {
33 id: DaemonId,
34 },
35 GetActiveDaemons,
36 GetDisabledDaemons,
37 Run(RunOptions),
38 Enable {
39 id: DaemonId,
40 },
41 Disable {
42 id: DaemonId,
43 },
44 UpdateShellDir {
45 shell_pid: u32,
46 dir: PathBuf,
47 },
48 GetNotifications,
49 #[serde(skip)]
51 Invalid {
52 error: String,
53 },
54}
55
56#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, strum::Display, strum::EnumIs)]
57pub enum IpcResponse {
58 Ok,
59 Yes,
60 No,
61 Error(String),
62 Notifications(Vec<(log::LevelFilter, String)>),
63 ActiveDaemons(Vec<Daemon>),
64 DisabledDaemons(Vec<DaemonId>),
65 DaemonAlreadyRunning,
66 DaemonStart {
67 daemon: Daemon,
68 },
69 DaemonFailed {
70 error: String,
71 },
72 PortConflict {
74 port: u16,
75 process: String,
76 pid: u32,
77 },
78 NoAvailablePort {
80 start_port: u16,
81 attempts: u32,
82 },
83 DaemonReady {
84 daemon: Daemon,
85 },
86 DaemonFailedWithCode {
87 exit_code: Option<i32>,
88 },
89 DaemonWasNotRunning,
91 DaemonStopFailed {
93 error: String,
94 },
95 DaemonNotRunning,
97 DaemonNotFound,
98}
99fn fs_name(name: &str) -> Result<Name<'_>> {
100 let path = env::IPC_SOCK_DIR.join(name).with_extension("sock");
101 let fs_name = path.to_fs_name::<GenericFilePath>().into_diagnostic()?;
102 Ok(fs_name)
103}
104
105fn serialize<T: serde::Serialize>(msg: &T) -> Result<Vec<u8>> {
106 if *env::IPC_JSON {
107 serde_json::to_vec(msg)
108 .into_diagnostic()
109 .wrap_err("failed to serialize IPC message as JSON")
110 } else {
111 rmp_serde::to_vec(msg)
112 .into_diagnostic()
113 .wrap_err("failed to serialize IPC message as MessagePack")
114 }
115}
116
117fn deserialize<T: serde::de::DeserializeOwned>(bytes: &[u8]) -> Result<T> {
118 let mut bytes = bytes.to_vec();
119 bytes.pop();
120 let preview = std::str::from_utf8(&bytes).unwrap_or("<binary>");
121 trace!("msg: {preview:?}");
122 if *env::IPC_JSON {
123 serde_json::from_slice(&bytes)
124 .into_diagnostic()
125 .wrap_err("failed to deserialize IPC JSON response")
126 } else {
127 rmp_serde::from_slice(&bytes)
128 .into_diagnostic()
129 .wrap_err("failed to deserialize IPC MessagePack response")
130 }
131}