use anyhow::{Context, Result, anyhow}; use clap::{Parser, Subcommand}; use microxdg::Xdg; use niri_tag::TagCmd; use nix::unistd::geteuid; use std::{io::Write, os::unix::net::UnixStream, path::PathBuf, str::FromStr}; #[derive(Parser)] #[command(name = "tagctl")] #[command(about = "ipc wrapper for niri-tag")] struct Cli { #[command(subcommand)] cmd: Commands, } #[derive(Clone, Debug, Subcommand)] enum Commands { Add { tag: u8 }, Remove { tag: u8 }, Toggle { tag: u8 }, EnableTag { tag: u8 }, DisableTag { tag: u8 }, ToggleTag { tag: u8 }, } impl From for niri_tag::TagCmd { fn from(value: Commands) -> Self { match value { Commands::Add { tag } => TagCmd::AddTagToWin(tag), Commands::Remove { tag } => TagCmd::RemoveTagFromWin(tag), Commands::Toggle { tag } => TagCmd::ToggleTagOnWin(tag), Commands::EnableTag { tag } => TagCmd::EnableTag(tag), Commands::DisableTag { tag } => TagCmd::DisableTag(tag), Commands::ToggleTag { tag } => TagCmd::ToggleTag(tag), } } } fn main() -> Result<()> { let cli = Cli::parse(); use Commands::*; match cli.cmd { Add { tag } if tag > 0 => (), Remove { tag } if tag > 0 => (), Toggle { tag } if tag > 0 => (), EnableTag { tag } if tag > 0 => (), DisableTag { tag } if tag > 0 => (), ToggleTag { tag } if tag > 0 => (), _ => return Err(anyhow!("Can't change tag 0!")), }; let cmd = TagCmd::from(cli.cmd); let xdg = Xdg::new()?; let mut path = xdg .runtime()? .unwrap_or(PathBuf::from_str(&format!("/run/user/{}", geteuid()))?); path.push("niri-tag.sock"); let mut ipc = UnixStream::connect(path).context("Connecting to niri-tag ipc socket")?; ipc.write_all(serde_json::to_string(&cmd)?.as_bytes())?; Ok(()) }