1use crate::Result;
2use crate::daemon::{Daemon, RunOptions};
3use crate::env;
4use interprocess::local_socket::{GenericFilePath, Name, ToFsName};
5use miette::IntoDiagnostic;
6use std::path::PathBuf;
7
8pub(crate) mod client;
9pub(crate) mod server;
10
11#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, strum::Display, strum::EnumIs)]
26pub enum IpcRequest {
27 Connect,
28 Clean,
29 Stop { id: String },
30 GetActiveDaemons,
31 GetDisabledDaemons,
32 Run(RunOptions),
33 Enable { id: String },
34 Disable { id: String },
35 UpdateShellDir { shell_pid: u32, dir: PathBuf },
36 GetNotifications,
37}
38
39#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, strum::Display, strum::EnumIs)]
40pub enum IpcResponse {
41 Ok,
42 Yes,
43 No,
44 Error(String),
45 Notifications(Vec<(log::LevelFilter, String)>),
46 ActiveDaemons(Vec<Daemon>),
47 DisabledDaemons(Vec<String>),
48 DaemonAlreadyStopped,
49 DaemonAlreadyRunning,
50 DaemonStart { daemon: Daemon },
51 DaemonFailed { error: String },
52 DaemonReady { daemon: Daemon },
53 DaemonFailedWithCode { exit_code: Option<i32> },
54}
55
56fn fs_name(name: &str) -> Result<Name<'_>> {
57 let path = env::IPC_SOCK_DIR.join(name).with_extension("sock");
58 let fs_name = path.to_fs_name::<GenericFilePath>().into_diagnostic()?;
59 Ok(fs_name)
60}
61
62fn serialize<T: serde::Serialize>(msg: &T) -> Result<Vec<u8>> {
63 let msg = if *env::IPC_JSON {
64 serde_json::to_vec(msg).into_diagnostic()?
65 } else {
66 rmp_serde::to_vec(msg).into_diagnostic()?
67 };
68 Ok(msg)
69}
70
71fn deserialize<T: serde::de::DeserializeOwned>(bytes: &[u8]) -> Result<T> {
72 let mut bytes = bytes.to_vec();
73 bytes.pop();
74 trace!("msg: {:?}", std::str::from_utf8(&bytes).unwrap_or_default());
75 let msg = if *env::IPC_JSON {
76 serde_json::from_slice(&bytes).into_diagnostic()?
77 } else {
78 rmp_serde::from_slice(&bytes).into_diagnostic()?
79 };
80 Ok(msg)
81}