Rust · 2022 bytes Raw Blame History
1 //! CLI control utility for gargears daemon
2
3 use anyhow::{Context, Result};
4 use clap::{Parser, Subcommand};
5 use gargears_ipc::{socket_path, Command, Response};
6 use std::io::{BufRead, BufReader, Write};
7 use std::os::unix::net::UnixStream;
8
9 #[derive(Parser, Debug)]
10 #[command(name = "gargearsctl")]
11 #[command(about = "Control the gargears daemon")]
12 struct Args {
13 #[command(subcommand)]
14 command: CtlCommand,
15 }
16
17 #[derive(Subcommand, Debug)]
18 enum CtlCommand {
19 /// Show the gargears window
20 Show,
21 /// Hide the gargears window
22 Hide,
23 /// Toggle gargears window visibility
24 Toggle,
25 /// Get daemon status
26 Status,
27 /// Quit the daemon
28 Quit,
29 }
30
31 fn main() -> Result<()> {
32 let args = Args::parse();
33
34 let command = match args.command {
35 CtlCommand::Show => Command::Show,
36 CtlCommand::Hide => Command::Hide,
37 CtlCommand::Toggle => Command::Toggle,
38 CtlCommand::Status => Command::Status,
39 CtlCommand::Quit => Command::Quit,
40 };
41
42 let response = send_command(&command)?;
43
44 if response.success {
45 if let Some(data) = response.data {
46 println!("{}", serde_json::to_string_pretty(&data)?);
47 } else {
48 println!("OK");
49 }
50 } else {
51 eprintln!("Error: {}", response.error.unwrap_or_else(|| "Unknown error".into()));
52 std::process::exit(1);
53 }
54
55 Ok(())
56 }
57
58 fn send_command(command: &Command) -> Result<Response> {
59 let path = socket_path();
60
61 let mut stream = UnixStream::connect(&path)
62 .with_context(|| format!("Failed to connect to gargears daemon at {:?}", path))?;
63
64 // Send command
65 let json = serde_json::to_string(command)?;
66 writeln!(stream, "{}", json)?;
67 stream.flush()?;
68
69 // Read response
70 let mut reader = BufReader::new(stream);
71 let mut line = String::new();
72 reader.read_line(&mut line)?;
73
74 let response: Response = serde_json::from_str(&line)
75 .with_context(|| "Failed to parse daemon response")?;
76
77 Ok(response)
78 }
79