1use crate::Result;
2use crate::daemon::{Daemon, RunOptions};
3use crate::env;
4use interprocess::local_socket::{GenericFilePath, Name, ToFsName};
5use miette::{Context, 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 if *env::IPC_JSON {
64 serde_json::to_vec(msg)
65 .into_diagnostic()
66 .wrap_err("failed to serialize IPC message as JSON")
67 } else {
68 rmp_serde::to_vec(msg)
69 .into_diagnostic()
70 .wrap_err("failed to serialize IPC message as MessagePack")
71 }
72}
73
74fn deserialize<T: serde::de::DeserializeOwned>(bytes: &[u8]) -> Result<T> {
75 let mut bytes = bytes.to_vec();
76 bytes.pop();
77 let preview = std::str::from_utf8(&bytes).unwrap_or("<binary>");
78 trace!("msg: {:?}", preview);
79 if *env::IPC_JSON {
80 serde_json::from_slice(&bytes)
81 .into_diagnostic()
82 .wrap_err("failed to deserialize IPC JSON response")
83 } else {
84 rmp_serde::from_slice(&bytes)
85 .into_diagnostic()
86 .wrap_err("failed to deserialize IPC MessagePack response")
87 }
88}