Rust · 9520 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 current temperature stats.
44 GetTemperature,
45 /// Get current GPU stats.
46 GetGpu,
47 /// Get running processes.
48 GetProcesses {
49 #[serde(default)]
50 sort_by: Option<SortField>,
51 #[serde(default)]
52 limit: Option<usize>,
53 },
54 /// Kill a process by PID.
55 KillProcess {
56 pid: i32,
57 #[serde(default)]
58 signal: Option<i32>,
59 },
60 /// Subscribe to real-time updates.
61 Subscribe { events: Vec<String> },
62 /// Unsubscribe from events.
63 Unsubscribe { events: Vec<String> },
64 /// Reload configuration.
65 Reload,
66 /// Quit the daemon.
67 Quit,
68 }
69
70 /// Sort field for process list.
71 #[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
72 #[serde(rename_all = "snake_case")]
73 pub enum SortField {
74 #[default]
75 Cpu,
76 Memory,
77 DiskRead,
78 DiskWrite,
79 DiskTotal,
80 NetConnections,
81 NetTcp,
82 NetBandwidth,
83 Pid,
84 Name,
85 }
86
87 /// IPC response from gartop daemon.
88 #[derive(Debug, Clone, Serialize, Deserialize)]
89 pub struct Response {
90 pub success: bool,
91 #[serde(skip_serializing_if = "Option::is_none")]
92 pub data: Option<serde_json::Value>,
93 #[serde(skip_serializing_if = "Option::is_none")]
94 pub error: Option<String>,
95 }
96
97 impl Response {
98 /// Create a successful response with no data.
99 pub fn ok() -> Self {
100 Self {
101 success: true,
102 data: None,
103 error: None,
104 }
105 }
106
107 /// Create a successful response with data.
108 pub fn ok_with_data(data: impl Serialize) -> Self {
109 Self {
110 success: true,
111 data: serde_json::to_value(data).ok(),
112 error: None,
113 }
114 }
115
116 /// Create an error response.
117 pub fn err(message: impl Into<String>) -> Self {
118 Self {
119 success: false,
120 data: None,
121 error: Some(message.into()),
122 }
123 }
124 }
125
126 /// CPU usage statistics.
127 #[derive(Debug, Clone, Serialize, Deserialize)]
128 pub struct CpuStats {
129 /// Overall CPU usage percentage (0-100).
130 pub usage_percent: f64,
131 /// Per-core usage percentages.
132 pub per_core: Vec<f64>,
133 /// Number of cores.
134 pub core_count: usize,
135 /// Timestamp (milliseconds since epoch).
136 pub timestamp: u64,
137 }
138
139 /// Memory usage statistics.
140 #[derive(Debug, Clone, Serialize, Deserialize)]
141 pub struct MemoryStats {
142 /// Total memory in bytes.
143 pub total: u64,
144 /// Used memory in bytes (excluding cache/buffers).
145 pub used: u64,
146 /// Free memory in bytes.
147 pub free: u64,
148 /// Available memory in bytes.
149 pub available: u64,
150 /// Swap total in bytes.
151 pub swap_total: u64,
152 /// Swap used in bytes.
153 pub swap_used: u64,
154 /// Usage percentage (0-100).
155 pub usage_percent: f64,
156 /// Timestamp (milliseconds since epoch).
157 pub timestamp: u64,
158 }
159
160 /// Process information.
161 #[derive(Debug, Clone, Serialize, Deserialize)]
162 pub struct ProcessInfo {
163 /// Process ID.
164 pub pid: i32,
165 /// Parent process ID.
166 pub ppid: i32,
167 /// Process name.
168 pub name: String,
169 /// Command line.
170 pub cmdline: String,
171 /// CPU usage percentage.
172 pub cpu_percent: f64,
173 /// Memory usage percentage.
174 pub memory_percent: f64,
175 /// Resident set size in bytes.
176 pub rss: u64,
177 /// Virtual memory size in bytes.
178 pub vsize: u64,
179 /// Disk read bytes (cumulative).
180 pub io_read_bytes: u64,
181 /// Disk write bytes (cumulative).
182 pub io_write_bytes: u64,
183 /// Disk read rate in bytes/sec.
184 pub io_read_rate: f64,
185 /// Disk write rate in bytes/sec.
186 pub io_write_rate: f64,
187 /// Number of open network sockets (total).
188 pub net_connections: u32,
189 /// Number of TCP connections.
190 pub net_tcp: u32,
191 /// Number of UDP sockets.
192 pub net_udp: u32,
193 /// Number of listening sockets.
194 pub net_listen: u32,
195 /// Number of established TCP connections.
196 pub net_established: u32,
197 /// Network receive rate in bytes/sec.
198 pub net_rx_rate: f64,
199 /// Network transmit rate in bytes/sec.
200 pub net_tx_rate: f64,
201 /// Process state.
202 pub state: String,
203 /// User owning the process.
204 pub user: String,
205 /// Container ID (if running in a container, e.g., Docker/Podman).
206 pub container: Option<String>,
207 }
208
209 /// Network interface statistics.
210 #[derive(Debug, Clone, Serialize, Deserialize)]
211 pub struct NetworkStats {
212 /// Interface name (e.g., "eth0", "wlan0").
213 pub interface: String,
214 /// Bytes received.
215 pub rx_bytes: u64,
216 /// Bytes transmitted.
217 pub tx_bytes: u64,
218 /// Packets received.
219 pub rx_packets: u64,
220 /// Packets transmitted.
221 pub tx_packets: u64,
222 /// Receive rate in bytes/sec (calculated from delta).
223 pub rx_rate: f64,
224 /// Transmit rate in bytes/sec (calculated from delta).
225 pub tx_rate: f64,
226 /// Timestamp (milliseconds since epoch).
227 pub timestamp: u64,
228 }
229
230 /// Disk I/O statistics.
231 #[derive(Debug, Clone, Serialize, Deserialize)]
232 pub struct DiskStats {
233 /// Device name (e.g., "sda", "nvme0n1").
234 pub device: String,
235 /// Bytes read.
236 pub read_bytes: u64,
237 /// Bytes written.
238 pub write_bytes: u64,
239 /// Read operations completed.
240 pub reads: u64,
241 /// Write operations completed.
242 pub writes: u64,
243 /// Read rate in bytes/sec (calculated from delta).
244 pub read_rate: f64,
245 /// Write rate in bytes/sec (calculated from delta).
246 pub write_rate: f64,
247 /// Timestamp (milliseconds since epoch).
248 pub timestamp: u64,
249 }
250
251 /// Individual temperature sensor reading.
252 #[derive(Debug, Clone, Serialize, Deserialize)]
253 pub struct TempSensor {
254 /// Sensor label (e.g., "Core 0", "Package id 0", "GPU").
255 pub label: String,
256 /// Hardware device name (e.g., "coretemp", "k10temp", "amdgpu").
257 pub device: String,
258 /// Temperature in degrees Celsius.
259 pub temp_celsius: f64,
260 /// Critical temperature threshold (if available).
261 pub critical: Option<f64>,
262 /// High temperature threshold (if available).
263 pub high: Option<f64>,
264 }
265
266 /// Temperature statistics from all sensors.
267 #[derive(Debug, Clone, Serialize, Deserialize)]
268 pub struct TempStats {
269 /// All temperature sensor readings.
270 pub sensors: Vec<TempSensor>,
271 /// Timestamp (milliseconds since epoch).
272 pub timestamp: u64,
273 }
274
275 /// Individual GPU device stats.
276 #[derive(Debug, Clone, Serialize, Deserialize)]
277 pub struct GpuDevice {
278 /// Device name (e.g., "card0", "nvidia0").
279 pub name: String,
280 /// GPU vendor/model if available.
281 pub model: String,
282 /// GPU utilization percentage (0-100).
283 pub usage_percent: f64,
284 /// VRAM used in bytes.
285 pub vram_used: u64,
286 /// VRAM total in bytes.
287 pub vram_total: u64,
288 /// GPU core clock in MHz (if available).
289 pub clock_mhz: Option<u32>,
290 /// GPU temperature in Celsius (if available).
291 pub temp_celsius: Option<f64>,
292 /// Power usage in watts (if available).
293 pub power_watts: Option<f64>,
294 }
295
296 /// GPU statistics from all devices.
297 #[derive(Debug, Clone, Serialize, Deserialize)]
298 pub struct GpuStats {
299 /// All GPU device readings.
300 pub devices: Vec<GpuDevice>,
301 /// Timestamp (milliseconds since epoch).
302 pub timestamp: u64,
303 }
304
305 /// Events broadcast to subscribers.
306 #[derive(Debug, Clone, Serialize, Deserialize)]
307 #[serde(tag = "event", rename_all = "snake_case")]
308 pub enum Event {
309 /// CPU stats updated.
310 CpuUpdate(CpuStats),
311 /// Memory stats updated.
312 MemoryUpdate(MemoryStats),
313 /// Process list updated.
314 ProcessUpdate { processes: Vec<ProcessInfo> },
315 /// Network stats updated.
316 NetworkUpdate { interfaces: Vec<NetworkStats> },
317 /// Disk stats updated.
318 DiskUpdate { disks: Vec<DiskStats> },
319 /// Temperature stats updated.
320 TempUpdate(TempStats),
321 /// GPU stats updated.
322 GpuUpdate(GpuStats),
323 }
324
325 /// Daemon status information.
326 #[derive(Debug, Clone, Serialize, Deserialize)]
327 pub struct StatusInfo {
328 /// Daemon version.
329 pub version: String,
330 /// Uptime in seconds.
331 pub uptime_secs: u64,
332 /// Sample interval in milliseconds.
333 pub sample_interval_ms: u64,
334 /// History buffer size.
335 pub history_size: usize,
336 }
337
338 /// Get the default socket path for gartop IPC.
339 pub fn socket_path() -> PathBuf {
340 let runtime_dir =
341 std::env::var("XDG_RUNTIME_DIR").unwrap_or_else(|_| "/tmp".to_string());
342 PathBuf::from(runtime_dir).join("gartop.sock")
343 }
344