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