Rust · 7454 bytes Raw Blame History
1 //! Shared IPC protocol types for gartop.
2 //!
3 //! This crate defines the request/response types used for communication
4 //! between gartop daemon and clients (gartopctl, GUI, garbar).
5
6 use serde::{Deserialize, Serialize};
7 use std::path::PathBuf;
8
9 /// IPC commands sent to the gartop daemon.
10 #[derive(Debug, Clone, Serialize, Deserialize)]
11 #[serde(tag = "command", rename_all = "snake_case")]
12 pub enum Command {
13 /// Get daemon status.
14 Status,
15 /// Get current CPU stats.
16 GetCpu,
17 /// Get current memory stats.
18 GetMemory,
19 /// Get CPU history.
20 GetCpuHistory {
21 #[serde(default)]
22 count: Option<usize>,
23 },
24 /// Get memory history.
25 GetMemoryHistory {
26 #[serde(default)]
27 count: Option<usize>,
28 },
29 /// Get current network stats.
30 GetNetwork,
31 /// Get network history.
32 GetNetworkHistory {
33 #[serde(default)]
34 count: Option<usize>,
35 },
36 /// Get current disk I/O stats.
37 GetDisk,
38 /// Get disk I/O history.
39 GetDiskHistory {
40 #[serde(default)]
41 count: Option<usize>,
42 },
43 /// Get running processes.
44 GetProcesses {
45 #[serde(default)]
46 sort_by: Option<SortField>,
47 #[serde(default)]
48 limit: Option<usize>,
49 },
50 /// Kill a process by PID.
51 KillProcess {
52 pid: i32,
53 #[serde(default)]
54 signal: Option<i32>,
55 },
56 /// Subscribe to real-time updates.
57 Subscribe { events: Vec<String> },
58 /// Unsubscribe from events.
59 Unsubscribe { events: Vec<String> },
60 /// Reload configuration.
61 Reload,
62 /// Quit the daemon.
63 Quit,
64 }
65
66 /// Sort field for process list.
67 #[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
68 #[serde(rename_all = "snake_case")]
69 pub enum SortField {
70 #[default]
71 Cpu,
72 Memory,
73 DiskRead,
74 DiskWrite,
75 DiskTotal,
76 NetConnections,
77 NetTcp,
78 NetBandwidth,
79 Pid,
80 Name,
81 }
82
83 /// IPC response from gartop daemon.
84 #[derive(Debug, Clone, Serialize, Deserialize)]
85 pub struct Response {
86 pub success: bool,
87 #[serde(skip_serializing_if = "Option::is_none")]
88 pub data: Option<serde_json::Value>,
89 #[serde(skip_serializing_if = "Option::is_none")]
90 pub error: Option<String>,
91 }
92
93 impl Response {
94 /// Create a successful response with no data.
95 pub fn ok() -> Self {
96 Self {
97 success: true,
98 data: None,
99 error: None,
100 }
101 }
102
103 /// Create a successful response with data.
104 pub fn ok_with_data(data: impl Serialize) -> Self {
105 Self {
106 success: true,
107 data: serde_json::to_value(data).ok(),
108 error: None,
109 }
110 }
111
112 /// Create an error response.
113 pub fn err(message: impl Into<String>) -> Self {
114 Self {
115 success: false,
116 data: None,
117 error: Some(message.into()),
118 }
119 }
120 }
121
122 /// CPU usage statistics.
123 #[derive(Debug, Clone, Serialize, Deserialize)]
124 pub struct CpuStats {
125 /// Overall CPU usage percentage (0-100).
126 pub usage_percent: f64,
127 /// Per-core usage percentages.
128 pub per_core: Vec<f64>,
129 /// Number of cores.
130 pub core_count: usize,
131 /// Timestamp (milliseconds since epoch).
132 pub timestamp: u64,
133 }
134
135 /// Memory usage statistics.
136 #[derive(Debug, Clone, Serialize, Deserialize)]
137 pub struct MemoryStats {
138 /// Total memory in bytes.
139 pub total: u64,
140 /// Used memory in bytes (excluding cache/buffers).
141 pub used: u64,
142 /// Free memory in bytes.
143 pub free: u64,
144 /// Available memory in bytes.
145 pub available: u64,
146 /// Swap total in bytes.
147 pub swap_total: u64,
148 /// Swap used in bytes.
149 pub swap_used: u64,
150 /// Usage percentage (0-100).
151 pub usage_percent: f64,
152 /// Timestamp (milliseconds since epoch).
153 pub timestamp: u64,
154 }
155
156 /// Process information.
157 #[derive(Debug, Clone, Serialize, Deserialize)]
158 pub struct ProcessInfo {
159 /// Process ID.
160 pub pid: i32,
161 /// Process name.
162 pub name: String,
163 /// Command line.
164 pub cmdline: String,
165 /// CPU usage percentage.
166 pub cpu_percent: f64,
167 /// Memory usage percentage.
168 pub memory_percent: f64,
169 /// Resident set size in bytes.
170 pub rss: u64,
171 /// Virtual memory size in bytes.
172 pub vsize: u64,
173 /// Disk read bytes (cumulative).
174 pub io_read_bytes: u64,
175 /// Disk write bytes (cumulative).
176 pub io_write_bytes: u64,
177 /// Disk read rate in bytes/sec.
178 pub io_read_rate: f64,
179 /// Disk write rate in bytes/sec.
180 pub io_write_rate: f64,
181 /// Number of open network sockets (total).
182 pub net_connections: u32,
183 /// Number of TCP connections.
184 pub net_tcp: u32,
185 /// Number of UDP sockets.
186 pub net_udp: u32,
187 /// Number of listening sockets.
188 pub net_listen: u32,
189 /// Number of established TCP connections.
190 pub net_established: u32,
191 /// Network receive rate in bytes/sec.
192 pub net_rx_rate: f64,
193 /// Network transmit rate in bytes/sec.
194 pub net_tx_rate: f64,
195 /// Process state.
196 pub state: String,
197 /// User owning the process.
198 pub user: String,
199 }
200
201 /// Network interface statistics.
202 #[derive(Debug, Clone, Serialize, Deserialize)]
203 pub struct NetworkStats {
204 /// Interface name (e.g., "eth0", "wlan0").
205 pub interface: String,
206 /// Bytes received.
207 pub rx_bytes: u64,
208 /// Bytes transmitted.
209 pub tx_bytes: u64,
210 /// Packets received.
211 pub rx_packets: u64,
212 /// Packets transmitted.
213 pub tx_packets: u64,
214 /// Receive rate in bytes/sec (calculated from delta).
215 pub rx_rate: f64,
216 /// Transmit rate in bytes/sec (calculated from delta).
217 pub tx_rate: f64,
218 /// Timestamp (milliseconds since epoch).
219 pub timestamp: u64,
220 }
221
222 /// Disk I/O statistics.
223 #[derive(Debug, Clone, Serialize, Deserialize)]
224 pub struct DiskStats {
225 /// Device name (e.g., "sda", "nvme0n1").
226 pub device: String,
227 /// Bytes read.
228 pub read_bytes: u64,
229 /// Bytes written.
230 pub write_bytes: u64,
231 /// Read operations completed.
232 pub reads: u64,
233 /// Write operations completed.
234 pub writes: u64,
235 /// Read rate in bytes/sec (calculated from delta).
236 pub read_rate: f64,
237 /// Write rate in bytes/sec (calculated from delta).
238 pub write_rate: f64,
239 /// Timestamp (milliseconds since epoch).
240 pub timestamp: u64,
241 }
242
243 /// Events broadcast to subscribers.
244 #[derive(Debug, Clone, Serialize, Deserialize)]
245 #[serde(tag = "event", rename_all = "snake_case")]
246 pub enum Event {
247 /// CPU stats updated.
248 CpuUpdate(CpuStats),
249 /// Memory stats updated.
250 MemoryUpdate(MemoryStats),
251 /// Process list updated.
252 ProcessUpdate { processes: Vec<ProcessInfo> },
253 /// Network stats updated.
254 NetworkUpdate { interfaces: Vec<NetworkStats> },
255 /// Disk stats updated.
256 DiskUpdate { disks: Vec<DiskStats> },
257 }
258
259 /// Daemon status information.
260 #[derive(Debug, Clone, Serialize, Deserialize)]
261 pub struct StatusInfo {
262 /// Daemon version.
263 pub version: String,
264 /// Uptime in seconds.
265 pub uptime_secs: u64,
266 /// Sample interval in milliseconds.
267 pub sample_interval_ms: u64,
268 /// History buffer size.
269 pub history_size: usize,
270 }
271
272 /// Get the default socket path for gartop IPC.
273 pub fn socket_path() -> PathBuf {
274 let runtime_dir =
275 std::env::var("XDG_RUNTIME_DIR").unwrap_or_else(|_| "/tmp".to_string());
276 PathBuf::from(runtime_dir).join("gartop.sock")
277 }
278